エントリハンドラ
エントリハンドラ
Section titled “エントリハンドラ”エントリハンドラはkindごとにレジストリエントリを処理します。エントリが追加、更新、削除されると、レジストリがマッチするハンドラにイベントをディスパッチします。
レジストリはkindパターンからハンドラへのマップを維持。エントリが変更されると:
- レジストリがイベントを発行(
entry.create、entry.update、entry.delete) - ハンドラレジストリがエントリkindを登録されたパターンとマッチング
- マッチするハンドラがエントリを受信
- ハンドラがエントリを処理または拒否
Kindパターン
Section titled “Kindパターン”ハンドラはパターンを使用してサブスクライブ:
| パターン | マッチ |
|---|---|
http.service | 完全一致のみ |
http.* | http.service、http.router、http.endpoint |
function.* | function.lua、function.lua.bc |
EntryListenerインターフェース
Section titled “EntryListenerインターフェース”ハンドラは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とObserver
Section titled “ListenerとObserver”| タイプ | 目的 | 拒否可能 |
|---|---|---|
| Listener | 主要ハンドラ | はい |
| Observer | 二次ハンドラ(ログ、メトリクス) | いいえ |
handlers.RegisterListener("http.*", httpManager)handlers.RegisterObserver("function.*", metricsCollector)ハンドラの登録
Section titled “ハンドラの登録”ブート時にハンドラを登録:
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 }, })}エントリデータのデコード
Section titled “エントリデータのデコード”internal/entryのentry.DecodeEntryConfigを使用してエントリデータをアンマーシャルします。このヘルパーはinternal/配下に存在するため、ランタイムモジュール内からのみインポート可能です。ツリー外の拡張機能は、このパターンをコピーするか、トランスコーダを直接使用する必要があります:
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()を呼び出し
Config構造体
Section titled “Config構造体”エントリ設定は通常以下を含む:
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}トランザクションサポート
Section titled “トランザクションサポート”複数エントリにまたがるアトミック操作にはTransactionListenerを実装:
type TransactionListener interface { Begin(ctx context.Context) Commit(ctx context.Context) Discard(ctx context.Context)}レジストリはバッチ処理前にBeginを呼び出し、成功時にCommit、失敗時にDiscardを呼び出します。