Skip to content

ooyeku/vigil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

102 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vigil

A process supervision and inter-process communication library for Zig, designed for building reliable distributed systems and concurrent applications. Inspired by Erlang/OTP.

Installation

zig fetch --save "git+https://github.com/ooyeku/vigil"

Add as a dependency in your build.zig:

const vigil = b.dependency("vigil", .{
    .target = target,
    .optimize = optimize,
});
exe.root_module.addImport("vigil", vigil.module("vigil"));

Quick Start

Simple Worker Application

const std = @import("std");
const vigil = @import("vigil");

fn worker() void {
    std.debug.print("Worker running\n", .{});
    vigil.compat.sleep(100 * std.time.ns_per_ms);
}

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var app = try vigil.app(allocator);
    _ = try app.worker("task1", worker);
    _ = try app.workerPool("pool", worker, 4);
    try app.start();
    defer app.shutdown();
}

Runtime-Owned Services

var rt = try vigil.runtime(allocator, .{});
defer rt.deinit();

var inbox = try rt.inbox(.{ .capacity = 128 });
defer inbox.close();

try inbox.send("hello from the runtime");

Channel-Like Message Passing

var inbox = try vigil.inbox(allocator);
defer inbox.close();

try inbox.send("hello");

if (try inbox.recvTimeout(1000)) |msg| {
    defer msg.deinit();
    std.debug.print("Received: {s}\n", .{msg.payload.?});
}

Circuit Breaker for Resilience

var breaker = try vigil.CircuitBreaker.init(allocator, "api", .{
    .failure_threshold = 5,
    .reset_timeout_ms = 30000,
});
defer breaker.deinit();

if (breaker.getState() == .open) {
    // Service unavailable, fail fast
}

Rate Limiting

var limiter = vigil.RateLimiter.init(100); // 100 ops/sec

if (limiter.allow()) {
    // Process request
} else {
    // Rate limited
}

Process Groups

var group = try vigil.ProcessGroup.init(allocator, "workers");
defer group.deinit();

try group.add("worker1", inbox1);
try group.add("worker2", inbox2);

try group.broadcast("message");  // Send to all
try group.roundRobin("message"); // Load balance

Features

Core

  • Process Supervision - Automatic restart strategies (one_for_one, one_for_all, rest_for_one)
  • Message Passing - Thread-safe inboxes with priority queues
  • Owned Runtime - Registry, telemetry, shutdown, inboxes, and supervisors under one owner
  • Fluent Builders - Intuitive API with sensible defaults
  • Configuration Presets - Production, development, HA, and testing modes

Resilience

  • Circuit Breaker - Protect services from cascading failures
  • Rate Limiting - Token bucket algorithm for flow control
  • Backpressure - Strategies for handling overload (drop_oldest, drop_newest, block, error)

Messaging

  • Pub/Sub - Topic-based messaging with wildcard support
  • Process Groups - Manage related processes with broadcast/round-robin routing
  • Request/Reply - Synchronous messaging with correlation IDs

Observability

  • Telemetry - Event hooks for monitoring (process, message, supervisor, circuit events)
  • Testing Utilities - Mock inboxes, mock supervisors, time control

Advanced

  • Graceful Shutdown - Coordinated cleanup with shutdown hooks
  • State Checkpointing - Persist and recover process state
  • Distributed Registry - Cross-process name resolution

Configuration Presets

// Production: conservative restarts, monitoring enabled
var app = try vigil.appWithPreset(allocator, .production);

// Development: verbose logging, quick restarts
var app = try vigil.appWithPreset(allocator, .development);

// High availability: intensive health checks
var app = try vigil.appWithPreset(allocator, .high_availability);

// Testing: minimal restarts, fast health checks
var app = try vigil.appWithPreset(allocator, .testing);

Examples

The root package is library-only: use zig build test at the repository root, and run examples from their own directories.

See examples/vigil_showcase for a self-contained resilient order pipeline that demonstrates:

  • Runtime-owned registry, telemetry, shutdown hooks, and inboxes
  • Process groups for worker routing and operations broadcast
  • Pub/Sub event fanout for audit and alert streams
  • Inbox backpressure, rate limiting, and circuit breaker behavior
cd examples/vigil_showcase
zig build run

See examples/vigilant_server for a complete TCP server with:

  • Circuit breaker protection
  • Rate limiting
  • Telemetry integration
  • Graceful shutdown
cd examples/vigilant_server
zig build run

Documentation

See docs/api.md for comprehensive API documentation.

Migrating to 2.0

Vigil 2.0 removes the old 0.2 compatibility helpers from the root vigil module. Code that needs historical low-level types should import vigil/legacy explicitly. New code should use vigil.Runtime, vigil.app, vigil.supervisor, vigil.inbox, and vigil.GenServer.

Running Tests

zig build test

Requirements

  • Zig 0.16.x
  • Core runtime support for Zig's native thread targets
  • Distributed TCP registry and networking examples currently use the bundled POSIX socket compatibility layer

License

MIT - see the LICENSE file for details.

About

A process supervision and management library for Zig, inspired by Erlang/OTP's supervisor model.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages