Body-related state and notification methods
Hullo all - I think I may have found a number of bugs in the sample adapters, and even the VIGOS gzip adapter, which is rather worrying as I've only been looking at eCAP for a day! I also have some suggestions for how the API could be made easier to understand and less error-prone to code for, if my current understanding of it is correct.
Bug in all sample adapters, and VIGOS gzip adapter:
* They send noteAbContentDone as soon as they receive noteVbContentDone. This is dangerous, because the host may not have actually retrieved all adapted body from the adapter's buffer - it will only have done so if, every time the adapter sends noteAbContentAv
* This raises an odd issue: since noteAbContentDone is a function call, not a return code, it will almost definitely be called *before* the host has returned from whatever function calls abContentShift.
Suggestions for improving the API if this is true:
* Why can the host ever perform a non-destructive read from the adapter? API would be far less error-prone if all the host could do was destructive reads, with an explicit EOF returned when the last data that is going to be produced is read. Also hosts should be coded to cope with the case where they are told data is available, then receive 0 bytes and an EOF, so that an adapter can signal that it's finished producing data in a way that works with non-blocking code. Think BSD sockets, but with EOF signalled explicitly, rather than implicitly by returning 0 bytes. noteAbContentDone must die!
* IMHO, noteVbContentDone should be removed in a similar way (force adapters to call vbContentShift and send EOF when done), although non-destructive reads for unshifted data are a good idea (useful, for example, for peeking at the first few bytes of body during streaming).
Second bug in sample adapters:
* Sample adapters should not call vbDiscard from abDiscard, as they may have already called vbMake in Xaction::start. If an adaptor has called vbMake, it should surely call vbStopMaking. Looking at the implementation of vbDiscard in Squid's XactionRep.cc, it will actually throw an exception if vbDiscard is called after vbMake.
Second suggestion for improving API: why do we need (vb|ab)Discard *and* (vb|ab)StopMaking? Surely it is trivial for hosts and adaptors to only delete body buffers if they're actually been allocated, and have a single call pair? I think this would be a better fit for the code the Squid team have actually written, because internally, its vbStopMaking and vbDiscard implementations end up calling the same function anyway! Also, it *never* calls abDiscard on adapters, only abStopMaking!
Please read my post and the sample code carefully, because I'm convinced I'm on to something here. If there is a valid reason for a host to ever perform a non-destructive read from the adapter, I would love to know what it is - but even if you want non-destructive reads to be possible, signalling that content is "done" should be a return code from a destructive read, in both halves of the API. This is how all other mainstream input/output APIs are implemented, both blocking and non-blocking. By not doing it this way, you're giving people too much rope to hang themselves - as shown by the presence of bugs in your own examples.
Regards,
Phil
Question information
- Language:
- English Edit question
- Status:
- Solved
- For:
- eCAP Edit question
- Assignee:
- No assignee Edit question
- Solved by:
- Alex Rousskov
- Solved:
- Last query:
- Last reply: