![]() |
Mads
Multi-Agent Distributed System
|
Namespaces | |
| namespace | detail |
| namespace | Doctor |
| namespace | Play |
| namespace | PluginMigrate |
| namespace | PluginSkill |
Classes | |
| class | Agent |
| class | AgentAppT |
| Application-facing wrapper for Agent and Agent subclasses. More... | |
| struct | AgentTopicInfo |
One mads.ini agent section's topics. More... | |
| class | ARIMA |
| class | BagError |
| Error thrown by BagWriter/BagReader for any I/O or format problem (bad magic, unsupported format_ver, unreadable/unwritable file, ...). More... | |
| class | BagReader |
| Reads a bag file written by BagWriter (or a compatible/truncated one), transparently using the trailing index when present and falling back to a linear scan otherwise. More... | |
| struct | BagRecord |
| class | BagWriter |
| Sequentially appends BagRecord entries to a bag file. More... | |
| class | Bridge |
| The Bridge class represents metadata for an agent. More... | |
| class | ClockConsensus |
| Per-clock-domain adoption of the smallest-delay measurement heard from any agent sharing that domain (§2.1 of the design): agents on one host announce their own measurements, and every agent applies this same deterministic rule – so they converge on one offset without an election. More... | |
| class | ClockOffsetEstimator |
| Accumulates ClockSamples and returns the classic NTP "best of N": the retained sample with the smallest round-trip delay, i.e. the one least polluted by queuing delay along the path. More... | |
| struct | ClockOffsetResult |
Result of a clock-offset measurement: offset_us added to a clock in the measured domain yields broker-host time (broker_host_clock - domain_clock). source/hops/origin_agent_id/seq are Agent-level bookkeeping the estimator does not fill in – only estimate()'s own offset_us/delay_us/samples/valid are computed from the timestamps. More... | |
| struct | ClockPeerObservation |
One responder's answer to Agent::broadcast_clock_probe()'s ping (clock-offset source B, see clock_offset.hpp): the raw four-timestamp sample plus the responder's identity and its own currently adopted clock offset, which is what lets an initiator compose clock_offset(mine) = responder_adopted.offset_us + estimate(sample).offset_us rather than treating a peer exchange as an unrelated measurement. More... | |
| struct | ClockSample |
| One four-timestamp exchange, all fields microseconds since the Unix epoch: t1/t4 read from the initiator's clock, t2/t3 from the responder's. More... | |
| class | CurveAuth |
| struct | CurveKeypair |
| A CURVE keypair, both keys Z85-encoded (40 characters each). More... | |
| class | Dealer |
| struct | DirectorConfig |
A fully parsed, validated, expanded director.toml. processes is already in a valid topological start order (every entry's after names appear earlier in the vector), so mads up can just iterate it in order. More... | |
| struct | DirectorLoadOptions |
| Caller-supplied overrides applied while the file is expanded. More... | |
| class | Dummy |
| struct | EchoRenderOptions |
Rendering choices for format_echo_json()/format_echo_blob(), mirroring mads echo's CLI flags. More... | |
| class | ExecutionTimeWindowStats |
| Running window statistics for execution time samples. More... | |
| class | GoBack |
| struct | GraphOptions |
| Rendering knobs for topology_graph(). More... | |
| struct | HostSkewStat |
| Snapshot of one host's passive clock skew, as computed by HostSkewStats::snapshot() at a given instant. More... | |
| class | HostSkewStats |
Thread-safe sliding-window tracker of per-host clock skew, fed by mads top's passive mode: for every received message, record (local_rx_time - payload's own timestamp field), both as epoch microseconds. No protocol at all – works against any existing MADS deployment, since timestamp/hostname are already stamped on every published message by Agent::publish(). More... | |
| class | HttpsClient |
| Portable HTTPS GET client with zero external dependencies. More... | |
| class | Image |
| The RFID class represents metadata for an agent. More... | |
| struct | image_data_t |
| class | LazyPayload |
| A received message payload that lazily holds either its JSON text or its parsed nlohmann::json form, caching whichever is produced on first use. More... | |
| struct | LinkState |
| class | Logger |
| The Logger class is responsible for logging messages to a MongoDB instance. More... | |
| class | Metadata |
| The Metadata class represents metadata for an agent. More... | |
| class | MongoFetch |
| Replay reader over one or more MongoDB collections. More... | |
| struct | ProbeCurveKeys |
| Client-side CURVE credentials for a probe socket: the same key_dir/client/server naming convention every mads-* executable's –crypto/–keys_dir/–key_client/–key_broker flags configure (and that Mads::CurveAuth::setup_curve_client() reads). More... | |
| struct | ProcessConfig |
One process instance, after scale expansion and template substitution. This is what mads up actually starts: one ProcessConfig per launched OS process. More... | |
| struct | ReadySpec |
A parsed, validated ready = "..." value. More... | |
| struct | RunResult |
| class | ServiceDiscovery |
| struct | SharedLatest |
| class | SocketMonitor |
| One monitor per monitored socket. start() must be called before the socket's connect()/bind(): libzmq lets a connection through – and may fire its lifecycle events – while no monitor is attached yet, exactly the same race Mads::ZapAuth::start() avoids for the ZAP handler. More... | |
| struct | TopicStat |
| Snapshot of one topic's aggregated activity, as computed by TopicStats::snapshot() at a given instant. More... | |
| class | TopicStats |
| Thread-safe sliding-window aggregator of per-topic msg/s and bytes/s, fed by record() and read back via snapshot(). More... | |
| struct | UpOptions |
| class | UpSupervisor |
| Starts, supervises and tears down the processes described by an expanded Mads::DirectorConfig. Foreground-only by design (see NEW_FEATURES.md P5): one call to run() drives the whole lifecycle and blocks until teardown completes. More... | |
| class | Watcher |
| class | Worker |
| class | ZapAuth |
| In-process ZAP (ZeroMQ Authentication Protocol, RFC 27) handler. More... | |
Typedefs | |
| using | AgentApp = AgentAppT< Agent > |
| template<typename AgentT > | |
| using | AgentAppFor = AgentAppT< AgentT > |
| using | json = nlohmann::json |
| using | LiveSubscriptions = std::map< std::string, int > |
Enumerations | |
| enum class | CurveProbeResult { Connected , RejectedAuth , Timeout } |
| enum class | ClockSource { None = 0 , Broker = 1 , Peer = 2 } |
| Which mechanism produced a ClockOffsetResult. More... | |
| enum class | auth_verbose { off , on } |
| enum class | ReadyKind { Broker , Port , Log , Delay } |
Discriminates the four ready = "..." probe kinds. More... | |
| enum class | LinkEvent { None , Connected , ConnectDelayed , ConnectRetried , HandshakeSucceeded , HandshakeFailedAuth , HandshakeFailedProtocol , HandshakeFailedNoDetail , Disconnected , AcceptFailed } |
| enum class | LinkStatus { Unknown , Up , Down } |
| enum class | SubMatch { None , Exact , Prefix , Wildcard } |
| enum class | RunOutcome { Ok , Timeout , ReadyTimeout , StartFailed , ProcessFailed } |
Functions | |
| std::unique_ptr< Agent > | start_agent (std::string name, std::string settings_uri, std::map< std::string, std::string > crypto_settings={}) |
| Quick Agent initialization function. | |
| bool | probe_broker (const std::string &uri, std::chrono::milliseconds timeout, const std::optional< ProbeCurveKeys > &curve=std::nullopt) |
Probes whether a MADS broker's settings endpoint is up and speaking the MADS wire protocol: connects a REQ socket to uri, sends [LIB_VERSION, "settings", <probe-name>] and waits up to timeout for any reply. Any protocol-shaped reply counts as success – this does not try to load or validate settings for a real agent, it only proves the broker is listening and answering. ZeroMQ's own TCP reconnect logic means a single bounded receive is enough to also cover "not up yet" within timeout. | |
| bool | probe_tcp_port (const std::string &host, int port, std::chrono::milliseconds timeout) |
Probes whether a local TCP port is accepting connections, retrying (short bounded attempts) until timeout elapses. Used by ready = "port:<n>". | |
| CurveProbeResult | probe_curve_handshake (const std::string &uri, const std::filesystem::path &key_dir, const std::string &client_key_name, const std::string &server_key_name, std::chrono::milliseconds timeout) |
Attempts a real CURVE handshake against uri, using the client and server keys Mads::CurveAuth::setup_curve_client() reads from key_dir (same file convention as mads doctor --crypto's key check). A Mads::SocketMonitor attached before connecting distinguishes a genuine ZMQ_EVENT_HANDSHAKE_FAILED_AUTH rejection from an unreachable broker or an unresponsive one, both of which previously looked identical – a timeout. | |
| std::optional< std::map< std::string, int > > | fetch_subscription_table (const std::string &sub_uri, std::chrono::milliseconds timeout, const std::optional< ProbeCurveKeys > &curve=std::nullopt) |
Reads one live subscription table off a broker that was started with [broker] subscription_table = true, by subscribing to the subscriptions topic exactly as any ordinary agent would. | |
| ClockOffsetResult | estimate (const ClockSample &s) |
| NTP-style estimate from one four-timestamp exchange. | |
| std::optional< std::chrono::milliseconds > | parse_duration (const std::string &text) |
Parses a duration string like "500ms", "2s", "1.5s", "3m" into a std::chrono::milliseconds value. A bare number (no unit) is interpreted as seconds. Returns std::nullopt on malformed input (empty string, non-numeric magnitude, unknown unit, or a negative value). | |
| std::optional< ReadySpec > | parse_ready_spec (const std::string &value, std::string *out_error) |
Parses a raw ready string into a ReadySpec. Exposed standalone (rather than only reachable through load_director_config()) so it has its own focused unit tests. | |
| std::optional< DirectorConfig > | load_director_config (const std::string &path, std::string *out_error, std::vector< std::string > *out_warnings=nullptr, const DirectorLoadOptions &options={}) |
| Loads, validates, expands and orders a director.toml file. | |
| std::string | format_echo_json (const std::string &topic, const nlohmann::json &payload, size_t wire_size, const EchoRenderOptions &opts) |
Formats one received JSON message for mads echo stdout. | |
| std::string | format_echo_blob (const std::string &topic, const std::string &format, const unsigned char *data, size_t len, const EchoRenderOptions &opts) |
Formats one received blob message for mads echo stdout. | |
| std::string | base64_encode (const unsigned char *data, size_t len) |
Standard base64 encoding (RFC 4648, with = padding). | |
| std::filesystem::path | exec_path () |
| std::string | exec_dir (std::string relative="") |
| std::string | prefix () |
| GoBack | goback (std::size_t lines, bool really=true) |
| bool | topic_match (std::string_view pattern, std::string_view topic) |
| Tests whether a concrete topic matches an MQTT-style pattern. | |
| bool | has_wildcard (std::string_view sub_entry) |
Tells whether a sub_topic entry is a wildcard pattern. | |
| SubMatch | subscription_match (std::string_view sub_entry, std::string_view topic) |
| Single source of truth for "would an agent subscribing to
`sub_entry` receive a message published on `topic`?". | |
| bool | subscription_matches (std::string_view sub_entry, std::string_view topic) |
| Convenience predicate over subscription_match(). | |
| std::string | literal_prefix (std::string_view pattern) |
| Computes the longest literal (wildcard-free) prefix of a pattern. | |
| bool | is_implicitly_subscribed_topic (const std::string &topic) |
| std::string | topology_graph (const std::map< std::string, AgentTopicInfo > &agents, const GraphOptions &options={}) |
| Builds Graphviz DOT text describing the declared pub/sub topology of a set of agent sections. | |
| CurveKeypair | generate_keypair () |
| Generate a fresh CURVE keypair. | |
| std::string | z85_encode (const std::string &data) |
| Z85-encode a binary buffer. | |
Variables | |
| constexpr uint32_t | BAG_FORMAT_VERSION = 1 |
| constexpr const char * | kDefaultBrokerProbeUri = "tcp://localhost:9092" |
Default broker settings URI probed by a bare ready = "broker". | |
| using Mads::AgentApp = typedef AgentAppT<Agent> |
Definition at line 654 of file agent_app.hpp.
| using Mads::AgentAppFor = typedef AgentAppT<AgentT> |
Definition at line 657 of file agent_app.hpp.
| using Mads::json = typedef nlohmann::json |
Definition at line 18 of file service_discovery.hpp.
| using Mads::LiveSubscriptions = typedef std::map<std::string, int> |
A live topic -> subscriber-count table as published by a broker running with [broker] subscription_table = true (see Mads::fetch_subscription_table()).
Keys are the prefixes agents actually passed to zmq_setsockopt(ZMQ_SUBSCRIBE), i.e. a declared sub_topic entry after Mads::literal_prefix() – so a wildcard entry appears under its literal prefix, never as the pattern. The table carries NO peer identity (ZMQ subscription frames have none), so it can only ever answer "is anyone
subscribed to this prefix", never "which agent".
Definition at line 61 of file topology_graph.hpp.
|
strong |
|
strong |
Which mechanism produced a ClockOffsetResult.
| Enumerator | |
|---|---|
| None | |
| Broker | |
| Peer | |
Definition at line 42 of file clock_offset.hpp.
|
strong |
Outcome of a CURVE-handshake probe (ZMQ_DEVELOPMENT.md §2.1): what a socket monitor actually observed, distinguishing "the broker rejected this key" from "nothing answered at all" – a rejection previously surfaced as an identical bare timeout in both cases.
| Enumerator | |
|---|---|
| Connected | |
| RejectedAuth | |
| Timeout | |
Definition at line 88 of file broker_probe.hpp.
|
strong |
The connectivity events SocketMonitor exposes, condensed from libzmq's full ZMQ_EVENT_* set (zmq_socket_monitor(3)) down to what a caller acts on: is the link up, did the handshake fail, and if so why.
| Enumerator | |
|---|---|
| None | |
| Connected | |
| ConnectDelayed | |
| ConnectRetried | |
| HandshakeSucceeded | |
| HandshakeFailedAuth | |
| HandshakeFailedProtocol | |
| HandshakeFailedNoDetail | |
| Disconnected | |
| AcceptFailed | A bound socket could not accept an inbound connection. Unlike every other event here this describes the listener, not a link: the peer it would have belonged to never got far enough to have one. The errno libzmq reported (EMFILE when the process is out of file descriptors) arrives with it, in LinkState::last_event_value. |
Definition at line 31 of file socket_monitor.hpp.
|
strong |
Whether the link is usable right now. Where LinkEvent is a point-in-time observation, this is the state those observations add up to – which is what a caller reporting "am I still talking to the broker?" actually needs.
Definition at line 53 of file socket_monitor.hpp.
|
strong |
Discriminates the four ready = "..." probe kinds.
| Enumerator | |
|---|---|
| Broker | |
| Port | |
| Log | |
| Delay | |
Definition at line 51 of file director_config.hpp.
|
strong |
| Enumerator | |
|---|---|
| Ok | |
| Timeout | |
| ReadyTimeout | |
| StartFailed | |
| ProcessFailed | |
Definition at line 62 of file up_supervisor.hpp.
|
strong |
How one sub_topic entry matched a concrete published topic. See subscription_match(): the two literal outcomes exist because a literal entry is issued verbatim as a raw ZeroMQ SUBSCRIBE frame, which matches by byte prefix, so "sensors" genuinely receives "sensors/imu/raw" too.
| Enumerator | |
|---|---|
| None | Not delivered. |
| Exact | Literal entry equal to the topic. |
| Prefix | Literal entry that is a strict byte prefix of the topic. |
| Wildcard | Entry containing '+'/'#', matched per topic_match(). |
Definition at line 80 of file topic_match.hpp.
| std::string Mads::base64_encode | ( | const unsigned char * | data, |
| size_t | len | ||
| ) |
Standard base64 encoding (RFC 4648, with = padding).
Exposed mainly so tests can decode format_echo_*'s --raw output without duplicating the alphabet; mads echo itself only ever encodes.
| ClockOffsetResult Mads::estimate | ( | const ClockSample & | s | ) |
NTP-style estimate from one four-timestamp exchange.
offset_us = ((t2-t1) + (t3-t4)) / 2 (assumes a symmetric path; an asymmetric one biases the estimate by half the asymmetry – this is a property of the algorithm, not a bug, and is why several samples and ClockOffsetEstimator::best() matter).
delay_us is (s.local_elapsed_us - (t3-t2)) when local_elapsed_us is non-zero, so a system_clock step or manual date change occurring during the exchange cannot produce a negative or absurd delay; it falls back to (t4-t1) - (t3-t2) otherwise.
Only offset_us/delay_us/samples(=1)/valid are set; source/hops/ origin_agent_id/seq are Agent-level bookkeeping filled in by the caller.
|
inline |
Definition at line 62 of file exec_path.hpp.
References exec_path().
Referenced by Mads::AgentAppT< AgentT >::add_common_options(), and prefix().
|
inline |
Definition at line 46 of file exec_path.hpp.
Referenced by exec_dir().
| std::optional< std::map< std::string, int > > Mads::fetch_subscription_table | ( | const std::string & | sub_uri, |
| std::chrono::milliseconds | timeout, | ||
| const std::optional< ProbeCurveKeys > & | curve = std::nullopt |
||
| ) |
Reads one live subscription table off a broker that was started with [broker] subscription_table = true, by subscribing to the subscriptions topic exactly as any ordinary agent would.
The table is a topic -> live-subscriber-count map, built by the broker from its XPUB backend's own subscribe/unsubscribe notifications. It is deliberately anonymous: ZMQ subscription frames carry no peer identity, so this says how many sockets are subscribed to a prefix, never which agents they belong to. Keys are the prefixes actually passed to zmq_setsockopt(ZMQ_SUBSCRIBE), i.e. a declared sub_topic entry after Mads::literal_prefix() – a wildcard entry appears here as its literal prefix, not as the pattern.
The broker republishes the table about once a second, so timeout must comfortably exceed that to be reliable; 2000 ms or more is sensible.
| sub_uri | the broker's backend (subscribe) endpoint, i.e. where agents connect their SUB sockets. |
| timeout | how long to wait for one table to arrive. |
| curve | CURVE credentials to subscribe with; must be set when the broker runs with –crypto, exactly as for any other agent's SUB socket. |
subscription_table not enabled, or the wrong encryption mode for this broker). Never throws. | std::string Mads::format_echo_blob | ( | const std::string & | topic, |
| const std::string & | format, | ||
| const unsigned char * | data, | ||
| size_t | len, | ||
| const EchoRenderOptions & | opts | ||
| ) |
Formats one received blob message for mads echo stdout.
| topic | The message's topic. |
| format | The blob's declared format (e.g. "raw"), from its metadata; "raw" is used when the metadata did not specify one. |
| data | Pointer to the blob bytes (may be null iff len == 0). |
| len | Number of bytes in the blob. |
| opts | Rendering choices. |
| std::string Mads::format_echo_json | ( | const std::string & | topic, |
| const nlohmann::json & | payload, | ||
| size_t | wire_size, | ||
| const EchoRenderOptions & | opts | ||
| ) |
Formats one received JSON message for mads echo stdout.
| topic | The message's topic. |
| payload | The already-decoded JSON payload. |
| wire_size | Size, in bytes, of the message as it arrived on the wire (independent of the pretty-printed width). |
| opts | Rendering choices. |
| CurveKeypair Mads::generate_keypair | ( | ) |
Generate a fresh CURVE keypair.
Replaces zmqpp::curve::generate_keypair(); cppzmq exposes no wrapper for zmq_curve_keypair(), so the C API is called directly (as doctor_checks.cpp already does for zmq_z85_decode).
| zmq::error_t | if libzmq was built without CURVE support. |
Referenced by zmqpp::curve::generate_keypair().
|
inline |
Definition at line 121 of file goback.hpp.
| bool Mads::has_wildcard | ( | std::string_view | sub_entry | ) |
Tells whether a sub_topic entry is a wildcard pattern.
Deliberately as coarse as the runtime check it replaces: ANY occurrence of '+' or '#' anywhere in the string, not just a whole wildcard token. A entry like "a+b" therefore takes the wildcard path even though topic_match() matches its "a+b" token literally – keeping the two in step matters more than the (unreachable in practice) tightening, since Agent::connect_sub() and every consumer of subscription_match() must classify an entry the same way or the graph and the wire disagree.
| sub_entry | One sub_topic entry. |
| bool Mads::is_implicitly_subscribed_topic | ( | const std::string & | topic | ) |
Topics MADS subscribes to programmatically rather than through a declared sub_topic, plus the one this very query creates. They appear in a live table with nobody having declared them, and reporting them as undeclared subscribers would cry wolf on every single run:
control – pushed onto _sub_topic by Agent::enable_remote_control()subscriptions – the reader of the table is itself a subscriber | std::string Mads::literal_prefix | ( | std::string_view | pattern | ) |
Computes the longest literal (wildcard-free) prefix of a pattern.
Meant to be issued as the raw ZeroMQ SUBSCRIBE frame for a wildcard pattern: it must be a byte-prefix of every topic topic_match() would accept for that pattern (a superset is fine – broader than needed, e.g. "sensors/+/x" -> "sensors/", and topic_match() narrows it back down on the receive side – but never a subset, or a real match gets silently dropped by ZMQ before topic_match() ever runs).
| pattern | Subscription pattern. |
| std::optional< DirectorConfig > Mads::load_director_config | ( | const std::string & | path, |
| std::string * | out_error, | ||
| std::vector< std::string > * | out_warnings = nullptr, |
||
| const DirectorLoadOptions & | options = {} |
||
| ) |
Loads, validates, expands and orders a director.toml file.
| path | path to the director.toml file. |
| out_error | set to a human-readable message on failure (malformed TOML, missing/invalid command, unknown after target, dependency cycle, invalid scale, duplicate process name, invalid ready value, etc). |
| out_warnings | if non-null, appended with one human-readable message per ignored unknown key/section. This module never writes to stdout/stderr itself (it stays a pure function of its input); the caller (mads-up) decides how to display these. |
| options | overrides applied during expansion; see DirectorLoadOptions. Defaulted, so existing call sites are unaffected. |
Unknown top-level keys/sections/tables and unknown keys inside a process table are ignored, never fatal – a deliberate design choice (see NEW_FEATURES.md's P5 "Parser ownership" decision), not a fidelity match to Director's own parser (which is stricter about non-table top-level entries; see the comment at the top of director_config.cpp).
| std::optional< std::chrono::milliseconds > Mads::parse_duration | ( | const std::string & | text | ) |
Parses a duration string like "500ms", "2s", "1.5s", "3m" into a std::chrono::milliseconds value. A bare number (no unit) is interpreted as seconds. Returns std::nullopt on malformed input (empty string, non-numeric magnitude, unknown unit, or a negative value).
Recognized units: "ms" (milliseconds), "s" (seconds), "m" (minutes). Used both by ready = "delay:<dur>" and by mads-up's CLI duration flags (–timeout, –grace), so it lives here rather than duplicated in up.cpp.
| std::optional< ReadySpec > Mads::parse_ready_spec | ( | const std::string & | value, |
| std::string * | out_error | ||
| ) |
Parses a raw ready string into a ReadySpec. Exposed standalone (rather than only reachable through load_director_config()) so it has its own focused unit tests.
|
inline |
Definition at line 71 of file exec_path.hpp.
References exec_dir().
| bool Mads::probe_broker | ( | const std::string & | uri, |
| std::chrono::milliseconds | timeout, | ||
| const std::optional< ProbeCurveKeys > & | curve = std::nullopt |
||
| ) |
Probes whether a MADS broker's settings endpoint is up and speaking the MADS wire protocol: connects a REQ socket to uri, sends [LIB_VERSION, "settings", <probe-name>] and waits up to timeout for any reply. Any protocol-shaped reply counts as success – this does not try to load or validate settings for a real agent, it only proves the broker is listening and answering. ZeroMQ's own TCP reconnect logic means a single bounded receive is enough to also cover "not up yet" within timeout.
| uri | broker settings endpoint, e.g. "tcp://localhost:9092". |
| timeout | time budget to wait for a reachable broker. |
| curve | CURVE credentials to probe with; must be set to reach a broker running with –crypto, and must be unset to reach one without it. |
| CurveProbeResult Mads::probe_curve_handshake | ( | const std::string & | uri, |
| const std::filesystem::path & | key_dir, | ||
| const std::string & | client_key_name, | ||
| const std::string & | server_key_name, | ||
| std::chrono::milliseconds | timeout | ||
| ) |
Attempts a real CURVE handshake against uri, using the client and server keys Mads::CurveAuth::setup_curve_client() reads from key_dir (same file convention as mads doctor --crypto's key check). A Mads::SocketMonitor attached before connecting distinguishes a genuine ZMQ_EVENT_HANDSHAKE_FAILED_AUTH rejection from an unreachable broker or an unresponsive one, both of which previously looked identical – a timeout.
| uri | broker endpoint to connect a CURVE client socket to (frontend, backend, or settings – any CURVE-secured socket works). |
| key_dir | directory holding the client/server key files. |
| client_key_name | base name of the client's key files. |
| server_key_name | base name of the server's public key file. |
| timeout | time budget to wait for the handshake to resolve. |
| bool Mads::probe_tcp_port | ( | const std::string & | host, |
| int | port, | ||
| std::chrono::milliseconds | timeout | ||
| ) |
Probes whether a local TCP port is accepting connections, retrying (short bounded attempts) until timeout elapses. Used by ready = "port:<n>".
| host | hostname or IP to probe; "localhost" and an empty string both mean 127.0.0.1. |
| port | TCP port number. |
| timeout | time budget to wait for the port to start accepting. |
| std::unique_ptr< Agent > Mads::start_agent | ( | std::string | name, |
| std::string | settings_uri, | ||
| std::map< std::string, std::string > | crypto_settings = {} |
||
| ) |
Quick Agent initialization function.
| name | Agent's name |
| settings_uri | URI for the settings file (e.g. "/path/to/mads.ini" or "tcp://broker:5555") |
| crypto_settings | A map with crypto settings. If empty, crypto is disabled. If not empty, it must contain the following keys: key_dir, key_client, key_broker. |
| AgentError | if there is an error in the initialization (e.g. settings file |
| SubMatch Mads::subscription_match | ( | std::string_view | sub_entry, |
| std::string_view | topic | ||
| ) |
Single source of truth for "would an agent subscribing to `sub_entry` receive a message published on `topic`?".
Reproduces both stages of the runtime subscribe path exactly (see Agent::connect_sub() / Agent::_topic_matches_subscription(), which are implemented on top of this function):
SubMatch::Prefix: entry "sensors" receives "sensors/imu/raw", and the subscribe-all convention sub_topic = [""] receives everything. NOTE this is not topic_match()'s rule – topic_match() is exact-literal and would reject both.SubMatch::Wildcard).| sub_entry | One sub_topic entry (pattern or literal). |
| topic | Concrete published topic. |
Referenced by subscription_matches().
|
inline |
Convenience predicate over subscription_match().
| sub_entry | One sub_topic entry. |
| topic | Concrete published topic. |
Definition at line 118 of file topic_match.hpp.
References None, and subscription_match().
| bool Mads::topic_match | ( | std::string_view | pattern, |
| std::string_view | topic | ||
| ) |
Tests whether a concrete topic matches an MQTT-style pattern.
| pattern | Subscription pattern, e.g. "sensors/+/x" or "sensors/#". |
| topic | Concrete topic to test, e.g. "sensors/acc/x". |
topic matches pattern, per the grammar documented at the top of this file. | std::string Mads::topology_graph | ( | const std::map< std::string, AgentTopicInfo > & | agents, |
| const GraphOptions & | options = {} |
||
| ) |
Builds Graphviz DOT text describing the declared pub/sub topology of a set of agent sections.
One record-shaped node per entry, colored by inferred role (source = declared pub_topic only -> darkred; filter = both -> darkgreen; sink = sub_topic only -> darkblue; neither -> no color attribute; the role is always read off the declared keys, so an implicit pub_topic never turns a sink green), with a dashed contour on any agent that has a dangling topic: a declared pub_topic nothing subscribes to, or a sub_topic entry nothing ever publishes to. Every dangling topic is also marked in the node's own label with a trailing [!], so which entry is dead is visible without cross-referencing the edges. An agent's own pub_topic matching its own sub_topic – a self-loop – counts as satisfied on both sides, matching real broker behavior.
One edge is drawn per matching (publisher, subscriber) section pair, where "matching" is Mads::subscription_match(), i.e. exactly what the agent would receive on the wire: literal sub_topic entries match by byte prefix (sensors receives sensors/imu/raw; "" receives everything) and wildcard entries match per MQTT rules. Because those looser matches are precisely what a topology graph is for, how the edge came to exist is encoded in it: solid for an exact match, dashed for a prefix catch, dotted for a wildcard, and any non-exact edge names the responsible pattern(s) in its label (topic over via pattern, ..., with the subscribe-all pattern shown as (all)). An edge published under an implicit pub_topic is additionally drawn in grey. Edges are only drawn between distinct sections (a self-match never produces a self-loop edge, though it still counts toward the dangling computation above).
| agents | Map of section name -> declared topics. A std::map is used (rather than unordered_map) so node/edge emission order is deterministic (alphabetical by section name), which keeps output diffable and unit tests exact-string-comparable. |
| options | Rendering knobs; see GraphOptions. |
digraph mads { ... } DOT text, newline-terminated. | std::string Mads::z85_encode | ( | const std::string & | data | ) |
Z85-encode a binary buffer.
| data | The bytes to encode; the length must be a multiple of 4. |
|
inlineconstexpr |
|
constexpr |
Default broker settings URI probed by a bare ready = "broker".
Definition at line 72 of file director_config.hpp.