Zum Inhalt springen

Entry-Handler

Entry-Handler verarbeiten Registry-Einträge nach Kind. Wenn Einträge hinzugefügt, aktualisiert oder gelöscht werden, dispatcht die Registry Events an passende Handler.

Die Registry pflegt eine Map von Kind-Patterns zu Handlern. Wenn ein Eintrag sich ändert:

  1. Registry emittiert Event (entry.create, entry.update, entry.delete)
  2. Handler-Registry matched Entry-Kind gegen registrierte Patterns
  3. Passende Handler erhalten den Eintrag
  4. Handler verarbeiten oder lehnen den Eintrag ab

Handler subscriben mit Patterns:

PatternMatched
http.serviceNur exakter Match
http.*http.service, http.router, http.endpoint
function.*function.lua, function.lua.bc

Handler implementieren 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
}

Wird von Add ein Fehler zurückgegeben, wird der Eintrag abgelehnt.

TypZweckKann ablehnen
ListenerPrimärer HandlerJa
ObserverSekundärer Handler (Logging, Metriken)Nein
handlers.RegisterListener("http.*", httpManager)
handlers.RegisterObserver("function.*", metricsCollector)

Handler während Boot registrieren:

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

Verwenden Sie entry.DecodeEntryConfig aus internal/entry, um Entry-Daten zu unmarshallen. Dieser Helper befindet sich unter internal/, ist also nur innerhalb des Runtime-Moduls importierbar; Erweiterungen außerhalb des Baums müssen das Muster kopieren oder den Transcoder direkt verwenden:

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 verarbeiten...
return nil
}

Der Decoder:

  1. Unmarshalled entry.Data in Ihre Config-Struct
  2. Befüllt ID und Meta aus dem Entry
  3. Ruft InitDefaults() auf wenn implementiert
  4. Ruft Validate() auf wenn implementiert

Entry-Configs beinhalten typischerweise:

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
}

Für atomare Operationen über mehrere Einträge implementieren Sie TransactionListener:

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

Die Registry ruft Begin vor Verarbeitung eines Batches auf, dann Commit bei Erfolg oder Discard bei Fehler.