Skip to content

Client Concurrency Model

The application uses a Publication API object that lives in the Client API to write messages to a log buffer. This is either an ExclusivePublication or a ConcurrentPublication. They differ in their thread safety - ExclusivePublication has no thread safety code and is faster, but it can only be used by one thread; ConcurrentPublication can safely be used by multiple threads.

The two types of Publication we've discussed so far (IpcPublication and NetworkPublication) are Media Driver concerns. They control what happens to a message after it has been written to a Publication log buffer. Once a message is in a Publication log buffer, it will either be read directly by a Subscription (for an IPC Publication) or sent over the network (for a Network Publication).

image logbuffers publication logbuffers cnc.dat Shared Memory Aeron Client Client Conductor Subscriptions Exclusive Publication Concurrent Publication Application Logic Receiver Driver Conductor Sender Media Driver IPC Publication Network Publication

The two Client-side Publication API objects and the two Driver-side Publication objects are orthogonal and all four combinations are allowed. The application chooses between the Publication API classes by choosing between two different methods in the Client API when creating the Publication:

    Aeron.addPublication(channel, streamId)            // creates a ConcurrentPublication
    Aeron.addExclusivePublication(channel, streamId)

Concurrent Publications

A Concurrent Publication is thread safe and allows messages to be safely written to the log buffer from multiple threads, or even different processes on the same machine.

The first time a Concurrent Publication is created for a given Channel and StreamId, the Media Driver creates the Publication log buffer, then returns a ConcurrentPublication API object to the application. This API object can be used by multiple threads to write messages to the Publication log buffer.

If the application creates a second Concurrent Publication for the same Channel and StreamId, it is returned a second ConcurrentPublication API object, but the API object writes to the existing Publication log buffer. The same applies if a different process on the same machine (same Media Driver) creates a Concurrent Publication for the same Channel and StreamId - it will get a new ConcurrentPublication API object, but it will write to the existing Publication log buffer (remember the log buffer is in shared memory, so it can be written to by any process on that machine).

Thread-safety is maintained by the way the ConcurrentPublication updates the log buffer. It uses a CAS operation to bump the tail position in the log buffer to reserve space for the message. This is safe across threads and processes - it doesn't matter which ConcurrentPublication API object is used to write to the log buffer.

Exclusive Publications

When an application knows it will only publish to a Publication from a single thread, it can create an Exclusive Publication, which uses faster operations that are not thread safe. It takes advantage of the Single Writer Principle to achieve greater throughput. Each Exclusive Publication has its own log buffer, which will not be shared with any other Publication. If a second Exclusive Publication (or even a Concurrent Publication) is created for the same Channel and StreamId, it will have its own log buffer and the Subscription will have to iterate over them both.

Log buffer data format

The data format in a Publication log buffer is the same, whether it is written to by an Exclusive or a Concurrent Publication. The difference is just in the thread-safety of the write operations.

SessionIds

You can think of SessionIds as belonging to the log buffer files. Each ExclusivePublication has its own log buffer file and thus its own SessionId. If there is more than one ConcurrentPublication API object for the same Channel and StreamId on a given machine, they will all use the same log buffer file and thus use the same SessionId (and note that the Subscriber won't be able to tell which API object wrote each message). ConcurrentPublications for the same Channel and StreamId on a different machine will have a different log buffer (different Media Driver as they're on different machines) and a different SessionId.

Subscriptions

There is only one kind of Subscription. They do not vary based on Concurrent vs Exclusive or Network vs IPC. Subscriptions are not thread-safe and should only be used by a single thread. However, it is possible to create multiple Subscriptions for the same Channel and StreamId. Each Subscription tracks its own position in each log buffer it reads from.

Note that if there is more than one log buffer for a Channel and StreamId (more than one SessionId), and more than one Subscription, the Subscriptions may read from the log buffers in a different order and receive messages from different Sessions in a different order.