ach internals

Table of Contents

See Also

Overview

Ach is a formally verified library for message-bus or publish-subscribe IPC. Clients open channels and can post new messages or receive messages by polling or waiting for new data.

Ach is primarily intended for low-latency, real-time operation. One outcome of this is that -- in contrast to other FIFO IPC systems such as sockets -- a more recently arrived message may overwrite a previously received message regardless of whether the old message has been processed. This decision was made because real-time systems often care only about the most recent message, so it would not make sense to block the newer message until the old one had been removed from the queue.

Doxygen

Mechanism

Communication Primitives

Frames

Communication is done in terms of "Frames." A frame is simply a sequence of bytes (ie, a char[]). It is possible to send frames of varying size on a channel. Publishers send frames and subscribers will receive frames.

Channels

A "Channel" is a stream of frames. Each frame is published on a channel. All subscribers of channel may receive frames published on that channel. Channels is identified using a textual name. Multiple publishers may put frames on a channel.

Communication Method

Channel Implementation

Channels are implemented as circular buffers using posix shared memory. Providing for variable size frames requires an index array in addition to the data buffer. Thus the shared memory block will have three sections, a header, an index array, and a data buffer.

Network Protocol

The included `achpipe' program is capable of passing data over a network via TCP. To do this, inetd should be setup to fork an achpipe instance appropriately.

Milestones

  • M1: Client API "finalized". Publish-Subscribe implemented using shared memory
  • M1.5: Simple program to pass data across a network between SHM channels
  • M2 (future, maybe): Implement broker daemon to spread data about the network
    • May Use Posix Message Queues or a local socket to communicate between publishers and broker. One message to indicate a publish new channel operation and one message to indicate put new data. If using socket, double check atomicity of writes.
    • Add channel_id field to channel_header. This will be set by the broker when it is notified of a new channel. Broker can then notify the publisher who would be waiting on the condition variable.

Quirks

Upgrading glibc

to be safe, you should probably reboot afterwards. This has been known to break the synchronization on ubuntu.

Valgrind

Valgrind gets confused by mutexes and condition variables in shared memory. Sometimes it works; other times it breaks the channel. This means you can't reliably use valgrind to debug a program that uses ach. You might get some uses out of ach's map_anon feature, which puts the memory area for the channel into the process-local heap, but that probably won't get you very far. A better way may be to create a stand-in libach that popens achpipe rather than directly touching the shared memory.

Future Possibilities