1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
# eventbus - Асинхронная шина событий для Go
[](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 <i@neonxp.ru>
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 <i@neonxp.ru>
# 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 <i@neonxp.ru>
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 <i@neonxp.ru>
|