I updated the summary, since it was not intended as release notes, but more as
After some sparring with Peter we came up with the following text proposal.
Feel free to modify it in any way you see fit.
Due to the asynchronous nature of replication it can happen that some
replication messages get lost during an instance failure.
If the lost replication message is a delete message, it can happen that an
artifact survives in the replica cache even after the active copy has been
A stale version of such artifacts might be activated later before the timeout is
invoked on it (since the timer semantics are preserved for replicas).
Such an artifact is called a zombie.
If the lost replication message is an update message, it can mean that in later
a stale replica is activated and used in subsequent communication in this session.
If the lost replication message is a create message, then the session can be
If possible, the application should detect whether an artifact is stale or a
zombie when it is restored after a failure.
When the an object is restored after a failure the sessionDidActivate() callback
is invoked on the listener.
Because of this problem it is recommended to implement logic that discovers
For example for some applications it may be possible to call the
lastAccessTime() method on the SipApplicationSession and/or SipSession to
determine whether the session is stale or not. If the session is stale it
should be explicitly invalidated.
For some applications this detection may not be possible without storing (or
removing) state information from a database when a session is invalidated.
In general it is good practice to limit the life time of a SipApplicationSession
and a SipSession. Also in case that incoming messages get lost (e.g., an
incoming BYE gets lost), there is a chance that a SipSession and corresponding
SipApplicationSession will survive indefinitely. This also constitutes a memory
Therefore, the application should have an upper limit to the time an artifact
can live in the absence of external triggers.
This is specifically important if the application can do no staleness detection.
There are several ways to do this. The easiest way is to use the
SipApplicationSession's expiry time as defined in JSR289 section 188.8.131.52.
- SAS timer based
One pattern could be to set this to the maximum time you are prepared to wait
for some external trigger and only in the presence of that trigger extend the
Then if the trigger does not arrive on time, let the SAS expire. This will
invalidate the SAS and its children.
In this pattern the SAS is never extended as part of the sessionExpired() callback.
Even if the application has good reason to extend the SAS in the
sessionExpired(), it should never do so indiscriminately, and thereby
effectively create an endless SAS.
- ST timer based
Another possibility is that the application uses the Servlet Timer as a lifetime
E.g., a servlet timer can be started to guard the lifetime of a specific SipSession.
The main thing that we want to convey here is that an application must be very
careful to avoid endless sessions as they constitute memory leaks.
And if possible the application should do a staleness check on any restored
artifact in the sessionDidActivate callback.