-
Notifications
You must be signed in to change notification settings - Fork 423
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
Chunked transmission lasts longer than timeout #4214
base: master
Are you sure you want to change the base?
Conversation
2244b8c
to
aded4cc
Compare
...ty-server/cats/src/test/scala/sttp/tapir/server/netty/cats/NettyCatsRequestTimeoutTest.scala
Outdated
Show resolved
Hide resolved
There are two differences compared to the original report:
|
49a1e12
to
ad42e13
Compare
Thanks for your precise comment. I've rewritten it to |
.streamBody(Fs2Streams[IO])(inputStream) | ||
.send(backend) | ||
.map{ response => | ||
response.code shouldBe StatusCode.Ok |
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.
hm well if this test passes, something is wrong - we set the timeout to 1s, so we should never receive a response if it takes 2s to send it? unless the request timeout is for something else?
anyway, this doesn't test the scenario from the test case - where the transmission is interrupted half-way because of connection problems; I don't know if we can simulate this in a test case, but using a timeout is a good approximation. But probably a good way to check if we can at all reproduce the bug is to run: a long-running client sender process; a server process; then kill -9
the client process when it's half-way sending the data, and seeing on the server if received the incomplete data in the server logic
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.
I have given it another try as you suggested. There are playServer and longLastingClient but I don't know what's wrong with that approach. Suggestions are welcome 💡
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.
When you write "I don't know what's wrong with this approach ", do you mean that it works as expected (that is: you run both, interrupt the client brutally after some time, and the server properly closes the connection), or is there something else that's wrong?
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.
I'm trying with the following steps:
$ scala-cli run playServer.scala
[playServer-pekko.actor.default-dispatcher-4] INFO org.apache.pekko.event.slf4j.Slf4jLogger - Slf4jLogger started
[application-pekko.actor.default-dispatcher-6] INFO org.apache.pekko.event.slf4j.Slf4jLogger - Slf4jLogger started
[main] INFO play.api.Play - Application started (Dev) (no global state)
[main] INFO play.core.server.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
$ scala-cli run longLastingClient.scala
ByteString(65, 65, 65, 65, 65, 65, 65, 65, 65, 65) 17:46:14.514330
ByteString(65, 65, 65, 65, 65, 65, 65, 65, 65, 65) 17:46:15.534314
ByteString(65, 65, 65, 65, 65, 65, 65, 65, 65, 65) 17:46:16.553033
ByteString(65, 65, 65, 65, 65, 65, 65, 65, 65, 65) 17:46:17.573135
....
- server side
Received 10000 bytes, Source(SourceShape(Map.out(1467551936))) bytes in total
-
$ ps aux | grep longLastingClient | awk '{print $2}' | head -n 1 | xargs kill -9
-
and nothing new (error/exception/whatever) on server side 🤔
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.
I think the lack of exception/error might be the problem here ;) but first there are two problems in the code:
- in the client code, you claim to send 10000 bytes in the content-length, but in fact you might send more?
- in the server code, you do
stream.map(_.length)
, which just creates aSource[Long]
, that is a description of a stream that produces lenghts of received byte-strings (byte chunks). You never run (receive) the stream, and that's where you'd expect to see errors (when the stream is being run)
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.
🤦♂️ added pointed adjustments and the result is the following :
$ scala-cli run playServer.scala
[playServer-pekko.actor.default-dispatcher-4] INFO org.apache.pekko.event.slf4j.Slf4jLogger - Slf4jLogger started
[application-pekko.actor.default-dispatcher-4] INFO org.apache.pekko.event.slf4j.Slf4jLogger - Slf4jLogger started
[main] INFO play.api.Play - Application started (Dev) (no global state)
[main] INFO play.core.server.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
$ scala-cli run longLastingClient.scala
Chunk 1 sent 13:00:13.650915
Chunk 2 sent 13:00:14.668797
Chunk 3 sent 13:00:15.690020
Chunk 4 sent 13:00:16.710184
Chunk 5 sent 13:00:17.730033
Chunk 6 sent 13:00:18.748416
Chunk 7 sent 13:00:19.769451
Chunk 8 sent 13:00:20.789355
-
killing client
-
server side
Stream finished: 800/10000 transmitted
😞
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.
So, I suppose, that's the problem as originally reported?
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.
We can now try to fix it, and/or reproduce using a test :)
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.
So, I suppose that we should return an error with a descriptive message i.e. java.lang.IllegalStateException: Expected
Content-Length: 10000 bytes, but only 800 were written
, right?
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.
Yes, since the client interrupted the transmission, I think it's reasonable to expect that the stream will fail? With any exception for a start.
9402d02
to
67760c5
Compare
*Why I did it?* In order to have a test which might confirm an issue with an interrupted request *How I did it:* I prepared `NettyCatsRequestTimeoutTest` with the folloing test scenario: - send first chunk (100 bytes) - sleep - send second chunk (100 bytes)
- add PlayServerTest instead of NettyCatsServerTest - improve fs2 implementation
This reverts commit 02ba4b0.
4281e96
to
f1aad13
Compare
Why I did it?
In order to have a test which might confirm an issue
with an interrupted request
How I did it:
I prepared
NettyCatsRequestTimeoutTest
with the folloing test scenario:Closes #4169