It seems like there is a regression introduced into SseEmitter in latest 5.2.10.RELEASE (apparently #25442), it now returns to the client only first SSE event.
How to reproduce
package com.example.sse.emmiter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder;
@SpringBootApplication
public class SseEmitterRegressionApplication {
@RestController
@EnableAutoConfiguration
static class LibraryController {
@GetMapping("/sse")
public SseEmitter streamSseMvc() {
final SseEmitter emitter = new SseEmitter();
final ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor();
sseMvcExecutor.execute(() -> {
try {
for (int eventId = 1; eventId <= 5; ++eventId) {
SseEventBuilder event = SseEmitter.event()
.id(Integer.toString(eventId))
.data(new Book("New Book #" + eventId, "Author #" + eventId), MediaType.APPLICATION_JSON)
.name("book");
emitter.send(event);
Thread.sleep(100);
}
emitter.complete();
} catch (Exception ex) {
emitter.completeWithError(ex);
}
});
return emitter;
}
}
static class Book {
private String title;
private String author;
public Book() {
}
public Book(final String title, final String author) {
this.setTitle(title);
this.setAuthor(author);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
public static void main(String[] args) {
SpringApplication.run(SseEmitterRegressionApplication.class, args);
}
}
- using latest Spring Boot
2.3.4.RELEASE and Spring Framework 5.2.9.RELEASE
$ curl http://localhost:8080/sse -iv
> GET /sse HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.71.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
< Date: Wed, 28 Oct 2020 22:09:00 GMT
<
{ [15 bytes data]
100 335 0 335 0 0 589 0 --:--:-- --:--:-- --:--:-- 590HTTP/1.1 200
Content-Type: text/event-stream
Transfer-Encoding: chunked
Date: Wed, 28 Oct 2020 22:09:00 GMT
id:1
data:{"title":"New Book #1","author":"Author #1"}
event:book
id:2
data:{"title":"New Book #2","author":"Author #2"}
event:book
id:3
data:{"title":"New Book #3","author":"Author #3"}
event:book
id:4
data:{"title":"New Book #4","author":"Author #4"}
event:book
id:5
data:{"title":"New Book #5","author":"Author #5"}
event:book
- using latest Spring Boot
2.3.4.RELEASE and Spring Framework 5.2.10.RELEASE (overriding with <spring-framework.version>5.2.10.RELEASE</spring-framework.version>)
$ curl http://localhost:8080/sse -iv
> GET /sse HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.71.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
< Date: Wed, 28 Oct 2020 22:10:33 GMT
<
{ [15 bytes data]
100 54 0 54 0 0 2250 0 --:--:-- --:--:-- --:--:-- 2250HTTP/1.1 200
Content-Type: text/event-stream
Transfer-Encoding: chunked
Date: Wed, 28 Oct 2020 22:10:33 GMT
id:1
data:{"title":"New Book #1","author":"Author #1"}
Reproducible all the time. Please advice if this is a regression or SseEmitter semantics has changed (would appreciate documentation pointers) or more details are needed, thank you.
It seems like there is a regression introduced into
SseEmitterin latest5.2.10.RELEASE(apparently #25442), it now returns to the client only first SSE event.How to reproduce
2.3.4.RELEASEand Spring Framework5.2.9.RELEASE2.3.4.RELEASEand Spring Framework5.2.10.RELEASE(overriding with<spring-framework.version>5.2.10.RELEASE</spring-framework.version>)Reproducible all the time. Please advice if this is a regression or
SseEmittersemantics has changed (would appreciate documentation pointers) or more details are needed, thank you.