Mailboxes to entities residing on a BaseApp should exist for as long as they are needed by the web server. However, these same entities may be player entities controlled by the BigWorld client. These two different usages of the same entity must be reconciled when it comes to managing entity lifetimes — for example, if the client disconnects while the game's web interface is still using the player's base entity, this entity should not be destructed until the game's web interface has finished with it. Also, if the player is currently not logged in via the BigWorld client. If the player does not explicitly log out of the web server, we would want to clean up that mailbox reference after an inactivity period.
The solution to this problem is for the TwistedWeb service to periodically inform the base entity that it is still interested in it. The entity can then stay around even if the client has disconnected (destruction of the base entity is the normal course of action).
The TwistedWeb service keeps a cache of mailboxes.
Only mailboxes to entities that have a
webKeepAlivePing()
method are cached. Each time the
service is queried that uses one of these mailboxes it is either added to
this cache or marked with the time it was last queried.
The service will periodically check all mailboxes in this cache. If
the mailbox has not been used for a long time, it is removed from the cache.
If it is still active, the webKeepAlivePing()
method is called on it.
It is okay if the mailbox is removed from the cache too early. In this
case, the database will be queried to retrieve the mailbox. This is
important when running multiple TwistedWeb
service fragments on
different ServiceApps. Besides a very minor performance impact on the
database, it does not matter which ServiceApp is queried. Running the
service on multiple ServiceApps is a way to achieve fault tolerance and also
scaling beyond a single machine.
This functionality is implemented in
bigworld/res/scripts/service/TWResources/KeepAliveMailboxes.py
.
The frequency of the pings is specified by the
CHECK_PERIOD
constant. The amount of time before a
mailbox times out is specified by the TIMEOUT_PERIOD
constant.
For game script, entities can make use of the
KeepAlive
class located in
fantasydemo/res/scripts/base/KeepAlive.py
to implement
this functionality. It also has CHECK_PERIOD
and
TIMEOUT_PERIOD
constants specifying how frequently to
check for these entities timing out and how long before they time out. This
timeout period should be slightly more than that of
KeepAliveMailboxes.py
.
When accessing this service from a website, keep-alive intervals can be used with HTTP session timeouts so that players have to re-login after a certain inactivity period to create a new HTTP session. Keep-alive intervals should be set to be equal to or longer than session durations.