|
CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
|
Pub/sub delivers messages to whoever is listening right now. Whiteboards and catalogs cover the other half of the problem: keeping data so it can be found later — past messages, files, persistent key/value data, recorded sessions.
A whiteboard holds messages in memory at run-time for any module to retrieve. Messages are indexed by time, and optionally by user-defined keys.
Messages arrive at a whiteboard in two ways:
Any message entering a whiteboard needs a TTL (time to live) greater than 0 and is removed automatically when it expires; the ttl= attribute on the post sets it in milliseconds, and a whiteboard-side KeepMS <parameter> can supply a default TTL for messages that arrive without one. Expiry is what bounds a whiteboard's size — there is no per-whiteboard message-count cap; the maxcount= attribute belongs to <retrieve> entries (below), where it limits how many messages one retrieve returns.
A module declares named retrieves in the PsySpec:
r1 is a plain time-indexed retrieve; r2 uses the custom integer index over the count user entry that WB1 declared with key=/keytype=. Crank code executes them by name via cmlabs::PsyAPI:
Status codes are the QUERY_SUCCESS / QUERY_TIMEOUT / QUERY_FAILED family. Note the ownership difference from triggers: messages returned by a retrieve are copies owned by you — delete them when done.
The classic use case combines whiteboards with contexts: when the system context changes, data that was irrelevant a moment ago may suddenly matter, and a freshly-in-context module can pull the recent history it missed from a whiteboard instead of having subscribed all along. Runnable demo: Examples/whiteboard.xml with the Examples::RetrieveTest crank in Examples/src/Examples.cpp.
A catalog fronts larger or longer-lived data with a query mechanism. Modules access catalogs through named <query> entries and one call, cmlabs::PsyAPI::queryCatalog() — regardless of which machine either side runs on. Three catalog types ship with the system (in the PsySystem library — System/src/Catalog.cpp — which you can copy and modify to build your own):
In the module:
In the crank — read ./test/test.txt from wherever the catalog lives:
Writing works the same way with a "write" action and a data buffer:
The ReadOnly parameter (default no) blocks writes when set to yes.
A central datastore, flushed from memory to root= every interval= milliseconds, surviving system restarts. Same query pattern as the FileCatalog — read/write a named entry:
Record chosen message types in one system, replay them later in another — e.g. capture two minutes of a robot's video/sensor messages, then develop against the recording with no robot present.
Recording (Examples/messagerecord.xml): the catalog subscribes like any component and writes matching messages to disk, bounded by maxsize= bytes and/or maxcount= messages:
Playback (Examples/messageplayback.xml): the same catalog with <post> entries re-posts the recorded messages with their original timing. Trigger and post names must match; the posted types may differ from the recorded ones:
| Need | Use |
|---|---|
| Recent message history, queryable by time or key | Whiteboard |
| Central file read/write across machines | FileCatalog |
| Small persistent state surviving restarts | DataCatalog |
| Deterministic replay of recorded traffic | ReplayCatalog |
| Custom storage/query semantics | Your own catalog (start from PsySystem) |
Everything on this page runs in Examples/single.xml (the Test.Catalogs phase) and Examples/whiteboard.xml; the crank side is Examples::RetrieveTest in Examples/src/Examples.cpp.