-
Notifications
You must be signed in to change notification settings - Fork 319
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
Fix incomplete read in the DockerMultiplexedInputStream #693
Conversation
readInternal() assumed that the 8-byte header of a docker stream will always be fully read in one call. This is just misleaded. This assumption would be okay if the network always had a high bandwidth and low jitter, but real-world cases we may have jitter (because of packet losses, buffering, ...) that causes random read errors, eg: FATAL: java.io.IOException: Expected 8 bytes application/vnd.docker.raw-stream header, got 2
7ce20c1
to
78c0337
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initial changes look good; it looks like a perfect fit to solving #628
The handling of stderr, however, leaves a lot to be desired (mainly due to the original code). I agree that the EOF handling is an improvement, but I think that now we've seen it, it would be wrong to leave it at that and we really ought to "fix it properly".
Ideally, we should also have some unit tests for this code too (if we'd had some to start with, #628 probably would've been found by the tests...)
src/main/java/io/jenkins/docker/client/DockerMultiplexedInputStream.java
Outdated
Show resolved
Hide resolved
src/main/java/io/jenkins/docker/client/DockerMultiplexedInputStream.java
Outdated
Show resolved
Hide resolved
@ndeloof It looks like you were the original author of this code... Can you confirm that I've understood it correctly?
So, the existing code's handling of the stderr case (type==2)...
...and would you also agree that an effective unit-test could be to take some example input data paired with expected output, and then check that the code handled it correctly both when it was provided by the multiplexed stream "all at once" and when it's only available one byte at a time. |
this is the docker 'stream' format, it is described in the API at: |
78c0337
to
6e6f38d
Compare
I've been using 1.1.6-rc867.6e6f38dd6134 for 4 days now and didn't get a single "Expected 8 bytes ..." error |
After the upgrade to the docker-plugin 1.1.5 a random error of incomplete input stream started to appear, documented at jenkinsci/docker-plugin#693 Fix the specific communication issue waiting to upgrade to the next forthcoming 1.1.6 Change-Id: I166550a336b5b954a8ac1a3b7ba14dd33d7a1265
4dd6c34
to
b1e4b95
Compare
I applied the suggested changes + wrote tests for this class |
b1e4b95
to
ae5728d
Compare
@a-ba Thanks for persevering with this; it's much appreciated. |
Fix #628 (which should be reopened) and https://issues.jenkins-ci.org/browse/JENKINS-53669
readInternal()
assumed that the 8-byte header of a docker stream will always be fully read in one call. This is just misleaded.The assumption would be okay if the network always had a high bandwidth and low jitter, but real-world cases we may random delays (because of packet losses, buffering, ...) that causes random read errors, eg:
Note: the PR also fixes a missing exit case when reaching EOF in the stderr channel