There are several things we want to achieve;
- modifications made during traffic are saved
- during traffic the relevant SASes are locked to avoid migration of these SASes
- after invalidation the objects are still available in the cache until they will no longer be accessed.
The main classes involved in this are:
There is one dialogLifeCycle object per DialogFragment. It keeps track of the UnitOfWork associated with that DF and guards the lifecycle of the DF and the related objects (e.g., SSes). The UOW is saved on the DLC and associated with the current thread at appropriate times (e.g., when a new thread is handling a proxying, when a response is send on an incoming request, etc.) For the latter it also keeps track of all the SIP transactions the DF is involved in. The DLC also determines when to lock and unlock the trees during traffic
-
- The SAS is locked when creating and sending an outgoing request that creates a new SipSession and SAS
- All SASes reachable from a DF are locked on receiving an incoming subsequent request or initial request.
- The locks are released when the HTTP request handling finises.
- The locks are released and the UOW is saved when
- the last ongoing server transaction has finished
- the DLC is scavanged
The scavaning is controlled by a reaper mechanism, where the DLC registers itself when it has no ongoing transactions, but it has not reached the end of its lifecycle and it still is waiting for something. E.g., after initialisation, before the first transaction is associated, or after invalidation at a point there are no transactions ongoing.
This represents some task during which all artifacts touched are collected to be saved when the task completes. It also keeps track of all the SASes that are currently locked. For traffic related cases there is a UOW associated with the DLC. The DLC will ensure that the UOW is saved at some trigger points, either internally from the DLC or externally frome the Replication Manager.
The ReplicationManager is implemented as a Layer in the Sip Stack. It implements some additional triggers for saving the UOW.
-
- After handling an incoming ACK on a confirmed DF that contains a UA.
- When sending an outgoing ACK on a confirmed DF
- After sending an outgoing response on a DF
- After handling an incoming response on a DF that contains a UA.
After handing any incoming response, it will also unlock the SASes and save the UOW. If the DF has been invalidated during the handling of the response, this is the moment when it is removed from the cache, including any associated SSes. This ensures that the DF and the SSes are still available after they have been invalidated, to avoid tricky NPEs when they are still accessed from different threads even after the ongoing client transaction has finished.
- HAServletTimer, HASipApplicationSession
For timeouts, the UOW is created and SAS locked before handling the timeout and saved and the SAS unlocked after handling the timeout. This is normally called out-of-band.
There are other internal places in the code where UOWs is conditionally created (if not yet associated with the current thread) and locking and saving is done when the work finishes.
- HASipApplicationSession.activate() - to ensure that modification by the lifecycle listener are replicated
- HASipApplicationSession.passivate() - to ensure that modification by the lifecycle listener are replicated
- SipServletWrapper.doInvoke() - to ensure that modification by the initialisation listener are replicated
Known problems:
- there is a window of no save, modifications made after sending a response are not replicated
- there are other layers touching the artifacts after the ReplicationManager has already saved the UOW (and cleared the UOW from the thread).
- The lack of transactions will mean that the lock will be kept quite long. E.g., for the incoming ACK the lock will be kept for 32 seconds after handling the ACK.
|