Lifecycle and Concurrency semantics

We have explored a lot of APIs components. For any serious application development, it's very important to understand the threading and concurrency aspects of both the application and the frameworks being used. This lesson covers these aspects and helps answer some common questions such as

  • how many instances exist ?

  • is an instance inherently thread safe?

  • is concurrent access permitted (by the WebSocket implementation) ?

Session

Instances: there is a unique Session instance per client-server pair i.e. one instance of Session is created for a each client which connects to the WebSocket server endpoint. In short, the number of unique Session instances is equal to number of connected clients

Thread Safety: A Session is thread safe in spite of the fact that multiple threads are allowed to invoke a single instance of Session. This is because the the specification mandates implementations to ensure the integrity of the mutable properties of the session under such circumstances.

Endpoint

Instances: By default, there is one instance of an Endpoint per client unless this behavior is overridden by a custom Configurator implementation (see Configuration chapter for more details)

Example

If your application

  • has two endpoints: E1, E2

  • two clients connected to E1 and three clients connected to E2

then total number of Endpoint instances

  • would be five, and

  • will decrease to three in case all the clients connected to E1 disconnect

Thread Safety: The container will allow only one thread (per client) to enter the (lifecycle callback) methods of the server endpoint. In case there is a custom Configurator implementation which changes this semantic e.g. provide a singleton endpoint, then multiple threads will be able to invoke this instance concurrently and thread safety has to be built in explicitly

MessageHandler

Instances: In contrast to some of the other components, creation of a MessageHandler instance is controlled by the developer (not the container). Typically, each Session instance registers (via the addMessageHandler method) a separate instance of a MessageHandler i.e. there is a one-to-one relation b/w the peer who is sending a message (client), the Session (let's assume it's on the server end) and the MessageHandler instance (in this case it's responsible for receiving messages on the server side)

Thread Safety: The container will do as much as it can do ensure thread safety i.e. in case of MessageHandlers, it makes sure that only one thread enters a specific MessageHandler instance. In case the developer implementation is such that a single MessageHandler instance is registered to multiple Sessions, then concurrent access is inevitable and this needs to be accounted for

Encoder & Decoder

Instances: There is one instance of an Encoder/Decoder per connection (peer/client) for a specific server Endpoint

Thread Safety: A specific Endpoint instance itself is single-threaded (as mentioned above). In effect, what this means is that only thread can invoke an Encoder/Decoder instance specific to that endpoint

ServerEndpointConfig.Configurator & ClientEndpointConfig.Configurator

Instances: There is a single instance of a configurator (server/client) which exists per endpoint

Thread Safety: Both ServerEndpointConfig.Configurator & ClientEndpointConfig.Configurator are not thread safe since the container does not serialize concurrent access to a single instance. One needs to bear this in mind when writing a custom implementation of the same

WebsocketContainer & ServerContainer

Instances: A single instance exists per application

Thread Safety: It is thread safe in spite of the fact that multiple threads are allowed to invoke a single instance of the WebSocketContainer. This is because the the specification mandates implementations to ensure the integrity of the mutable properties of the session under such circumstances

Recap

Here is a table for quick reference

Component

Thread safe ?

Session

yes

Endpoint

yes (default only)

Encoder & Decoder

yes

ServerEndpointConfig.Configurator &ClientEndpointConfig.Configurator

No

MessageHandler

yes (default only)

WebsocketContainer & ServerContainer

yes

Last updated