{"id":30459544,"url":"https://github.com/youneedwork/zctor","last_synced_at":"2025-09-03T18:44:53.176Z","repository":{"id":297455151,"uuid":"981754689","full_name":"YouNeedWork/zctor","owner":"YouNeedWork","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-20T06:41:16.000Z","size":231,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-22T22:39:14.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YouNeedWork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-11T20:10:45.000Z","updated_at":"2025-06-20T06:41:18.000Z","dependencies_parsed_at":"2025-06-10T10:15:12.119Z","dependency_job_id":null,"html_url":"https://github.com/YouNeedWork/zctor","commit_stats":null,"previous_names":["youneedwork/zctor"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/YouNeedWork/zctor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YouNeedWork%2Fzctor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YouNeedWork%2Fzctor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YouNeedWork%2Fzctor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YouNeedWork%2Fzctor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YouNeedWork","download_url":"https://codeload.github.com/YouNeedWork/zctor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YouNeedWork%2Fzctor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271762694,"owners_count":24816816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-23T18:30:35.458Z","updated_at":"2025-08-23T18:30:37.226Z","avatar_url":"https://github.com/YouNeedWork.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zctor\n\nA high-performance, multi-threaded actor framework for Zig, providing scalable concurrent message-passing with intelligent load balancing and cross-thread communication.\n\n📖 **[View Complete Documentation](https://youneedwork.github.io/zctor/)** - Comprehensive documentation website with examples, API reference, and guides.\n\n## Overview\n\nzctor is a production-ready Zig implementation of the Actor Model, designed for building high-performance concurrent applications. The framework features true multi-threading with intelligent actor routing, load balancing, and comprehensive messaging patterns including broadcast, publisher-subscriber, and request-response communication.\n\n### Key Features\n\n- **🚀 True Multi-Threading**: Distribute actors across multiple threads with automatic CPU core utilization\n- **⚖️ Intelligent Load Balancing**: Round-robin distribution across multiple actor instances\n- **📡 Broadcast Messaging**: One-to-many communication patterns for pub-sub systems\n- **🔄 Cross-Thread Communication**: Seamless messaging between actors on different threads\n- **🎯 Request-Response Pattern**: Synchronous call operations across thread boundaries\n- **🧠 Smart Actor Registry**: Automatic thread routing based on actor type registration\n- **🛡️ Type Safety**: Compile-time guarantees with Zig's type system\n- **📊 Built-in State Management**: Thread-safe state management within actors\n- **⚡ High Performance**: Leverages libxev for efficient event loop management\n- **🔧 Minimal Dependencies**: Only depends on libxev for event handling\n\n## Documentation\n\n📚 **[Complete Documentation Website](https://youneedwork.github.io/zctor/)** - Visit our comprehensive documentation site for:\n\n- **[Quick Start Guide](https://youneedwork.github.io/zctor/#quick-start)** - Get up and running in minutes\n- **[API Reference](https://youneedwork.github.io/zctor/#api-reference)** - Complete API documentation\n- **[Examples](https://youneedwork.github.io/zctor/#examples)** - Real-world usage examples\n- **[Best Practices](https://youneedwork.github.io/zctor/#best-practices)** - Optimization tips and patterns\n- **[Advanced Topics](https://youneedwork.github.io/zctor/#advanced-topics)** - Complex patterns and customization\n\n## Requirements\n\n- **Zig**: Version 0.14.0 or higher\n- **libxev**: Automatically managed as a dependency\n\n## Installation\n\n### From Source\n\n```bash\ngit clone https://github.com/YouNeedWork/zctor.git\ncd zctor\nzig build\n```\n\n### Using as a Library\n\nIn your project's `build.zig`, add zctor as a dependency:\n\n```zig\n// In build.zig\nconst zctor_dep = b.dependency(\"zctor\", .{ .target = target, .optimize = optimize });\nexe.root_module.addImport(\"zctor\", zctor_dep.module(\"zctor\"));\n```\n\nThen in your Zig code:\n\n```zig\nconst zctor = @import(\"zctor\");\nconst ActorEngine = zctor.ActorEngine;\nconst Actor = zctor.Actor;\n```\n\n## Quick Start\n\n### Basic Multi-Threaded Actor Example\n\n```zig\nconst std = @import(\"std\");\nconst zctor = @import(\"zctor\");\nconst Actor = zctor.Actor;\nconst ActorEngine = zctor.ActorEngine;\nconst ActorThread = zctor.ActorThread;\n\n// Define your message types\nconst CalculatorMessage = union(enum) {\n    Add: struct { a: i32, b: i32 },\n    Multiply: struct { a: i32, b: i32 },\n\n    const Self = @This();\n\n    // Message handler - returns results for call operations\n    pub fn handle(actor: *Actor(Self), msg: Self) ?*anyopaque {\n        const thread_id = actor.getContext().thread_id;\n        switch (msg) {\n            .Add =\u003e |op| {\n                std.debug.print(\"[Thread {}] Computing {} + {}\\n\", .{ thread_id, op.a, op.b });\n                const result_ptr = actor.getAllocator().create(i32) catch return null;\n                result_ptr.* = op.a + op.b;\n                return @ptrCast(result_ptr);\n            },\n            .Multiply =\u003e |op| {\n                std.debug.print(\"[Thread {}] Computing {} * {}\\n\", .{ thread_id, op.a, op.b });\n                const result_ptr = actor.getAllocator().create(i32) catch return null;\n                result_ptr.* = op.a * op.b;\n                return @ptrCast(result_ptr);\n            },\n        }\n    }\n};\n\npub fn main() !void {\n    var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n    defer _ = gpa.deinit();\n    const allocator = gpa.allocator();\n\n    // Create the multi-threaded actor engine\n    var engine = try ActorEngine.init(allocator);\n    defer engine.deinit();\n\n    // Create multiple threads with calculator actors for load balancing\n    const thread1 = try ActorThread.init(allocator);\n    try thread1.registerActor(try Actor(CalculatorMessage).init(allocator, CalculatorMessage.handle));\n    try engine.spawn(thread1);\n\n    const thread2 = try ActorThread.init(allocator);\n    try thread2.registerActor(try Actor(CalculatorMessage).init(allocator, CalculatorMessage.handle));\n    try engine.spawn(thread2);\n\n    // Send messages (automatically load-balanced across threads)\n    var add_msg = CalculatorMessage{ .Add = .{ .a = 10, .b = 5 } };\n    try engine.send(CalculatorMessage, \u0026add_msg);\n\n    var mul_msg = CalculatorMessage{ .Multiply = .{ .a = 7, .b = 3 } };\n    try engine.send(CalculatorMessage, \u0026mul_msg);\n\n    // Request-response pattern (call)\n    var call_msg = CalculatorMessage{ .Add = .{ .a = 20, .b = 15 } };\n    const response = try engine.call(CalculatorMessage, \u0026call_msg);\n    if (response) |ptr| {\n        const result_ptr = @as(*i32, @ptrCast(@alignCast(ptr)));\n        std.debug.print(\"Call result: {}\\n\", .{result_ptr.*});\n        allocator.destroy(result_ptr);\n    }\n\n    // Start the engine\n    engine.start();\n}\n```\n\n### Available Examples\n\nRun these examples to see different messaging patterns:\n\n```bash\n# Basic request-response pattern\nzig build run-call\n\n# Multi-threaded actors with load balancing\nzig build run-multi\n\n# Broadcast messaging (one-to-many)\nzig build run-broadcast\n\n# Cross-thread communication patterns\nzig build run-thread-comm\n\n# Publisher-subscriber pattern\nzig build run-pubsub\n\n# Load balancing demonstration\nzig build run-load-balance\n```\n\n## Building\n\n### Build the Library and Executable\n\n```bash\nzig build\n```\n\n### Run the Example\n\n```bash\nzig build run\n```\n\n### Build in Release Mode\n\n```bash\nzig build -Doptimize=ReleaseFast\n```\n\n## Testing\n\nRun the test suite:\n\n```bash\nzig build test\n```\n\nThis will run all unit tests for the library components.\n\n## Architecture\n\n### Core Components\n\n- **ActorEngine**: Manages the multi-threaded actor system with intelligent routing and load balancing\n- **ActorThread**: Handles actors within a single thread context with event loop management\n- **Actor(T)**: Generic actor type that processes messages of type T with thread-safe state management\n- **Context**: Provides runtime context, thread information, and services to actors\n- **Actor Registry**: Maps actor types to available threads for smart message routing\n\n### Multi-Threading Features\n\n#### **🎯 Smart Message Routing**\n\n- **Actor Registry**: Automatically tracks which threads have which actor types\n- **Load Balancing**: Round-robin distribution across multiple instances of the same actor type\n- **Cross-Thread Calls**: Request-response pattern works seamlessly across thread boundaries\n\n#### **📡 Messaging Patterns**\n\n- **`send()`**: Fire-and-forget messaging with automatic thread routing\n- **`call()`**: Synchronous request-response across threads\n- **`broadcast()`**: One-to-many messaging to all instances of an actor type\n\n#### **⚖️ Load Balancing**\n\n```zig\n// Multiple worker instances automatically load-balanced\nconst worker1 = try ActorThread.init(allocator);\ntry worker1.registerActor(try Actor(WorkerMessage).init(allocator, WorkerMessage.handle));\ntry engine.spawn(worker1);\n\nconst worker2 = try ActorThread.init(allocator);\ntry worker2.registerActor(try Actor(WorkerMessage).init(allocator, WorkerMessage.handle));\ntry engine.spawn(worker2);\n\n// Messages automatically distributed round-robin between worker1 and worker2\ntry engine.send(WorkerMessage, \u0026task1); // → worker1\ntry engine.send(WorkerMessage, \u0026task2); // → worker2\ntry engine.send(WorkerMessage, \u0026task3); // → worker1 (round-robin)\n```\n\n### Message Flow\n\n1. **Message Submission**: Messages sent via `ActorEngine.send()`, `call()`, or `broadcast()`\n2. **Thread Routing**: Actor registry determines target thread(s) based on actor type\n3. **Load Balancing**: Round-robin selection when multiple instances available\n4. **Queue Processing**: Messages queued in thread-specific mailboxes (FIFO)\n5. **Event Loop**: Each thread's event loop processes messages asynchronously\n6. **Handler Execution**: Messages handled by actor's message handler function\n7. **Response Handling**: For `call()` operations, responses sent back via one-shot channels\n\n### State Management\n\nActors can maintain internal state using the built-in state management system:\n\n```zig\nconst State = struct {\n    counter: u32 = 0,\n    data: []const u8 = \"\",\n    allocator: std.mem.Allocator,\n\n    pub fn init(allocator: std.mem.Allocator) !*State {\n        const s = try allocator.create(State);\n        s.* = State{\n            .counter = 0,\n            .data = \"\",\n            .allocator = allocator,\n        };\n        return s;\n    }\n};\n\npub fn handle(actor: *Actor(MyMessage), msg: MyMessage) ?void {\n    // Get or create state\n    var state = actor.getState(State) orelse blk: {\n        const new_state = State.init(actor.getAllocator()) catch |err| {\n            std.debug.print(\"Failed to initialize state: {}\\n\", .{err});\n            return null;\n        };\n        actor.setState(new_state);\n        break :blk actor.getState(State).?;\n    };\n\n    // Use state...\n    state.counter += 1;\n\n    switch (msg) {\n        .Hello =\u003e |name| {\n            std.debug.print(\"Hello {s}, counter: {}\\n\", .{ name, state.counter });\n        },\n        // ... other message handlers\n    }\n}\n```\n\n## API Reference\n\n### ActorEngine\n\n#### Core Methods\n\n- `init(allocator: Allocator) !*ActorEngine` - Create a new multi-threaded actor engine\n- `spawn(actor_thread: *ActorThread) !void` - Spawn a new actor thread\n- `start() void` - Start the engine and begin processing messages\n- `deinit() void` - Clean up the engine and all threads\n\n#### Messaging Methods\n\n- `send(comptime T: type, msg: *T) !void` - Send fire-and-forget message with load balancing\n- `call(comptime T: type, msg: *T) !?*anyopaque` - Synchronous request-response across threads\n- `broadcast(comptime T: type, msg: *T) !void` - Send message to all instances of actor type\n\n#### Utility Methods\n\n- `getThreadCount() usize` - Get number of active threads\n- `getActorRegistry() *const StringArrayHashMap(ArrayList(usize))` - Get actor registry for debugging\n\n### ActorThread\n\n- `init(allocator: Allocator) !*ActorThread` - Create a new actor thread\n- `registerActor(actor: *Actor(T)) !void` - Register an actor on this thread\n- `send(comptime T: type, msg: *T) !void` - Send message to actor on this thread\n- `call(comptime T: type, msg: *T) !?*anyopaque` - Call actor on this thread\n- `deinit(allocator: Allocator) void` - Clean up the thread\n\n### Actor(T)\n\n#### State Management\n\n- `getState(comptime S: type) ?*S` - Get typed state (thread-safe)\n- `setState(state: *anyopaque) void` - Set actor state\n- `resetState() void` - Clear actor state\n\n#### Context \u0026 Resources\n\n- `getAllocator() Allocator` - Get the actor's allocator\n- `getContext() *Context` - Get runtime context (includes thread_id)\n\n#### Message Handling\n\n- `send(msg_ptr: *anyopaque) !void` - Send message to this actor instance\n- `call(msg_ptr: *anyopaque) !*anyopaque` - Call this actor instance\n\n## Examples\n\nzctor includes comprehensive examples demonstrating different messaging patterns and multi-threading capabilities:\n\n### 🎯 **Basic Examples**\n\n#### **Request-Response Pattern**\n\n```bash\nzig build run-call\n```\n\nDemonstrates synchronous request-response communication with result handling.\n\n#### **Multi-Threaded Actors**\n\n```bash\nzig build run-multi\n```\n\nShows actors running on different threads with cross-thread communication.\n\n### 📡 **Advanced Messaging Patterns**\n\n#### **Broadcast Messaging**\n\n```bash\nzig build run-broadcast\n```\n\nOne-to-many communication where messages are sent to all subscribers simultaneously.\n\n- News broadcasts to multiple subscriber threads\n- Event notifications across the system\n- Real-time data distribution\n\n#### **Publisher-Subscriber Pattern**\n\n```bash\nzig build run-pubsub\n```\n\nReal-world pub-sub system with multiple topic types:\n\n- Stock market data feeds\n- News distribution\n- Chat messaging systems\n\n#### **Cross-Thread Communication**\n\n```bash\nzig build run-thread-comm\n```\n\nDemonstrates various thread communication patterns:\n\n- Same-thread messaging (intra-thread)\n- Cross-thread messaging (inter-thread)\n- Load balancing across threads\n- Monitoring and metrics collection\n\n#### **Load Balancing**\n\n```bash\nzig build run-load-balance\n```\n\nShows intelligent load balancing across multiple worker instances:\n\n- Round-robin task distribution\n- Multiple actor instances on different threads\n- Performance statistics collection\n- Parallel task processing\n\n### 📊 **Example Output**\n\nEach example shows thread IDs to demonstrate true multi-threading:\n\n```\nRegistered actor type 'WorkerMessage' -\u003e Threads: [0, 1, 2, 3, 4]\nLoad balancing: sending to thread 0 (option 1 of 5)\n[Thread 0] 🔄 Processing compute task 1 (complexity: 3)\nLoad balancing: sending to thread 1 (option 2 of 5)\n[Thread 1] 🔄 Processing compute task 2 (complexity: 1)\nLoad balancing: sending to thread 2 (option 3 of 5)\n[Thread 2] 🔄 Processing compute task 3 (complexity: 5)\n```\n\n### 🏗️ **Real-World Use Cases**\n\nThese examples demonstrate patterns suitable for:\n\n- **Web servers** with request distribution\n- **Data processing pipelines** with parallel workers\n- **Real-time systems** with event broadcasting\n- **Microservices** with inter-service communication\n- **Game servers** with player message handling\n- **IoT systems** with sensor data aggregation\n\n## Contributing\n\nContributions are welcome! Please see our [comprehensive contributing guide](https://youneedwork.github.io/zctor/#contributing) for detailed information.\n\n**Quick steps:**\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests for new functionality\n5. Ensure all tests pass\n6. Submit a pull request\n\nThe documentation website is automatically generated and deployed via GitHub Actions whenever changes are pushed to the main branch.\n\n## License\n\nSee the [LICENSE](LICENSE) file for license information.\n\n## Acknowledgments\n\n- Built with [libxev](https://github.com/mitchellh/libxev) for efficient event handling\n- Inspired by the Actor Model as implemented in Erlang, Elixir, and Akka\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyouneedwork%2Fzctor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyouneedwork%2Fzctor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyouneedwork%2Fzctor/lists"}