| 
 | 1 | +package router  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"github.com/openziti/foundation/v2/concurrenz"  | 
 | 5 | +	"github.com/openziti/ziti/router/env"  | 
 | 6 | +)  | 
 | 7 | + | 
 | 8 | +// LifecycleEvent represents different phases in the router's lifecycle.  | 
 | 9 | +// Events are fired during router startup and shutdown to allow external  | 
 | 10 | +// components to hook into the router's lifecycle.  | 
 | 11 | +type LifecycleEvent int  | 
 | 12 | + | 
 | 13 | +const (  | 
 | 14 | +	// LifecycleEventConfigLoaded is fired when the router's Create() method is called,  | 
 | 15 | +	// before the router instance is created. This allows listeners to modify the  | 
 | 16 | +	// router configuration before the router is instantiated.  | 
 | 17 | +	LifecycleEventConfigLoaded LifecycleEvent = iota  | 
 | 18 | + | 
 | 19 | +	// LifecycleEventStart is fired when the router's Start() method is called,  | 
 | 20 | +	// before any initialization logic begins. This allows listeners to perform  | 
 | 21 | +	// setup operations or modify the router configuration before startup.  | 
 | 22 | +	LifecycleEventStart  | 
 | 23 | +)  | 
 | 24 | + | 
 | 25 | +// LifecycleListener defines the interface for components that want to receive  | 
 | 26 | +// notifications about router lifecycle events. Implementations should be  | 
 | 27 | +// thread-safe as they may be called concurrently.  | 
 | 28 | +type LifecycleListener interface {  | 
 | 29 | +	// OnLifecycleEvent is called when a lifecycle event occurs.  | 
 | 30 | +	// The event parameter indicates which lifecycle phase is occurring.  | 
 | 31 | +	// The router parameter provides access to the router instance. This will be nil  | 
 | 32 | +	// for LifecycleEventConfigLoaded since the router has not been created yet.  | 
 | 33 | +	// The config parameter provides access to the router configuration.  | 
 | 34 | +	OnLifecycleEvent(event LifecycleEvent, router *Router, config *env.Config)  | 
 | 35 | +}  | 
 | 36 | + | 
 | 37 | +// LifecycleNotifier manages a collection of lifecycle listeners and provides  | 
 | 38 | +// methods to notify them of router lifecycle events. It uses a thread-safe  | 
 | 39 | +// copy-on-write slice to store listeners, allowing concurrent access during  | 
 | 40 | +// event notification.  | 
 | 41 | +type LifecycleNotifier struct {  | 
 | 42 | +	listeners concurrenz.CopyOnWriteSlice[LifecycleListener]  | 
 | 43 | +}  | 
 | 44 | + | 
 | 45 | +// NewLifecycleNotifier creates a new lifecycle notifier with an empty listener list.  | 
 | 46 | +func NewLifecycleNotifier() *LifecycleNotifier {  | 
 | 47 | +	return &LifecycleNotifier{}  | 
 | 48 | +}  | 
 | 49 | + | 
 | 50 | +// AddListener registers a new lifecycle listener. The listener will receive  | 
 | 51 | +// notifications for all future lifecycle events. This method is thread-safe  | 
 | 52 | +// and can be called concurrently with NotifyListeners.  | 
 | 53 | +func (ln *LifecycleNotifier) AddListener(listener LifecycleListener) {  | 
 | 54 | +	ln.listeners.Append(listener)  | 
 | 55 | +}  | 
 | 56 | + | 
 | 57 | +// NotifyListeners sends a lifecycle event notification to all registered listeners.  | 
 | 58 | +// Listeners are called synchronously in the order they were registered.  | 
 | 59 | +// If a listener panics, the panic will propagate and prevent subsequent  | 
 | 60 | +// listeners from being notified.  | 
 | 61 | +func (ln *LifecycleNotifier) NotifyListeners(event LifecycleEvent, router *Router, config *env.Config) {  | 
 | 62 | +	for _, listener := range ln.listeners.Value() {  | 
 | 63 | +		listener.OnLifecycleEvent(event, router, config)  | 
 | 64 | +	}  | 
 | 65 | +}  | 
 | 66 | + | 
 | 67 | +// GlobalLifecycleNotifier is the default lifecycle notifier instance used by  | 
 | 68 | +// the router. External components can register listeners with this global  | 
 | 69 | +// instance to receive router lifecycle events.  | 
 | 70 | +//  | 
 | 71 | +// Example usage:  | 
 | 72 | +//  | 
 | 73 | +//	router.GlobalLifecycleNotifier.AddListener(myListener)  | 
 | 74 | +var GlobalLifecycleNotifier = NewLifecycleNotifier()  | 
0 commit comments