No description
Find a file
2026-01-01 00:00:00 +00:00
schema drivers/subprocesses: subprocess-adapter -> unix-subprocess 2024-12-22 17:12:10 +05:30
src drivers/http_servers: tidy up 2026-01-01 00:00:00 +00:00
tests Cleanup exceptions 2025-12-18 12:00:00 +00:00
.gitignore Generate .envrc with Tup 2024-11-27 12:40:00 +00:00
.gitmodules Submodules considered harmful 2022-03-16 13:00:58 -05:00
default.nix Rewrite gatekeepers, relays, and transports 2025-12-03 12:00:00 +00:00
depends.tup Rewrite gatekeepers, relays, and transports 2025-12-03 12:00:00 +00:00
nlnet.svg Update README 2024-04-08 14:50:36 +01:00
README.md README: add note about Q&A and observing observations 2024-12-25 16:34:57 +05:30
sbom.json drivers/http_servers: tidy up 2026-01-01 00:00:00 +00:00
syndicate.nimble *.nimble: swap nim:bin key and value 2024-09-30 16:40:59 +01:00
tup.config.nix Rewrite gatekeepers, relays, and transports 2025-12-03 12:00:00 +00:00
Tupfile Rewrite gatekeepers, relays, and transports 2025-12-03 12:00:00 +00:00
Tuprules.jq Tup: break up $(BIN_DIR)/<syndicate> group 2024-12-07 21:29:57 +00:00
Tuprules.tup Rewrite gatekeepers, relays, and transports 2025-12-03 12:00:00 +00:00
UNLICENSE Unlicense 2021-09-01 13:47:21 +02:00

Syndicated Actors for Nim

The Syndicated Actor model is a new model of concurrency, closely related to the actor, tuplespace, and publish/subscribe models.

The Syndicate library provides a code-generator and DSL for writing idiomatic Nim within the excution flow of the Syndicated Actor Model. The library allows for structured conversations with other programs and other languages. It can be used to implement distributed systems but also makes it possible to create dynamically reconfigurable programs using a process controller and a configuration conversation.

The Preserves Data Language

Preserves is foundational to Syndicate and likewise is the Nim Preserves library foundation to this Syndicate implementation. When familiarizing yourself with the code here you will need to reference the documentation of that library as well.

Examples

test_chat

Simple chat demo that is compatible with chat.py.

SYNDICATE_ROUTE='<route [<unix "/run/user/1000/dataspace">] [<ref {oid: "syndicate" sig: #x"69ca300c1dbfa08fba692102dd82311a"}>]>' nim c -r tests/test_chat.nim --user:fnord

syndicate_utils

Drivers

This SAM implementation includes protocol drivers that may be instantiated from a library or as a standalone component.

For drivers that require additional dependencies see syndicate_utils.

HTTP

HTTP server and client. HTTPS is not supported.

Subprocess

Execute UNIX subprocesses and exchange data over stdio using messages.

Tracing

Tracing is enabled at compile-time by default, unless disabled with --define:traceSyndicate=false. Tracing is not active at runtime unless the $SYNDICATE_TRACE_FILE environmental variable is set. Tracing is currently not available for solo5.

trace

There is an experimental tool for converting Syndicate traces to the Graphviz dot format at trace-to-dot. It should be compatible with traces from other Syndicate implementations.

Recommendations

The following are the authors recommendations for using this library and interoperating with external Syndicate components. If you find they differ from Tony Garnock-Jones recommendations, take Tony's recommendations instead.

Speak the gatekeeper protocol to expose local entities

When providing a service do not expose that service on the initial capability exposed to peers. Require that peers use the gatekeeper protocol to resolve service instead. Require the gatekeeper protocol regardless if the peer or transport is "trusted".

Some lines of reasoning leading to this method:

  • Components can multiplex services over a single protocol session.
  • Clients can "step though" relays directly into a service provided by your component using the standard gatekeeper routing mechanism.
  • Failure or success of service negotiation is made explicit.

Furthermore, if a service requires dataspace semantics, provide clients with a dataspace that is local to the service. The reasoning being:

  • Local assertions to local dataspaces only create transport traffic during observation by a peer.
  • A capability to a local service asserted to a peer can be asserted back to a different service hosted in the same daemon, in which case traffic between the service entities short circuits and becomes local traffic within a daemon (unless the client has amended caveats to a capability).

Example of using the gatekeeper protocol within a Syndicate server configuration:

# When the foobar service is required…
? <require-service <service foobar ?detail>>
[
  # Require the foobard daemon…
  <require-service <daemon foobard>>
  ? <service-object <daemon foobard> ?obj>
  [
    # Resolve the service using the gatekeeper protocol and announce the capability
    # using a <service-object <service foobar …> …> assertion.
    let ?rewriter = <* $config [ <rewrite ?resp <service-object <service foobar $detail> $resp>> ]>
    $obj <resolve <$label $detail> $rewriter>
  ]
]

Example of a stacked sturdyref route:

<route
    [<tcp "example.net" 1024>]
    <ref {oid: examples, sig: #[W1gClLD8dJDFt_NTYqd4xA]}>
    <example-service { turbo-mode-enable: #t }>
    <ref {oid: service-internals, sig: #[8SQ3tSe9r2dNwCnxd-pVvw]}>
  >

Actors and Facets

  • Do not share data between actors, use communication instead. Assume that other actors are running on other CPU cores.
  • Facets are cheaper than actors. Share data between facets within an actor.

Observations of Observations

Services can react to clients by observing observations or using <q …> and <a …> assertions from the RPC protocol. Use both. Observe observations and react to them by locally asserting <q …> and responding to the observer using data collected from the corresponding local <a …>. This allows errors in either case to be observed via <a _ <error ?>>.


This work has been supported by the NLnet Foundation and the European Commission's Next Generation Internet programme. The Syndicate Actor Model through the NGI Zero PET program and this library as a part of the ERIS project through NGI Assure.

NLnet