nylon-ring-host 0.1.1

Dynamic plugin host for the nylon-ring ABI
Documentation

πŸ”— Nylon Ring

Ultra-Fast ABI-Stable Host–Plugin Interface for Rust

CI Crates.io Documentation License

Build fast native plugins with an explicit C-compatible ABI.

Features β€’ Quick Start β€’ Performance β€’ System Overview


🌟 Features

  • Stable ABI v1 β€” C-compatible types, fixed status values, version and structure-size validation.
  • Flexible calls β€” fire-and-forget, async unary, synchronous fast path, and bounded streaming with backpressure.
  • Safe lifecycle β€” in-flight call guards, graceful unload/reload, timeouts, and automatic request cleanup.
  • Cross-language validation β€” Rust examples plus a buildable C plugin.

The workspace provides:

  • nylon-ring β€” ABI types, vtables, and the define_plugin! macro.
  • nylon-ring-host β€” dynamic loading, routing, streaming, lifecycle controls, and metrics.

MSRV: Rust 1.88.


πŸš€ Quick start

Install

# Plugin
[dependencies]
nylon-ring = "0.1.0"

# Host
[dependencies]
nylon-ring-host = "0.1.0"

Plugin crates must also build as a dynamic library:

[lib]
crate-type = ["cdylib"]

Host

use nylon_ring_host::{NrStatus, NylonRingHost};

# async fn run() -> Result<(), Box<dyn std::error::Error>> {
let mut host = NylonRingHost::new();
host.load("example", "target/release/libexample_plugin.so")?;

let plugin = host.plugin("example").expect("plugin was loaded");
let (status, response) = plugin.call_response("echo", b"hello").await?;

assert_eq!(status, NrStatus::Ok);
assert_eq!(response, b"hello");
# Ok(())
# }

Other call patterns:

plugin.call("notify", b"payload").await?;
plugin.call_response_fast("echo", b"hello").await?;
plugin.call_response_timeout("echo", b"hello", timeout).await?;
let (sid, stream) = plugin.call_stream("events", b"start").await?;

See the complete Rust plugin example and Rust host example.

Run the workspace demo:

cargo run --release --package ex-nyring-host

πŸ“Š Performance

Release-build snapshot on an Apple M1 Pro.

Single-stream (Criterion)

Host operation Time Throughput
Fire-and-forget 40.798 ns 24.511M calls/s
Synchronous fast path 58.917 ns 16.973M calls/s
Standard unary 116.99 ns 8.548M calls/s
Unary + 128-byte payload 126.03 ns 7.934M calls/s
Unary + 1 KiB payload 184.96 ns 5.407M calls/s
Unary + 4 KiB payload 259.62 ns 3.852M calls/s

Multi-core (10 workers)

Host operation Throughput
Fire-and-forget 125.12M calls/s
Synchronous fast path 88.67M calls/s
Standard unary 19.72M calls/s

ABI primitives (Criterion)

ABI operation Time
NrStr::new 0.735 ns
NrBytes::as_slice 0.311 ns
NrVec::from_vec 15.318 ns
NrVec::into_vec 24.544 ns

These are reference measurements, not cross-platform guarantees. Reproduce them with:

cargo bench --package nylon-ring
cargo bench --package nylon-ring-host

πŸ— System overview

+------------------------------------------------------+
| Host (nylon-ring-host)                               |
|  NylonRingHost                                       |
|   β”œβ”€ LoadedPlugin + in-flight call gate              |
|   └─ HostContext                                     |
|       β”œβ”€ thread-local synchronous slot               |
|       β”œβ”€ sharded async request router                |
|       └─ bounded stream queues                       |
+-------------------------+----------------------------+
                          | C ABI v1
                          | NrPluginVTable / NrHostVTable
+-------------------------+----------------------------+
| Plugin                                               |
|  define_plugin! β†’ named handlers β†’ send_result       |
+------------------------------------------------------+

The host validates and initializes a library, assigns each call a session ID, then routes plugin callbacks to the matching unary request or stream. Call guards keep the library loaded until active work finishes; graceful unload/reload stops new calls and waits for existing calls to drain.


πŸ›‘ Safety

  • Host and plugin must use the same target and ABI version.
  • NrStr and NrBytes are borrowed; copy them before retaining their data.
  • Owned NrVec<T> values carry the producer's drop callback, avoiding cross-allocator frees.
  • Plugins must stop worker threads and callbacks during shutdown.
  • Only load trusted native libraries; this is not a security sandbox.

See the full ABI evolution and compatibility policy.


Development

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-targets --all-features

Publishing is handled by GitHub Actions in dependency order using the organization-level RUST_TOKEN secret.

License

MIT