Ir al contenido

Entry Handlers

Los entry handlers procesan entradas de registry por kind. Cuando las entradas son agregadas, actualizadas, o eliminadas, el registry despacha eventos a handlers matcheados.

El registry mantiene un mapa de patrones de kind a handlers. Cuando una entrada cambia:

  1. Registry emite evento (entry.create, entry.update, entry.delete)
  2. Registry de handlers matchea kind de entrada contra patrones registrados
  3. Handlers matcheados reciben la entrada
  4. Handlers procesan o rechazan la entrada

Los handlers se suscriben usando patrones:

PatrónMatchea
http.serviceSolo match exacto
http.*http.service, http.router, http.endpoint
function.*function.lua, function.lua.bc

Los handlers implementan 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 un error desde Add rechaza la entrada.

TipoPropósitoPuede Rechazar
ListenerHandler primario
ObserverHandler secundario (logging, métricas)No
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 datos de entrada. Este helper vive bajo internal/, por lo que solo se puede importar desde dentro del módulo runtime; las extensiones fuera del árbol deben copiar el patrón o usar el transcoder directamente:

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
}
// Procesar cfg...
return nil
}

El decoder:

  1. Deserializa entry.Data en su struct de config
  2. Completa ID y Meta desde la entrada
  3. Llama InitDefaults() si está implementado
  4. Llama Validate() si está implementado

Los configs de entrada típicamente incluyen:

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 operaciones atómicas a través de múltiples entradas, implemente TransactionListener:

type TransactionListener interface {
Begin(ctx context.Context)
Commit(ctx context.Context)
Discard(ctx context.Context)
}

El registry llama Begin antes de procesar un batch, luego Commit en éxito o Discard en fallo.