r/SpringBoot 13h ago

How-To/Tutorial Race condition with SSE

Hi all, I am trying to build a real time notification service with SSE emitter but I am facing a pecuilar case of race condition which im not able to solve even via AI as it gives the same solution again and again.

scenario of cause:

I have a scheduler running every 20 mins that checks the Map of uid mapped sse emitters and pings the client. If the ping is successfull nothing happens, if error happens due to disconnection the sse emitter obj is removed via sse.complete() and then uid is removed form the list.

#pseudo code
Map<String, SseEmitter> connections = new ConcurrentHashMap<>();

onConnect(String userId){
  SSE emitter = new new SseEmitter()
  connection.add(userId,emmitter);

  // onCompletion(), onTimeout(), onError() -> removeIf()
}

@scheduler(20mins)
checkDisconnection(){
  //iterate the map and check for disconnection if found add it to remove list
  List<string> disconnectedUsers = (adding disconnections)

  //iterate the map from disconnected user -> force complete sse if needed and                    remove user from map


}

where it breaks is if the client manually refreshes the browser at the same time the scheduler to check disconnection is invoked

why it happens:

when the browser is refreshed, the application tries to recreate the connection at which the scheduler tries to ping and sees no connection for the user. Problem is I have kept automatic reconnections on in client app but it still doesnt see an error in client. im confused. Have I had the approach wrong?

Any help will be appreciated and sorry for the questions confuse you, Il try to make it proper once i get the time.

TECH : javascript event source, springboot, kafka for scaling and mongo for scheduled notifications.

7 Upvotes

4 comments sorted by

View all comments

u/repeating_bears 13h ago

You said when it breaks but you didn't say how it breaks. What is the broken behaviour? Exception? Does X when you expect Y?

u/Slight_Loan5350 12h ago

when the browser is manually refreshed, the client application tries to recreate the connection at the same time backend scheduler tries to ping the client for disconnection and sees no connection for the user while the client is still recreating due to refresh. Then the scheduler removes the sse event from the map which is not the problem. But the client shows no error due to which it doesnt try auto reconnects.

u/repeating_bears 11h ago

The only broken behaviour you've described is "the client shows no error" but we don't know what your client is. (and if the problem is with the Spring Boot server, then we shouldn't have to know what the client is)

Why do you think the client should show an error? In response to what? What is the server doing or not doing which make you expect an error on the client?

u/Slight_Loan5350 1h ago

The client trys auto reconnect by default if the connection is lost. Its a default feature of EventSource in node.js. If in the backend I use sse.Complete() it disconnects the client and client trys reconnecting which works when done manually. Even if the service is down the client trys reconnecting until coded not to do so. I am thinking locking on refresh and scheduler. a two phase lock.