# eventbus - Асинхронная шина событий для Go [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [English version below](#english-version) `eventbus` - это реализация асинхронной шины событий для языка программирования Go. Библиотека предоставляет механизм публикации и подписки на события с использованием trie-структуры для эффективного управления подписками. ## Особенности - **Trie-структура**: Использует префиксное дерево для хранения подписок, что обеспечивает эффективный поиск подписчиков - **Конфигурируемость**: Поддерживает настройку разделителя имен и символа wildcard через опции конструктора - **Асинхронная доставка**: События доставляются подписчикам асинхронно, что предотвращает блокировку отправителя - **Потокобезопасность**: Все операции синхронизированы с использованием `sync.RWMutex` - **Обобщения**: Реализована с использованием обобщений Go 1.18+, что позволяет использовать любые сравнимые типы ## Установка ```bash go get go.neonxp.ru/eventbus ``` ## Использование ```go package main import ( "fmt" "go.neonxp.ru/eventbus" ) type MyEvent struct { name string data string } func (e MyEvent) Event() string { return e.name } func main() { // Создаем шину событий с настройками по умолчанию bus := eventbus.New() // Создаем шину событий с кастомными настройками customBus := eventbus.New( eventbus.NameSeparator("/"), eventbus.Wildcard("#"), eventbus.Capacity(32), ) // Подписываемся на конкретное событие ch1 := bus.Subscribe(context.Background(), "user.login") // Подписываемся на группу событий с wildcard ch2 := bus.Subscribe(context.Background(), "user.*") // Подписываемся на группу событий с кастомным wildcard ch3 := customBus.Subscribe(context.Background(), "/user/#") // Запускаем горутины для обработки событий go func() { for ev := range ch1 { fmt.Printf("User login: %s\n", ev.Event()) } }() go func() { for ev := range ch2 { fmt.Printf("User event: %s\n", ev.Event()) } }() go func() { for ev := range ch3 { fmt.Printf("Custom event: %s\n", ev.Event()) } }() // Отправляем события bus.Publish(MyEvent{name: "user.login", data: "user123"}) bus.Publish(MyEvent{name: "user.logout", data: "user123"}) customBus.Publish(MyEvent{name: "/user/login", data: "user123"}) // Ждем немного для обработки событий time.Sleep(100 * time.Millisecond) } ``` ## API ### `func New(opts ...Opt) *bus` Создает новую шину событий с опциональными настройками. Поддерживает следующие опции: - `NameSeparator` - задает разделитель имен событий (по умолчанию ".") - `Wildcard` - задает символ wildcard для подписок (по умолчанию "\*") - `Capacity` - задает начальную емкость для узлов дерева подписчиков (по умолчанию 32) ### `func (b *bus) Subscribe(ctx context.Context, path string) Listener` Подписывается на событие по указанному пути. Возвращает канал-подписчик для получения событий. ### `func (b *bus) Close()` Закрывает шину событий и все каналы подписчиков. ### `func (b *bus) Publish(ev Event)` Отправляет событие всем подписчикам, которые подписаны на соответствующий путь события. ## Лицензия Этот проект лицензирован в соответствии с GNU General Public License версии 3 (GPLv3). Подробности смотрите в файле [LICENSE](LICENSE). ``` GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2026 Alexander NeonXP Kiryukhin Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. ``` ## Ссылки - **Репозиторий**: [https://gitrepo.ru/NeonXP/eventbus.git](https://gitrepo.ru/NeonXP/eventbus.git) - **Автор**: Alexander NeonXP Kiryukhin # English Version `eventbus` is an implementation of an asynchronous event bus for the Go programming language. The library provides a publish-subscribe mechanism for events using a trie structure for efficient subscription management. ## Features - **Trie structure**: Uses a prefix tree to store subscriptions, providing efficient subscriber lookup - **Configurable**: Supports configuration of name separator and wildcard character through constructor options - **Asynchronous delivery**: Events are delivered to subscribers asynchronously, preventing sender blocking - **Thread-safe**: All operations are synchronized using `sync.RWMutex` - **Generics**: Implemented using Go 1.18+ generics, allowing any comparable types ## Installation ```bash go get go.neonxp.ru/eventbus ``` ## Usage ```go package main import ( "fmt" "go.neonxp.ru/eventbus" ) type MyEvent struct { name string data string } func (e MyEvent) Event() string { return e.name } func main() { // Create event bus with default settings bus := eventbus.New() // Create event bus with custom settings customBus := eventbus.New( eventbus.NameSeparator("/"), eventbus.Wildcard("#"), eventbus.Capacity(32), ) // Subscribe to specific event ch1 := bus.Subscribe(context.Background(), "user.login") // Subscribe to event group with wildcard ch2 := bus.Subscribe(context.Background(), "user.*") // Subscribe to event group with custom wildcard ch3 := customBus.Subscribe(context.Background(), "/user/#") // Start goroutines for event handling go func() { for ev := range ch1 { fmt.Printf("User login: %s\n", ev.Event()) } }() go func() { for ev := range ch2 { fmt.Printf("User event: %s\n", ev.Event()) } }() go func() { for ev := range ch3 { fmt.Printf("Custom event: %s\n", ev.Event()) } }() // Publish events bus.Publish(MyEvent{name: "user.login", data: "user123"}) bus.Publish(MyEvent{name: "user.logout", data: "user123"}) customBus.Publish(MyEvent{name: "/user/login", data: "user123"}) // Wait a bit for event processing time.Sleep(100 * time.Millisecond) } ``` ## API ### `func New(opts ...Opt) *bus` Creates a new event bus with optional settings. Supports the following options: - `NameSeparator` - sets the event name separator (default ".") - `Wildcard` - sets the wildcard character for subscriptions (default "\*") - `Capacity` - sets the initial capacity for listeners trie (default 32) ### `func (b *bus) Subscribe(ctx context.Context, path string) Listener` Subscribes to an event at the specified path. Returns a listener channel for receiving events. ### `func (b *bus) Close()` Closes the event bus and all listener channels. ### `func (b *bus) Publish(ev Event)` Publishs an event to all subscribers who are subscribed to the corresponding event path. ## License This project is licensed under the GNU General Public License version 3 (GPLv3). See the [LICENSE](LICENSE) file for details. ``` GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2026 Alexander NeonXP Kiryukhin Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. ``` ## Links - **Repository**: [https://gitrepo.ru/NeonXP/eventbus.git](https://gitrepo.ru/NeonXP/eventbus.git) - **Author**: Alexander NeonXP Kiryukhin