{"id":37101915,"url":"https://github.com/struct0x/dispatcher","last_synced_at":"2026-01-14T12:21:53.225Z","repository":{"id":314601649,"uuid":"1054712578","full_name":"struct0x/dispatcher","owner":"struct0x","description":"A high-performance, type-safe dispatcher for Go.","archived":false,"fork":false,"pushed_at":"2025-09-11T15:43:40.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-13T15:01:44.421Z","etag":null,"topics":["dispatchers","go","golang","golang-library"],"latest_commit_sha":null,"homepage":"","language":"Go","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/struct0x.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-11T08:22:19.000Z","updated_at":"2025-09-11T15:50:05.000Z","dependencies_parsed_at":"2025-09-13T15:01:46.586Z","dependency_job_id":"c435d5e7-0a72-445b-92bc-e56684fe6b2e","html_url":"https://github.com/struct0x/dispatcher","commit_stats":null,"previous_names":["struct0x/dispatcher"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/struct0x/dispatcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/struct0x%2Fdispatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/struct0x%2Fdispatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/struct0x%2Fdispatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/struct0x%2Fdispatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/struct0x","download_url":"https://codeload.github.com/struct0x/dispatcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/struct0x%2Fdispatcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["dispatchers","go","golang","golang-library"],"created_at":"2026-01-14T12:21:52.523Z","updated_at":"2026-01-14T12:21:53.200Z","avatar_url":"https://github.com/struct0x.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dispatcher\n\nA high-performance, type-safe dispatcher for Go.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/struct0x/dispatcher.svg)](https://pkg.go.dev/github.com/struct0x/dispatcher)\n[![Go Report Card](https://goreportcard.com/badge/github.com/struct0x/dispatcher)](https://goreportcard.com/report/github.com/struct0x/dispatcher)\n\n## Overview\n\nDispatcher is a Go library that provides a fast and efficient way to route values to their appropriate handlers based on type.\nIt's designed with performance in mind,\noffering both thread-safe and immutable variants with different performance characteristics.\n\n## Features\n\n- **Type Safety**: Compile-time type safety with generic handlers\n- **Zero Allocations**: Dispatch operations produce zero allocations in steady state\n- **High Performance**: Optimized for concurrent access patterns\n- **Middleware Support**: Chainable middleware for cross-cutting concerns\n- **Two Registry Types**:\n  - `Registry`: Thread-safe, dynamic registration\n  - `SealedRegistry`: Immutable, zero mutex overhead\n\n## Installation\n\n```bash\ngo get github.com/struct0x/dispatcher\n```\n\n## Usage\n\n### Basic Example\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/struct0x/dispatcher\"\n)\n\ntype UserCreated struct {\n    ID   int\n    Name string\n}\n\ntype OrderPlaced struct {\n    OrderID string\n    Amount  float64\n}\n\nfunc main() {\n    // Create a new registry\n    reg := dispatcher.NewRegistry()\n\n    // Register handlers for different types\n    dispatcher.Register[UserCreated](reg, func(ctx context.Context, event UserCreated) error {\n        fmt.Printf(\"User created: %s (ID: %d)\\n\", event.Name, event.ID)\n        return nil\n    })\n\n    dispatcher.Register[OrderPlaced](reg, func(ctx context.Context, event OrderPlaced) error {\n        fmt.Printf(\"Order placed: %s for $%.2f\\n\", event.OrderID, event.Amount)\n        return nil\n    })\n\n    // Dispatch events\n    ctx := context.Background()\n\n    if err := dispatcher.Dispatch(reg, ctx, UserCreated{ID: 1, Name: \"Alice\"}); err != nil {\n        log.Fatal(err)\n    }\n\n    if err := dispatcher.Dispatch(reg, ctx, OrderPlaced{OrderID: \"ORD-001\", Amount: 99.99}); err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n### Using Middleware\n\n```go\n// Define middleware\nloggingMiddleware := func(next dispatcher.HandlerFunc[UserCreated]) dispatcher.HandlerFunc[UserCreated] {\n    return func(ctx context.Context, event UserCreated) error {\n        fmt.Printf(\"Processing user: %s\\n\", event.Name)\n        err := next(ctx, event)\n        fmt.Printf(\"Finished processing user: %s\\n\", event.Name)\n        return err\n    }\n}\n\n// Register with middleware\ndispatcher.Register[UserCreated](reg, handler, loggingMiddleware)\n```\n\n### Sealed Registry for Maximum Performance\n\n```go\n// After registering all handlers, seal the registry for better performance\nsealedReg := reg.Seal()\n\n// SealedRegistry has zero mutex overhead\nif err := dispatcher.Dispatch(sealedReg, ctx, UserCreated{ID: 2, Name: \"Bob\"}); err != nil {\n    log.Fatal(err)\n}\n```\n\n## Performance\n\nDispatcher is optimized for high-performance scenarios:\n\n- **Zero Allocations**: Dispatch operations after initialization produce zero allocations\n- **Concurrent Safe**: `Registry` can be used safely across goroutines\n- **Sealed Optimization**: `SealedRegistry` eliminates all mutex overhead\n- **Benchmark Results** (Apple M2 Max):\n  - `Registry`:\n    - 1 CPU: 21.46 ns/op\n    - 4 CPU: 64.80 ns/op\n    - 8 CPU: 122.0 ns/op\n  - `SealedRegistry`:\n    - 1 CPU: 14.59 ns/op\n    - 4 CPU: 28.95 ns/op\n    - 8 CPU: 45.53 ns/op\n\n*Note: Performance may vary based on your system and workload. Run benchmarks on your target system for accurate measurements.*\n\nRun benchmarks with:\n```bash\ngo test -bench=. -benchmem\n```\n\n## How It Works\n\n1. **Registration**: Handlers are registered for specific types using Go generics\n2. **Type Mapping**: Types are mapped to handlers using `reflecgt.Type` as keys\n3. **Dispatch**: Values are routed to appropriate handlers based on their runtime type\n4. **Middleware Chain**: Middleware is applied in the order provided during registration\n\n## API Reference\n\n### Core Types\n\n- `dispatcher.Registry`: Thread-safe registry for dynamic handler registration\n- `dispatcher.SealedRegistry`: Immutable registry with zero mutex overhead\n- `dispatcher.HandlerFunc[T]`: Type-safe handler function\n- `dispatcher.Middleware[T]`: Type-safe middleware function\n\n### Core Functions\n\n- `dispatcher.NewRegistry()`: Creates a new thread-safe registry\n- `dispatcher.Register[T](reg, handler, middleware...)`: Registers a handler for type T\n  - ⚠️ If called multiple times for the same type `T`, later registrations overwrite earlier ones.\n- `dispatcher.Dispatch(reg, ctx, value)`: Dispatches a value to its registered handler\n- `registry.Seal()`: Creates a sealed immutable copy of a registry\n\n## Use Cases\n\n- **Event-driven architectures**\n- **Message routing systems**\n- **Command handlers in CQRS**\n- **Plugin systems**\n- **Any scenario requiring type-based dispatch**\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstruct0x%2Fdispatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstruct0x%2Fdispatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstruct0x%2Fdispatcher/lists"}