Pular para o conteúdo

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.

O registro mantém um mapa de padrões de tipo para handlers. Quando uma entrada muda:

  1. Registry emite evento (entry.create, entry.update, entry.delete)
  2. Registry de handlers faz match do tipo da entrada contra padrões registrados
  3. Handlers correspondentes recebem a entrada
  4. Handlers processam ou rejeitam a entrada

Handlers se inscrevem usando padrões:

PadrãoCorresponde
http.serviceApenas match exato
http.*http.service, http.router, http.endpoint
function.*function.lua, function.lua.bc

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.

TipoPropósitoPode Rejeitar
ListenerHandler primárioSim
ObserverHandler secundário (logging, métricas)Não
handlers.RegisterListener("http.*", httpManager)
handlers.RegisterObserver("function.*", metricsCollector)

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
},
})
}

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:

  1. Deserializa entry.Data em sua struct de config
  2. Popula ID e Meta da entrada
  3. Chama InitDefaults() se implementado
  4. Chama Validate() se implementado

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
}

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.