New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Streaming and chunked responses #350
Comments
In this case, you would want to set a smaller
True. But it's not uncommon for applications to use Excon in threads.
To do this Excon would have to buffer the entire response, which is what you're trying to avoid.
The file = File.open('log', 'a')
block = lambda {|chunk, remaining, total| file.write chunk }
connection.get(:response_block => block)
file.close |
@zimbatm I'm not familiar with docker-api, but I took a quick look. |
@burns |
@tlunter Thanks! |
Maybe Excon::Socket should be using #sysread or #readpartial instead (which are more like the underlying posix read()). Unless :chunk_size is set to 1 there is always going to be a bit of buffered data and chunks of 1 byte aren't very practical either. Ideally, docker would send a line of varying length and I would be able to read it at that time. Otherwise it's not really possible to have an interactive output. There's always going to be lines that are going to be cut in half or come together even if the emission time is separated by multiple seconds. |
I agree with the |
I still don't follow on this. If Single, or multi-threaded, the thread that calls this method is going to block no matter what (if |
read_nonblock has similar behavior to read partial (it shouldn't buffer) see: http://www.ruby-doc.org/core-2.1.0/IO.html#method-i-read_nonblock. In particular this section:
I guess I don't remember enough context around the rest to comment though. |
With threads, control is released as soon as you make the syscall so it's not an issue but with nonblock control has to be released explicitly. The function has to return so that a central reactor like EventMachine can invoke other pending IO. Making an API that works with both blocking and non-blocking is tricky IMO. |
I believe this is now fixed on master and in 0.34.0 |
Right now the response_stream only gets full chunks of size :chunk_size. This is an issue when trying to follow a continuous stream (like a stream of log lines) because in that case you want to get the latest chunk of data that arrived to forward it an not buffer it.
When going trough the code to find out the behavior I was also mislead by this argument parameter: https://github.com/geemus/excon/blob/master/lib/excon/socket.rb#L31 .
max_length
really should be calledlength
if it's never returning more or less than the given size.Also what's the point of using non-blocking IO if the control is blocked by the while loop ? In a single thread I don't see what advantage it's going to offer.
Ideally the response body would be a fake IO stream that can be read until the end of the response body (the connection can still be kept for keep-alive/pipelining) instead of using a block. That way the use can choose how to read the data and if he wants to block or not on it.
It would also solve another issue where the response_block is not called when the stream ends, giving no opportunity for the block to know when he can stop forwarding the data: https://github.com/geemus/excon/blob/master/lib/excon/response.rb#L73
The text was updated successfully, but these errors were encountered: