events.go RawHistoryFolder
1package proxy
2
3import (
4 "context"
5
6 "github.com/bnema/zerowrap"
7
8 "github.com/bnema/gordon/internal/domain"
9)
10
11// TargetInvalidator defines the interface for invalidating proxy targets.
12type TargetInvalidator interface {
13 InvalidateTarget(ctx context.Context, domainName string)
14}
15
16// ContainerDeployedHandler handles container.deployed events to invalidate proxy cache.
17type ContainerDeployedHandler struct {
18 invalidator TargetInvalidator
19 ctx context.Context
20}
21
22// NewContainerDeployedHandler creates a new ContainerDeployedHandler.
23func NewContainerDeployedHandler(ctx context.Context, invalidator TargetInvalidator) *ContainerDeployedHandler {
24 return &ContainerDeployedHandler{
25 invalidator: invalidator,
26 ctx: ctx,
27 }
28}
29
30// Handle handles a container.deployed event by invalidating the proxy cache.
31func (h *ContainerDeployedHandler) Handle(ctx context.Context, event domain.Event) error {
32 ctx = zerowrap.CtxWithFields(ctx, map[string]any{
33 zerowrap.FieldLayer: "usecase",
34 zerowrap.FieldHandler: "ContainerDeployedHandler",
35 zerowrap.FieldEvent: string(event.Type),
36 "event_id": event.ID,
37 })
38 log := zerowrap.FromCtx(ctx)
39
40 // Get domain from event
41 domainName := event.Route
42 if domainName == "" {
43 // Try to get from payload
44 if payload, ok := event.Data.(*domain.ContainerEventPayload); ok {
45 domainName = payload.Domain
46 }
47 }
48
49 if domainName == "" {
50 log.Debug().Msg("no domain in container deployed event, skipping cache invalidation")
51 return nil
52 }
53
54 log.Debug().Str("domain", domainName).Msg("invalidating proxy cache for deployed container")
55 h.invalidator.InvalidateTarget(ctx, domainName)
56
57 return nil
58}
59
60// CanHandle returns whether this handler can handle the given event type.
61func (h *ContainerDeployedHandler) CanHandle(eventType domain.EventType) bool {
62 return eventType == domain.EventContainerDeployed
63}
64
65// TargetRefresher defines the interface for refreshing all proxy targets.
66type TargetRefresher interface {
67 RefreshTargets(ctx context.Context) error
68}
69
70// ConfigReloadProxyHandler handles config.reload events to clear the proxy target cache.
71// When routes are removed during a config reload, cached targets for those routes
72// become stale. This handler clears all cached targets so they are re-resolved.
73type ConfigReloadProxyHandler struct {
74 refresher TargetRefresher
75 ctx context.Context
76}
77
78// NewConfigReloadProxyHandler creates a new ConfigReloadProxyHandler.
79func NewConfigReloadProxyHandler(ctx context.Context, refresher TargetRefresher) *ConfigReloadProxyHandler {
80 return &ConfigReloadProxyHandler{
81 refresher: refresher,
82 ctx: ctx,
83 }
84}
85
86// Handle clears all cached proxy targets so they are re-resolved from current state.
87func (h *ConfigReloadProxyHandler) Handle(ctx context.Context, event domain.Event) error {
88 ctx = zerowrap.CtxWithFields(ctx, map[string]any{
89 zerowrap.FieldLayer: "usecase",
90 zerowrap.FieldHandler: "ConfigReloadProxyHandler",
91 zerowrap.FieldEvent: string(event.Type),
92 "event_id": event.ID,
93 })
94 log := zerowrap.FromCtx(ctx)
95
96 log.Debug().Msg("clearing proxy target cache after config reload")
97 return h.refresher.RefreshTargets(ctx)
98}
99
100// CanHandle returns whether this handler can handle the given event type.
101func (h *ConfigReloadProxyHandler) CanHandle(eventType domain.EventType) bool {
102 return eventType == domain.EventConfigReload
103}