Keeping a session alive

I have a server that takes requests, and does some database operations. I have a custom session class so that I can keep information about the connected user. I have found that if my browser does a new operation while this long database operation is happening, the session object is being released (.free) and then the thread processing the operation is getting an access violation when it tries to use the session.

I am not sure if something might have changed in the session management in recent versions? It used to be that I’d create a session in the connection, and it would hang about for a fair while before it was free’d. I am using the InMemorySessionManager, and the duration and check interval are both 15.

By adding logging, I can see that the session is Free’d before TROCustomSessionManager.ReleaseSession is called, and that will often get an access violation at this point.

If someone could explain what the sessions are doing, and why they are deleted so quickly, I’d appreciate it. Or what I should be doing to make them live longer.

Actually, hang fire. Hmm, one of the steps is to log out, and that is calling DestroySession. It makes sense that it would destroy the session therefore. Key is, who should manage the fact it is still in use in another thread… I shall ponder.

can you set breakpoint at TROSession.Destroy, see callstack and detect what code causes this?

can you create a simple testcase, that reproduces this behavior, pls?
you can attach it here or send directly to support@

Yes, the key is that I’m calling TRORemoteDataModule.DestroySession in my Logout code. That causes it to set the fDestroySession flag which free’s it at the end of the logout. But another thread is still using the session object so it shouldn’t be destroyed at that point. My first thought is that the session object should have a count of activations and deactivations, and only free when fDestroySession is true and the count is zero. I shall have to think if I can work out a way I can resolve it. I’m not sure that if I add my own locking that it won’t cause deadlocks.

To reproduce, it would be quite easy I think. Have two functions, one of which sleeps for a while, and then returns. Have the other do a DestroySession and return. Call them in order, and the first will fail with an AV on exit.

(I’m looking at this as I have a problem with a server that is going to 100% of a CPU and stopping all processing. I was experimenting to see if I could get it to fail on my dev PC, and found this repeatable issue. Not sure if it is the cause of my big issue, but I can see how it might be contributing.)

from Remoting SDK logic, it does all correctly, because DestroySession was called.

I think, you can store count of activations and deactivations inside session and destroy session only if it is equal to 1.

Okay, this seems to be working. In each interface implementation I have an activate/deactivate event handler. These call a function that does the work, and the deactivate is as follows:

procedure DeactivateSession(xModule : TRORemoteDataModule; aSession: TROSession);
begin
  if assigned(aSession) then
  begin
        (aSession as TAccountSession).DecrementActivations;
        if (aSession as TAccountSession).LogoutRequested  and ((aSession as TAccountSession).Activations = 0) then
              xModule.DestroySession;
  end;
end;

The Activate Session just calls IncrementActivations. DecrementActivations just decrements the counter, but you must watch for it going negative, as the initial session will not be assigned, so the first this is called is do deactivate it. And then in the Logout, it sets the LogoutRequested flag, and this now lets other calls complete before the final Free is done.

I hope that this will help others who might face this situation where they want to destroy the session before its natural life.