Skip to content
CraigHutchinsonPublic

About

Production tested C++ Type-based Subscriber-Publisher data-oriented scheduling model with minimal-to-no overhead

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

Sub0Pub

Typed publish-subscribe for C++23 that compiles to direct calls when the receivers are known.

Sub0Pub is a header-only library for synchronous, type-safe message delivery. Write publishers and subscribers once; each message type then says whether it is delivered through a bounded runtime broker, where subscribers subscribe and unsubscribe independently, or by direct calls to a known set of receivers. The core does not allocate broker storage from the heap; optional policies and application callbacks have their own costs.

Status: v2.0.0-alpha is CI-tested, but has not yet been field-tested.

One API; the message type decides the delivery

struct TemperatureReading { int celsius; };

class Sensor : public sub0::Publish<TemperatureReading> {
public:
    void sample(int celsius) noexcept { sub0::publish(*this, TemperatureReading{celsius}); }
};

class Display : public sub0::Subscribe<TemperatureReading> {
public:
    void receive(const TemperatureReading& reading) noexcept { /* show it */ }
};

As written, a Display subscribes when it is constructed and unsubscribes when it is destroyed: the runtime broker delivers through a bounded, per-type table. When the receivers of a type are known, name them beside the type and the same code compiles to direct calls, with no table, run-time subscription or virtual call behind it:

class Display;
extern Display display;

struct TemperatureReading {
    int celsius;
    using sub0_config = sub0::config<sub0::StaticTo<&display>>;
};
flowchart LR
    P[Publish T] -->|publish| C{T's configuration}
    C -->|nothing said| B[Runtime broker]
    C -->|StaticTo| R[Listed receivers, direct calls]
    C -->|StaticFirst| F[Listed receivers, direct calls]
    F --> B
    B -->|delivery through its table| S[Subscribe T, subscribed at run time]
Loading
Your case Say on the type Main constraint
1 Receivers subscribe and unsubscribe independently. Start here. nothing Fixed capacity; a subscription can fail when the table is full.
2 The receivers are a closed set of objects with static storage. sub0::StaticTo<&a, &b> The list is the whole truth: nothing subscribes or unsubscribes at run time.
3 A fixed core, plus receivers that subscribe and unsubscribe at run time. sub0::StaticFirst<&a> The broker's cost stays on every publication.

A publication that reaches no receiver is treated as a mistake: a debug build reports it, and a StaticTo list nobody can receive from does not compile. A type for which that is expected says sub0::AllowNoReceivers. An audit build reports every such mistake a run makes, and which message types are ready to name their receivers.

See basic pub/sub for subscribing and unsubscribing through object lifetime, promote to static for one application built both ways from one source, and dynamic diagnostics for a fixed receiver with probes that subscribe at run time beside it.

When the type cannot decide

Receivers that are local objects, several independent wirings of one message type, a receiver that stops a publication, and a transport bound beside local receivers are composed explicitly, with plain receiver classes:

auto wiring = sub0::wire(display, logger);
wiring.publish(TemperatureReading{22});

wire(...), StaticWiring, Sink<T>, Forward and BrokerPort<T> each exist for a specific case; the usage guide lists which.

Get started

Requirements: C++23 and CMake 3.21+. The CMake target propagates the language requirement; direct header users must select C++23 themselves.

find_package(Sub0Pub REQUIRED)
target_link_libraries(MyApp PRIVATE Sub0Pub::Sub0Pub)

Alternatively, add Sub0Pub as a subdirectory:

add_subdirectory(Sub0Pub)
target_link_libraries(MyApp PRIVATE Sub0Pub::Sub0Pub)

Build and run the tests from a clone:

cmake --preset default
cmake --build --preset default
ctest --preset default

#include <sub0pub/sub0pub.hpp> includes the full library. For smaller includes, see the header map.

Feature guides

The README is an overview; detailed behavior, constraints, and complete examples live in focused guides:

Guide Covers
Usage and wiring Which delivery to choose by case, moving a type to direct calls, explicit wiring, callback behavior, subscriber lifetime, and examples
Per-type configuration Where a type's configuration goes, topology, dispatch, context, capacity, filtering, cancellation, locking, scoped domains, and project defaults
IPC and transports Routes, forwarding, stream serialization, layout checks, and wire-format responsibilities
Runnable examples Standalone programs for the current API, organized by use case
Design and contracts Design rationale, measured constraints, and known limitations
Comparisons Architectural trade-offs versus related libraries; not a speed ranking
Migration notes Changes to consider when updating an existing application

How it compares

Sub0Pub focuses on synchronous typed delivery, fixed-capacity broker storage, and direct calls when the receiver set is known. It does not provide an event queue, scheduler, or GUI event loop. Whether that is a good fit depends on the application; the comparison notes describe the trade-offs without claiming cross-library performance superiority.

Performance and validation

Performance claims are measured against equivalent hand-written work. See the current performance baseline, measurement evidence, and compile-time measurements. The benchmark suite can be built with the tests:

cmake --build --preset default --target Sub0Pub_Bench

CI covers GCC, Clang, AppleClang, and MSVC on Linux, macOS, and Windows, with sanitizer configurations. This testing does not replace integration testing on a project's target platform.

License

MIT License -- Copyright (c) 2018 Craig Hutchinson

About

Production tested C++ Type-based Subscriber-Publisher data-oriented scheduling model with minimal-to-no overhead

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages