Affects: 6.1.5


hello.

I encountered a problem with multiple subscriptions while delivering broadcast messages to subscribed sessions (clients), and I thought there might be a need for a way to prevent this, so I created an issue thinking it would be good to discuss.

My case is as follows:

  1. For some reason, subscription request was made twice for subscription A with the same ID (sub-1).
  2. The server stores it in memory as shown below.
    • sessionRegistry is {session-id, sub-1, subscription}
    • desctinationCache is {A, session-id, {sub-1,sub-1}}
  3. If you cancel subscription A
    • Find session information by session-id in sessionRegistry and remove subscription by sub-1
    • Get a list of all session-ids corresponding to desctination from desctinationCache and remove only one identical subscription ID from it.

In the above situation, sub-1, which cannot be erased, remains in desctinationCache. Of course, the client implementation may be incorrect, but it seems that this could lead to a situation in which excessive memory may accumulate on the server.

To think briefly, I think it would be a good idea to store the subscription list in desctinationCache as a collection that does not allow duplication, such as a hashset, rather than an array list. Or is there a reason it has to be this way or is there another better way?

I see a few similar issues, but they seem slightly different. - https://github.com/spring-projects/spring-framework/issues/19794 - https://github.com/spring-projects/spring-framework/issues/20102 - https://github.com/spring-projects/spring-framework/issues/26474 - https://github.com/spring-projects/spring-framework/issues/26983

Comment From: heowc

It varies depending on the implementation, but vertx-stomp limits this. - https://github.com/vert-x3/vertx-stomp/blob/master/src/main/java/io/vertx/ext/stomp/DefaultSubscribeHandler.java#L57...L64

Comment From: rstoyanchev

SessionInfo.addSubscription uses computeIfAbsent, essentially ignoring an already existing registration. It's only the destination cache that accumulates multiple subscription id's in the same session. That's not intentional.