Closed counter2015 closed 1 month ago
Disclosure: I can't follow Discord links.
Compiling an fs2.Stream[IO, Byte]
(which is what the body is) twice is not guaranteed to return the same result. An IO
value, sequenced twice, is generally free to do different things.
There's a toStrict
method that can be called on requests or responses. Unfortunately, it doesn't change the IO
type to something that guarantees repeatability, but it should work for your use case. Be sure to read the fine print on memory: you probably want an EntityLimiter
or some other body limiting HTTP proxy in front.
@rossabaker Thanks your reply! I'm not sure if I understand correctly.
fs2.Stream[IO, Byte] (which is what the body is) twice is not guaranteed to return the same result
That's to say, the result maybe different for same input, but I test it many times, and it always works well when reqeust localhost endpoint, and random fails on remote endpoint. It behaves differernt depends on network environment at least in my views.
Here is some disscusion on discord.
the result maybe different for same input, but I test it many times, and it always works well when reqeust localhost endpoint, and random fails on remote endpoint. It behaves differernt depends on network environment at least in my views.
I'm confident enough to say that this behaviour is quite expected. When you're on the localhost, the network is likely to be reliable (since it's a sort of self-contained network interface rather than a full-fledged network).
That's the point which makes me confused. Why the network has influence on response body consuming ? It won't supprise me if returns me a timeout exception rather than BodyAlreadyConsumedError. Can we say in local environment, the BodyAlreadyConsumedError won't be raised?
Can we say in local environment, the BodyAlreadyConsumedError won't be raised?
Not with certainty. I wouldn't be surprised if this fails if you try it enough times. I wouldn't be surprised if it fails on a different machine. I wouldn't be surprised if it abruptly started failing on the same machine. Once your stream is backed by a TCP socket, the behavior of consuming it twice is undefined. If you want that guarantee, you need to use toStrict
, the BodyCache
middleware, or some other solution that caches the stream for multiple reads.
ok, got it. Thanks!
Recently, I discovered a strange phenomenon.
The full code can be accessed from https://github.com/counter2015/http4s-bug
For following code, it should raise error since it reads from response body twice
However, it runs well when request uri is localhost, and for remote host, it fails randomly. I have test it for serveral times, and the result is 14 successes, 6 failures.
The exception message like following
My question is
see more error about BodyAlreadyConsumedError : https://discord.com/channels/632277896739946517/632286375311573032/1179740665916182598 https://discord.com/channels/632277896739946517/632286375311573032/1066044042095382690 https://discord.com/channels/632277896739946517/632286375311573032/933061105067118622