Quickstart
The current distribution is a source checkout. Published binaries and production configuration are not ready yet.
Prerequisites
Section titled “Prerequisites”Docker (recommended), or a current Rust toolchain and Git to build from source.
Run the broker
Section titled “Run the broker”The quickest path is the published main image from GitHub Container Registry:
docker pull ghcr.io/axmouth/fibril-server:maindocker run --rm \ -p 9876:9876 \ -p 8081:8081 \ -v fibril-server-data:/app/server_data \ ghcr.io/axmouth/fibril-server:mainThe main tag is a moving pre-release image. CI also publishes immutable
sha-<commit> tags for exact builds.
As a backup, run from a source checkout instead:
git clone https://github.com/Axmouth/fibril.gitcd fibrilcargo run --release --bin fibril-serverEither way, the development server currently:
- listens for broker TCP traffic on
9876 - serves the early admin interface on
8081 - stores durable state under
server_data/(thefibril-server-datavolume with Docker) - uses development authentication defaults in the server binary
Do not expose this development server directly to the public internet. Before
exposing a broker beyond localhost, enable TLS and create a
real user (the built-in fibril/fibril credentials are accepted from loopback
only). See the cluster setup guide for a secured
multi-node bring-up.
Client shape
Section titled “Client shape”Fibril has Rust, TypeScript, Python, Go, and C# clients over the same broker surface: publishers, delayed publish, and manual-ack subscriptions. The examples are for the current pre-alpha source tree, not a stable package contract.
The Rust client lives in crates/client.
let client = ClientOptions::new() .auth("fibril", "fibril") .connect("127.0.0.1:9876") .await?;
let publisher = client.publisher("email.send")?;publisher.publish("hello").await?;publisher.publish_delayed("hello later", std::time::Duration::from_secs(30)).await?;
let mut sub = client .subscribe("email.send")? .prefetch(32) .sub() .await?;
while let Some(msg) = sub.recv().await { process(msg.text()?).await?; msg.complete().await?;}The TypeScript client lives in clients/typescript. Delays are in milliseconds.
import { ClientOptions, NewMessage } from "@fibril/client";
const client = await new ClientOptions() .withAuth("fibril", "fibril") .connect("127.0.0.1:9876");
const publisher = client.publisher("email.send");await publisher.publish(NewMessage.json({ body: "hello" }));await publisher.publishDelayed(NewMessage.json({ body: "hello later" }), 30_000);
const sub = await client .subscribe("email.send") .prefetch(32) .sub();
for await (const msg of sub) { const body = msg.deserialize<{ body: string }>(); await process(body); await msg.complete();}The Python client lives in clients/python. Delays are seconds (a float or a
timedelta). A synchronous fibril.blocking.BlockingClient mirrors the same API
without async.
from fibril import ClientOptions, NewMessage
client = await ClientOptions().with_auth("fibril", "fibril").connect("127.0.0.1:9876")
publisher = client.publisher("email.send")await publisher.publish(NewMessage.json({"body": "hello"}))await publisher.publish_delayed(NewMessage.json({"body": "hello later"}), 30)
sub = await client.subscribe("email.send").prefetch(32).sub()async for msg in sub: await process(msg.deserialize()) await msg.complete()from fibril import ClientOptions, NewMessagefrom fibril.blocking import BlockingClient
client = BlockingClient.connect( "127.0.0.1:9876", ClientOptions().with_auth("fibril", "fibril"))
publisher = client.publisher("email.send")publisher.publish(NewMessage.json({"body": "hello"}))publisher.publish_delayed(NewMessage.json({"body": "hello later"}), 30)
sub = client.subscribe("email.send").prefetch(32).sub()for msg in sub: process(msg.deserialize()) msg.complete()The Go client lives in clients/go. Every network method takes a
context.Context first (use context.Background() with no deadline). Delays are
a time.Duration. Deliveries arrive on a channel and settle with Complete/Fail/Retry.
import ( "context"
fibril "github.com/Axmouth/fibril/clients/go")
ctx := context.Background()client, err := fibril.Dial(ctx, "127.0.0.1:9876", fibril.ClientOptions{ Credentials: &fibril.Credentials{Username: "fibril", Password: "fibril"},})
publisher := client.Publisher("email.send")publisher.Publish(ctx, fibril.Text("hello"))publisher.PublishDelayed(ctx, fibril.Text("hello later"), 30*time.Second)
// SubscribeTopic fans in every partition (default group, prefetch 32, manual ack).sub, err := client.SubscribeTopic(ctx, "email.send", fibril.TopicSubscribeOptions{Prefetch: 32, AutoAck: false})for msg := range sub.Deliveries { process(msg.Text()) msg.Complete()}The C# client lives in clients/csharp. Every network method takes an optional
CancellationToken. Delays are a TimeSpan. Deliveries arrive as an
IAsyncEnumerable and settle with Complete/Fail/Retry.
using Fibril;
await using var client = await Client.ConnectAsync("127.0.0.1:9876", new ClientOptions{ Credentials = new Credentials("fibril", "fibril"),});
var publisher = client.Publisher("email.send");await publisher.PublishAsync(Message.Text("hello"));await publisher.PublishDelayedAsync(Message.Text("hello later"), TimeSpan.FromSeconds(30));
// SubscribeTopicAsync fans in every partition (prefetch 32, manual ack).await using var sub = await client.SubscribeTopicAsync("email.send", prefetch: 32);await foreach (var msg in sub.Deliveries()){ Process(msg.Text()); msg.Complete();}The API is evolving. Treat examples as a guide to the current source tree rather than a stable package contract.
For more publishing, subscription, delayed publish, and message encoding examples, see client usage.
For startup config, runtime settings, and idle queue cleanup options, see configuration.
Try a cluster
Section titled “Try a cluster”To stand up a real multi-broker cluster locally and watch ownership, replication, and failover from the admin dashboard, see try a cluster with Docker in under a minute. Clustering is experimental.