jonnifyechomq

Trafikist · module 01

Valkey and the module

Native code the server loads at startup, and a module that checks its host, its APIs and its own table before it serves one command.

Trafikist is Valkey plus one Rust module. This module reads that module the way the server meets it: a shared library named on a loadmodule line, loaded when the server starts, registering commands through the module API. The module is trafikey. Before it registers anything it refuses the load unless the host is a Valkey 9 server, every host API it calls is present and the loadmodule line passes no arguments. Then every command registers from one table, and init refuses the load unless that table and the registered set agree. The Protocol's native module introduced the second executor; this module goes underneath it.

Native code, loaded at startup

A Valkey module is a shared library of native code. The server loads it when it starts, from a loadmodule line in its configuration, calls the module's load entry point, and from then on runs the module's commands when clients call them. trafikey is a Rust crate built as exactly that kind of library: a cdylib, a shared object with a C ABI and no network listener of its own.

# trafikey — the crate manifest: a library the server loads, with no server of its own
[package]
name = "trafikey"
# …
[lib]
crate-type = ["cdylib"]
# …
# The cdylib is loaded by Valkey; no standalone RESP listener or bitmap data type is implemented here.

The line that loads it is one directive, loadmodule, naming the shared library at /opt/trafikey/libtrafikey.so. The deploy folder keeps that line as a fragment of its own, module.load.conf, under a warning: the fragment is never a complete server configuration, it is included only from the observed startup path after a first rehearsal, and loading trusted native code is itself a production change.

The fragment is a reviewed recipe, and the deploy folder records its runtime as unverified. Where the module runs is the stand: a node of its own on port 6391, whose configuration carries the loadmodule line, beside the Echo service node on port 6390, which loads no module. The installer builds the module on the machine that runs it, as libtrafikey.dylib on macOS and libtrafikey.so on Linux; the release’s own artifact is a darwin-arm64 .dylib.

A module is a library the server loads, not a service beside it: one line at startup, on a node that agrees to run native code.

What trafikey checks before it registers anything

Loading runs in three steps inside that one entry point. First the gate, preload, before any command exists: the host's major version must be 9, every host API the module calls must be present, and the loadmodule line must pass no arguments. Then every row of the registration table registers its command. Then init runs: it sets each row's ACL categories and refuses the load unless the table and the registered set are equal, reads the server's process identity, records whether the server runs in cluster mode, and exports the module's shared C API. preload and init each answer Status::Ok or Status::Err, and an Err refuses the load.

// trafikey — preload, the load gate the module declaration names
/// Load gate, before anything registers: no module arguments, a Valkey 9.x host, and every
/// host API this module calls present. raw wrappers unwrap the host pointers and the release
/// profile aborts on panic, so a missing API must refuse the load instead of killing the node.
fn preload(ctx: &Context, args: &[ValkeyString]) -> Status {
    let apis = registry::host_apis_present();
    match ctx.get_server_version() {
        // all three at once: every API present, no arguments, major 9
        Ok(v) if apis && args.is_empty() && v.major == 9 => Status::Ok,
        // anything else, a version the host cannot report included, refuses the load
        _ => Status::Err,
    }
}

The load path · pick a host

loadmoduleserver start preloadthe gate registerone per row initACL · epoch · mode servingcommands loaded · 24 commands registered · EMQ served
Valkey 9, standalone, no arguments — loaded
preload: Status::Ok (every host API present, no arguments, major 9)
register: 24 commands from the table (18 EMQ.*, 6 TRA.*)
init: ACL categories set on every row · run_id read and held · mode recorded: standalone · shared API exported
serving: every EMQ.* command passes the mode check; EMQ.VERSION lists 17 capability tokens

The gate runs before the first command exists, so on a host the module cannot run on, no EMQ.* or TRA.* command is ever registered.

One table, two families

Every command arrives through one table. The module's declaration lists no commands of its own; each row of registry::TABLE carries a command's name, family, arity, flags, key-spec, ACL categories and capability tokens, and four things derive from it: registration, the ACL categories init sets, the capability list EMQ.VERSION advertises, and the bitmap count TRA.CAPABILITIES reports. The default build registers twenty-four commands: eighteen EMQ.* rows (the read-only EMQ.VERSION, thirteen job-core write verbs, three bus write verbs and the administrative EMQ.INSTALL) and six TRA.* rows (two metadata commands and four bitmap commands on ordinary strings).

// trafikey — the crate's own rule, from its module documentation
//! A command exists by having its row in [`registry::TABLE`]; its handler stays in its family's
//! module. `init` sets every row's ACL categories and refuses the load on any mismatch.

A command exists by having its row: the table is the module's whole command surface.

Standalone only

The module serves standalone servers. init reads the server mode once. On a cluster-enabled server the module still loads and every command stays registered, but every EMQ.* write verb refuses with EMQWIRE expected a standalone server but cluster mode is enabled before it reads a key, and EMQ.VERSION advertises no capability. The TRA.* commands carry no such check. A refused call writes nothing: the mode check is the first thing the fence does, and the fence comes before every read.

Loaded is not served: on a cluster the commands exist, answer, and refuse every write.

The dives

Three dives read the module as the server meets it, each grounded in the real trafikey sources: the load, the table, and the one server mode it serves.

built page ready to read

Pattern & implementation

Where Redis Patterns Applied teaches a pattern pushed below the language line becoming a protocol, this module reads the place the job core goes one step further down: native code inside the server process.

the pattern (Redis Patterns Applied)

An agreement every runtime keeps — the keys, the fields, the atomic steps — stops being a library and becomes a protocol once it lives below the language line. Patterns become protocol teaches it.

the implementation (trafikey)

A Rust cdylib the server loads at startup with loadmodule; a gate that refuses a non-9 host, a missing host API or any argument; twenty-four commands from one table; an init that refuses the load on a table mismatch; standalone servers only.

Take the dives in order. The next module of the part, The command grammar, reads the order every job-core and bus write verb runs once it is registered.

References

Sources

Related in this course