Know when a stream is closed?
There should be something like connection.onidle but for when a stream's state changes (or maybe only closes).
What's the best workaround for that?
What is your usecase? -> when/why do you want to want to be notified of state changes?
I think knowing when the state becomes "closed" would be enough. This is in case the connection is dropped, I can react accordingly.
Or do get_headers and get_next_chunk return errors in that case?
I think knowing when the state becomes "closed" would be enough. This is in case the connection is dropped, I can react accordingly.
Wouldn't that be knowing when connection is closed then? not the stream?
Or do get_headers and get_next_chunk return errors in that case?
Yes. any errors in reading from stream (e.g. due to connection closure) are returned from get_*
I've interposed set_state for debugging purposes.
The state is being set to "closed", but each_chunk never returns an error.
Edit: Oh nevermind, the for loop is just ending because chunk is nil. Looks like I'll need to use get_next_chunk in order to handle errors.
Edit 2: Hmm, seems that get_next_chunk simply returns nil when the connection is dropped. No error message.
Is it an error? or just a natural end of stream?
Like lua's own file:read, reaching the end of a file just returns nil, it's not an error condition.
How can I know if the connection dropped if it's not differentiated from a successful end of stream?
Compare received body length to the Content-Type header? Or for chunked Transfer-Encoding, check if trailers were received?
For a stream delimited by Connection: close, there is no way to tell! the end of the response is when the connection drops .
Otherwise you need to check the result of :get_next_chunk. If you use the each_chunk iterator the error will be dropped on the floor. Perhaps that is something we should fix?
If you use the each_chunk iterator the error will be dropped on the floor. Perhaps that is something we should fix?
What are our options?
We could return false instead of nil. But do we really want to do an if chunk check on every iteration? But that might be the most elegant solution.
What are our options?
With cqueues, errors are saved and repeated until cleared. In practice I've found that behaviour annoying outside of the iterator case. Additionaly, it only saves the error code: not the full error message.
Additionally, for PUC-Rio 5.1 compat you should avoid iterators.... those two facts together mean that I don't often have the issue you're mentioning (I only use the iterator form for throwaway scripts)