Tomasz Nurkiewicz opened SPR-13224 and commented
SseEmitter
misbehaves when multiple threads call send()
at the same time. Sometimes container fails, but most of the time different messages get interleaved, e.g.:
emitter.send("foo"); //thread A
emitter.send("bar"); //thread B
sometimes results in:
data:data:AB
It happens because emitter.send("A")
actually sends three independent messages: data:
, A
and \n\n
. These three messages can be interleaved with messages from different threads. Please either synchronize properly or document clearly that SseEmitter
is not thread safe, so that if clients want to use from multiple threads (I think it's quite useful), it must be synchronized manually:
synchronized(sseEmitter) {
sseEmitter.send("foo");
}
Affects: 4.2 RC2
Issue Links: - #17814 ResponseBodyEmitter skips same messages during initialization
Referenced from: commits https://github.com/spring-projects/spring-framework/commit/bdb63483df2cd81bdbcc963db8789f37ea2a6727
Comment From: spring-projects-issues
Juergen Hoeller commented
Implemented together with #17814, using a common struct for a value with media type both in ResponseBodyEmitter
and in SseEventBuilder
, and using common synchronization for all affected operations - including the option to manually synchronize on the emitter, for aggregating multiple values just like SseEmitter
does by default now.
Juergen
Comment From: martinandersson
Can you please re-open this issue? The thread-safety of relevant types are still not documented, leading to 1) time waste for people concerned about thread-safety having to google this - and that should be most of us, 2) developers programming against a contract must manually synchronize regardless of implementation details they might have come across online - and that should be most of us.
Comment From: snicoll
@martinandersson we're not going to reopen an issue that was closed in a released version of the framework. Please create a separate issue with additional details against the current GA version.