Start
Overview
FairMQ is a C++17 library and framework for message queuing in data processing pipelines. Programs called devices send messages to each other through channels. FairMQ moves the messages with ZeroMQ, or through shared memory without a copy on one host.
What FairMQ is
Section titled “What FairMQ is”FairMQ comes from the FairRoot project at GSI. It helps to build the large data processing workflows of particle physics experiments. FairMQ has two parts:
- A library. It gives a message passing API with the communication patterns of ZeroMQ, for example
push/pull,pub/subandreq/rep. Different transports implement this API. You can use channels without a device. - A framework. You write devices. A device is a class that sends and receives messages. Each device has a state machine and a plugin system for configuration and control.
FairMQ does not look at the content of a message, so your data can have any format. A device can use different transports on different channels at the same time.
The building blocks
Section titled “The building blocks”| Building block | What it does | Page |
|---|---|---|
| Device | Runs your code. You derive a class from fair::mq::Device and override its hooks. The header fairmq/runDevice.h runs one device in one process. |
Devices |
| Channel, sub-channel, socket | A channel is a named connection point of a device, for example data. A channel has one or more sub-channels. Each sub-channel has one socket with a type (for example push), a method (bind or connect) and an address. |
Channels and sockets |
| Transport | Makes the messages, sockets, pollers and regions of a channel (fair::mq::TransportFactory). zeromq is the default transport. shmem moves the data through shared memory between devices on one host. |
Transports |
| Message and multipart | A message holds one buffer of bytes. A multipart message (fair::mq::Parts) holds several parts that a channel sends and receives as one unit. |
Messages and multipart |
| State machine and hooks | Each device has a state machine with states such as IDLE, READY and RUNNING. In some states, the device calls its hooks, for example InitTask() and ConditionalRun(). |
Device states |
| Configuration | Each device has a store of properties (fair::mq::ProgOptions). Command-line options, --channel-config, JSON files (--mq-config) and plugins set the properties. Your code reads them with GetProperty(). |
Configuration and properties |
| Plugins and controllers | Plugins add functions to a device at run time. A controller is a plugin that changes the state of the device. The built-in plugin control is the default controller. |
Plugins and control |
FairMQ has more parts for special tasks. A poller waits for data on several channels (see Poll several channels). An unmanaged region is a buffer that your code manages, and messages can point into it (see Unmanaged regions).
How the parts fit together
Section titled “How the parts fit together”A set of devices and the channels between them is a topology. The topology of example 1-1 has two devices. The sampler sends messages, and the sink receives them. The two devices work like this:
- You start each device as a process. The command line gives the device ID and the channel configuration, for example
--id sampler1 --channel-config name=data,type=push,method=bind,address=tcp://*:5555. - The built-in plugin
configreads the channel configuration into the properties of the device. - The built-in plugin
controlrequests the transitions of the state machine. The device goes fromIDLEthrough the initialization states toRUNNING. - In the states
BINDINGandCONNECTING, the device makes the sockets of its channels with the transportzeromq. The sampler binds itspushsocket. The sink connects itspullsocket. - In the state
RUNNING, the sampler makes a message inConditionalRun()and sends it on the channeldata. The sink receives each message in a data callback, which it registered withOnData(). - When you press Ctrl+C, the plugin
controlstops the device. The device goes through the reset states toEXITING.
Your first device shows these steps with the code of example 1-1. Threads in a device tells which thread runs each hook and callback. For the devices and channels of your own topology, see Design a topology.
What the installation contains
Section titled “What the installation contains”- The library
libfairmqand its headers ininclude/fairmq/. - The CMake package
FairMQwith the imported targetFairMQ::FairMQ. See Use FairMQ in a CMake project. - The header
fairmq/runDevice.h. It gives themain()function of a device program. - The built-in devices
fairmq-bsampler,fairmq-merger,fairmq-multiplier,fairmq-proxy,fairmq-sinkandfairmq-splitter. See Built-in devices. - The tool
fairmq-shmmonitor, which monitors and cleans up shared memory, and the toolfairmq-uuid-gen, which prints a UUID. - The examples and their start scripts (CMake option
BUILD_EXAMPLES, defaultON). - Optional: the static analyzer
fairmq-tidy(CMake optionBUILD_TIDY_TOOL, defaultOFF).
What FairMQ does not do
Section titled “What FairMQ does not do”- Deployment. FairMQ does not start devices on hosts. You start each device as a process, for example with a shell script like the start scripts of the examples. For a topology on many hosts, use a deployment system, for example DDS. ODC controls a topology of FairMQ devices through DDS. The example dds describes a topology for DDS.
- Serialization. A message is a buffer of bytes. FairMQ does not serialize your data. Your code defines the data format.
- A broker or storage. FairMQ has no broker. The devices connect directly to each other. FairMQ does not write messages to disk.
- Security. FairMQ does not encrypt or authenticate the connections between devices.
- Shared memory between hosts. The transport
shmemworks only between devices on one host. Between hosts, use the transportzeromq.
Where to go next
Section titled “Where to go next”- Install FairMQ with Spack or from source.
- Write, build and run your first device.
- Use FairMQ in a CMake project.
- Run the examples. Each example shows one feature.
- Read the concepts, starting with devices.
- Design a topology: the patterns, the binding devices and the transports.
- Test your devices with CTest.
- Measure the throughput of the transports with a benchmark.
- Look up a class in the API reference, or read the code in the source browser.