Обработчики записей
Обработчики записей обрабатывают записи реестра по kind. При добавлении, обновлении или удалении записей реестр диспатчит события соответствующим обработчикам.
Принцип работы
Реестр поддерживает карту паттернов kind к обработчикам. При изменении записи:
- Реестр отправляет событие (
entry.create,entry.update,entry.delete) - Реестр обработчиков сопоставляет kind записи с зарегистрированными паттернами
- Соответствующие обработчики получают запись
- Обработчики обрабатывают или отклоняют запись
Паттерны kind
Обработчики подписываются с использованием паттернов:
| Паттерн | Совпадает |
|---|---|
http.service |
Только точное совпадение |
http.* |
http.service, http.router, http.endpoint |
function.* |
function.lua, function.lua.bc |
Интерфейс Entry Listener
Обработчики реализуют registry.EntryListener:
type EntryListener interface {
Add(ctx context.Context, entry Entry) error
Update(ctx context.Context, entry Entry) error
Delete(ctx context.Context, entry Entry) error
}
Возврат ошибки из Add отклоняет запись.
Listener vs Observer
| Тип | Назначение | Может отклонить |
|---|---|---|
| Listener | Основной обработчик | Да |
| Observer | Вторичный обработчик (логирование, метрики) | Нет |
handlers.RegisterListener("http.*", httpManager)
handlers.RegisterObserver("function.*", metricsCollector)
Регистрация обработчиков
Регистрация обработчиков при загрузке:
func MyService() boot.Component {
return boot.New(boot.P{
Name: "myservice",
DependsOn: []boot.Name{core.RegistryName},
Load: func(ctx context.Context) (context.Context, error) {
handlers := bootpkg.GetHandlerRegistry(ctx)
handlers.RegisterListener("myservice.*", manager)
return ctx, nil
},
})
}
Декодирование данных записи
Используйте entry.DecodeEntryConfig для десериализации данных записи:
func (m *Manager) Add(ctx context.Context, ent registry.Entry) error {
cfg, err := entry.DecodeEntryConfig[ComponentConfig](ctx, m.dtt, ent)
if err != nil {
return err
}
// Обработка cfg...
return nil
}
Декодер:
- Десериализует
entry.Dataв вашу структуру конфига - Заполняет
IDиMetaиз записи - Вызывает
InitDefaults(), если реализован - Вызывает
Validate(), если реализован
Структура конфига
Конфиги записей обычно включают:
type ComponentConfig struct {
ID registry.ID `json:"id"`
Meta attrs.Bag `json:"meta"`
Name string `json:"name"`
Timeout int `json:"timeout,omitempty"`
}
func (c *ComponentConfig) InitDefaults() {
if c.Timeout == 0 {
c.Timeout = 30
}
}
func (c *ComponentConfig) Validate() error {
if c.Name == "" {
return fmt.Errorf("name is required")
}
return nil
}
Поддержка транзакций
Для атомарных операций над несколькими записями реализуйте TransactionListener:
type TransactionListener interface {
Begin(ctx context.Context)
Commit(ctx context.Context)
Discard(ctx context.Context)
}
Реестр вызывает Begin перед обработкой пакета, затем Commit при успехе или Discard при неудаче.
См. также
- Реестр — хранение записей
- Архитектура — последовательность загрузки