Session Locking

Last Updated: 5/6/2009



Sections above here:
Home  ยป  Development

Sections below here:

Topics in this section:
Rethinking the User Interface
Writing your first Delphi App
Images and Graphics
Extending Intraweb
Working with COM
Working with ClientDataSets
Creating PDA Applications
Error Handling
Control Size
Reading and writing custom cookies
Miscellaneous
Advanced Development
Session Locking

Search Documentation:

The following information is aimed at advanced users interacting directly with the session management mechanism in IntraWeb.

Guiding principles of the session management mechanism

  1. Concurrent access to session objects is serialized instead of prevented - the ESessionAlreadyLocked exception does not exist any longer.

    This was needed, because we can not always predict how exactly different browsers and different version behave or how exactly a customer's benchmark works - e.g. IE retrieves resources using multiple threads, opera reuses response contents on multiple windows.

    For application execution consistence we will rely on the session TrackID checks.
  2. A session object is always locked when it is in use.

    Whenever a reference to a session object is obtained, the session is locked before the reference is returned. Whenever the reference is no more needed, the session object is unlocked and the reference is set to nil.

    This prevents collisions and ensures that session objects cannot be deleted while in use, and prevents the time-stamp from being updated, while checking if the session has expired.
  3. The API is changed in a manner to prevent improper or dangerous use of session objects - as far as possible.
  4. No more differentiation of locked and unlocked sessions.

    Whether a session is locked or not is a volatile state, thus we do no longer maintain two different lists of locked and unlocked sessions. We now keep a single list of sessions only. This avoids moving object from one list to another, and it avoids checks if a session is already in one or the other list. Remember: if you have a reference to one specific session, then this session's locked-state may be changed frequently by other tasks - unless you locked the session your self. 

How to:

  1. Accessing current session object in event handlers:

    IntraWeb automatically locks and unlocks sessions objects by threads executing web requests, so when event handlers are executed it is ensured the current session object is locked. So simply use code like this:

    (OnRenderForm, OnButtonClick etc...)
    var
      LSession : TIWApplication;
    begin
      LSession := GGetWebApplicationThreadVar;
      // do some read/modify operations
     
  2. Accessing session objects in separate threads:

    var
      LSession : TIWApplication;
    begin
      LSession := GSessions.LookupAndLock(AAppID);
      try
        // do some read/modify operations
      finally
        LSession.Unlock;
        LSession := nil; //this is a precaution for following code in this method
      end;
  3. Terminating a session:
    (This for terminating from a different thread, this must not be confused with the normal Terminate() methods which still can be called from event handlers)

    var
      LAppID : String;
    begin
      // obtain session ID and store in LAppID
      GSessions.Terminate(LAppID)
  4. Accessing the list of sessions:

    var
      LSessions : TList;
      LSession : TIWApplication;
      i : Integer;
    begin
      // Get and lock the list of sessions.
      // The LockList method does not lock individual session objects, but the
      // internal list. Between LockList and UnlockList it's guaranteed that
      // the list of sessions can not be modified by other threads.
      LSessions := GSessions.LockList;
      try
        for i := 0 to Pred(LSessions.Count) do begin
          LSession := LSessions[i];

          // we still need to lock the session object to avoid concurrent access
          LSession.Lock;
          try
            // do some read/modify operations with LSession
          finally
            LSession.Unlock;
            LSession := nil;
          end;
        end;
      finally
        GSessions.UnLockList;
      end; 



(C) 2002-2009 - Atozed Software Ltd.