Entry Handlers
Entry Handlers
Seção intitulada “Entry Handlers”Entry handlers processam entradas do registro por tipo. Quando entradas são adicionadas, atualizadas ou deletadas, o registro despacha eventos para handlers correspondentes.
Como Funciona
Seção intitulada “Como Funciona”O registro mantém um mapa de padrões de tipo para handlers. Quando uma entrada muda:
- Registry emite evento (
entry.create,entry.update,entry.delete) - Registry de handlers faz match do tipo da entrada contra padrões registrados
- Handlers correspondentes recebem a entrada
- Handlers processam ou rejeitam a entrada
Padrões de Tipo
Seção intitulada “Padrões de Tipo”Handlers se inscrevem usando padrões:
| Padrão | Corresponde |
|---|---|
http.service | Apenas match exato |
http.* | http.service, http.router, http.endpoint |
function.* | function.lua, function.lua.bc |
Interface EntryListener
Seção intitulada “Interface EntryListener”Handlers implementam 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}Retornar erro de Add rejeita a entrada.
Listener vs Observer
Seção intitulada “Listener vs Observer”| Tipo | Propósito | Pode Rejeitar |
|---|---|---|
| Listener | Handler primário | Sim |
| Observer | Handler secundário (logging, métricas) | Não |
handlers.RegisterListener("http.*", httpManager)handlers.RegisterObserver("function.*", metricsCollector)Registrando Handlers
Seção intitulada “Registrando Handlers”Registre handlers durante boot:
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 }, })}Decodificando Dados de Entrada
Seção intitulada “Decodificando Dados de Entrada”Use entry.DecodeEntryConfig de internal/entry para deserializar dados da entrada. Este helper reside em internal/, portanto só pode ser importado de dentro do módulo runtime; extensões fora da árvore devem copiar o padrão ou usar o transcoder diretamente:
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 } // Processar cfg... return nil}O decoder:
- Deserializa
entry.Dataem sua struct de config - Popula
IDeMetada entrada - Chama
InitDefaults()se implementado - Chama
Validate()se implementado
Estrutura de Config
Seção intitulada “Estrutura de Config”Configs de entrada tipicamente incluem:
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}Suporte a Transações
Seção intitulada “Suporte a Transações”Para operações atômicas através de múltiplas entradas, implemente TransactionListener:
type TransactionListener interface { Begin(ctx context.Context) Commit(ctx context.Context) Discard(ctx context.Context)}O registry chama Begin antes de processar um batch, depois Commit em sucesso ou Discard em falha.
Veja Também
Seção intitulada “Veja Também”- Registry - Armazenamento de entradas
- Architecture - Sequência de boot