No description
Find a file
2026-01-24 17:56:58 +03:00
.golangci.yml v1.0.0 2026-01-24 17:46:54 +03:00
bus.go v1.0.1 2026-01-24 17:56:58 +03:00
bus_test.go v1.0.0 2026-01-24 17:46:54 +03:00
go.mod v1.0.0 2026-01-24 17:46:54 +03:00
LICENSE v1.0.0 2026-01-24 17:46:54 +03:00
opts.go v1.0.1 2026-01-24 17:56:58 +03:00
README.md v1.0.1 2026-01-24 17:56:58 +03:00
trie.go v1.0.0 2026-01-24 17:46:54 +03:00
trie_test.go v1.0.0 2026-01-24 17:46:54 +03:00

eventbus - Асинхронная шина событий для Go

License: GPL
v3

English version below

eventbus - это реализация асинхронной шины событий для языка программирования Go. Библиотека предоставляет механизм публикации и подписки на события с использованием trie-структуры для эффективного управления подписками.

Особенности

  • Trie-структура: Использует префиксное дерево для хранения подписок, что обеспечивает эффективный поиск подписчиков
  • Конфигурируемость: Поддерживает настройку разделителя имен и символа wildcard через опции конструктора
  • Асинхронная доставка: События доставляются подписчикам асинхронно, что предотвращает блокировку отправителя
  • Потокобезопасность: Все операции синхронизированы с использованием sync.RWMutex
  • Обобщения: Реализована с использованием обобщений Go 1.18+, что позволяет использовать любые сравнимые типы

Установка

go get go.neonxp.ru/eventbus

Использование

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("user.login")
    defer bus.Unsubscribe(ch1)

    // Подписываемся на группу событий с wildcard
    ch2 := bus.Subscribe("user.*")
    defer bus.Unsubscribe(ch2)

    // Подписываемся на группу событий с кастомным wildcard
    ch3 := customBus.Subscribe("/user/#")
    defer customBus.Unsubscribe(ch3)

    // Запускаем горутины для обработки событий
    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.Fire(MyEvent{name: "user.login", data: "user123"})
    bus.Fire(MyEvent{name: "user.logout", data: "user123"})
    customBus.Fire(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(path string) Listener

Подписывается на событие по указанному пути. Возвращает канал-подписчик для получения событий.

func (b *bus) Unsubscribe(l Listener)

Отписывается от события и закрывает канал подписчика.

func (b *bus) Close()

Закрывает шину событий и все каналы подписчиков.

func (b *bus) Fire(ev Event)

Отправляет событие всем подписчикам, которые подписаны на соответствующий путь события.

Лицензия

Этот проект лицензирован в соответствии с GNU General Public License версии 3 (GPLv3). Подробности смотрите в файле LICENSE.

                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2026 Alexander NeonXP Kiryukhin <i@neonxp.ru>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

Ссылки

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

go get go.neonxp.ru/eventbus

Usage

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("user.login")
    defer bus.Unsubscribe(ch1)

    // Subscribe to event group with wildcard
    ch2 := bus.Subscribe("user.*")
    defer bus.Unsubscribe(ch2)

    // Subscribe to event group with custom wildcard
    ch3 := customBus.Subscribe("/user/#")
    defer customBus.Unsubscribe(ch3)

    // 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())
        }
    }()

    // Fire events
    bus.Fire(MyEvent{name: "user.login", data: "user123"})
    bus.Fire(MyEvent{name: "user.logout", data: "user123"})
    customBus.Fire(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(path string) Listener

Subscribes to an event at the specified path. Returns a listener channel for receiving events.

func (b *bus) Unsubscribe(l Listener)

Unsubscribes from an event and closes the listener channel.

func (b *bus) Close()

Closes the event bus and all listener channels.

func (b *bus) Fire(ev Event)

Fires 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 file for details.

                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2026 Alexander NeonXP Kiryukhin <i@neonxp.ru>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.