In InMemoryWebSessionStore, expired sessions are checked and deleted when retrieveSession is called. In our case sessions are created but users never reuse the session id. So we never retrieve sessions and never clean them. We then have a memory leak.
I think that InMemoryWebSessionStore should not rely on session's creation/retrieval etc... to clean up its own sessions.
The checkExpiredSessions is made on every retrieve, but not more frequently than 60 seconds. In other words retrieve is used as the trigger but it doesn't matter whose session the retrieve is for (all sessions are checked). Does no one every call retrieve again?
I just want to double check. I'm sure this is clear but just in case – a retrieve for +any+ session will trigger checkExpiredSessions. Eventually the load balancer should route someone with a session to each server, or else the number of sessions on that server is not growing.
In the end this is trying to find a convenient trigger to perform expiration checks vs managing scheduler resources. The main way I can see this becoming an issue is if there is a big spike of sessions on one server, and then no more session users to that server again. Seems like a less common scenario but possible. Even then the memory will not grow unbounded, so it's a question of how much memory can be accumulated in the mean time.
Any further specifics you want to share would help, but it seems like we need to provide more control for specific scenarios. Would a property for the frequency of checks help? If you have spikes, and then nothing at all then setting it to a low number would help.
The frequency of checks would most certainly help but I think we can improve differently.
We can add an extra check on the total number of sessions created since the last expiration check. If done from the create method, that will happen on every request and should effectively put an upper limit (e.g. N = 100) on the total number of sessions that can be created before the next round of expiration checks. That will complement the time window limit currently in place.
This can also help optimize performance by reducing the frequency of current time checks from every session request, to once every Nth request, as well as help to ensure a round of expiration checks happens regardless of whether retrieve is called.
I ended with hooks in create and retrieve to ensure periodic checks for any getSession() call. In addition, there is now a maxSessions to put an upper limit on the total count (10K by default but configurable). That should cover most cases I think and puts upper limits but I also added a public API removeExpiredSessions for extra flexibility if you need to force a check at a specific time. Last, there is a getSessions() method based on #21254.