Documentation
¶
Overview ¶
ConfigLayerBroker Overview
ConfigLayerBroker provides thread-safe access to Config with two key features:
- Ordered Layers: Multiple layers can apply partial updates, allowing configuration to be built up from multiple sources (defaults, files, environment, flags, etc.)
- Field Subscriptions: Subscribe to individual field changes with type-safe callbacks that fire immediately with the current value (if set) and on subsequent changes.
Creating a LayerBroker ¶
Create a new broker with an initial configuration (or nil for empty):
broker := NewConfigLayerBroker(&Config{Name: "default"})
// or
broker := NewConfigLayerBroker(nil)
Reading Configuration ¶
Get a deep copy of the current configuration:
cfg := broker.Get() fmt.Println(cfg.Name)
Applying Updates with Layers ¶
Create layers to apply partial updates. Each layer can apply multiple updates over time, and updates are applied in the order received:
// Create a layer (e.g., for file-based config)
fileLayer := broker.Layer()
fileLayer.Set(&ConfigPartial{Name: ptr("from-file")})
// Create another layer (e.g., for environment variables)
envLayer := broker.Layer()
envLayer.Set(&ConfigPartial{Name: ptr("from-env")})
// Later updates from any layer are applied immediately
fileLayer.Set(&ConfigPartial{Name: ptr("updated-from-file")})
Subscribing to Field Changes ¶
Subscribe to individual fields with type-safe callbacks. The callback is invoked:
- Immediately with the current value (if non-zero)
- Whenever the field value changes
The subscribe method returns an unsubscribe function:
unsub := broker.SubscribeName(func(name string) {
fmt.Println("Name changed to:", name)
})
defer unsub() // Clean up when done
Subscribers are only notified when the value actually changes. Setting the same value again does not trigger a notification.
Thread Safety ¶
All operations on ConfigLayerBroker are thread-safe. Multiple goroutines can safely call Get(), Layer().Set(), and Subscribe methods concurrently.
Get() is lock-free using atomic pointer load, making reads very fast. Set() uses copy-on-write with atomic swap, ensuring readers never block.
Dependencies ¶
This generated code requires the following to also be generated:
- ConfigPartial (from: sudo-gen merge)
- Config.Copy() (from: sudo-gen copy)
Index ¶
- type Config
- type ConfigLayer
- type ConfigLayerBroker
- func (b *ConfigLayerBroker) Get() *Config
- func (b *ConfigLayerBroker) Layer() *ConfigLayer
- func (b *ConfigLayerBroker) MarshalJSON() ([]byte, error)
- func (b *ConfigLayerBroker) SubscribeCreatedAt(callback func(time.Time)) func()
- func (b *ConfigLayerBroker) SubscribeDatabase(callback func(*DatabaseConfig)) func()
- func (b *ConfigLayerBroker) SubscribeDescription(callback func(*string)) func()
- func (b *ConfigLayerBroker) SubscribeEnabled(callback func(bool)) func()
- func (b *ConfigLayerBroker) SubscribeHosts(callback func([]string)) func()
- func (b *ConfigLayerBroker) SubscribeLabels(callback func(map[string]string)) func()
- func (b *ConfigLayerBroker) SubscribeMaxRetries(callback func(int32)) func()
- func (b *ConfigLayerBroker) SubscribeMetadata(callback func(map[string]any)) func()
- func (b *ConfigLayerBroker) SubscribeName(callback func(string)) func()
- func (b *ConfigLayerBroker) SubscribePort(callback func(int)) func()
- func (b *ConfigLayerBroker) SubscribeRate(callback func(float64)) func()
- func (b *ConfigLayerBroker) SubscribeTags(callback func([]Tag)) func()
- func (b *ConfigLayerBroker) SubscribeTimeout(callback func(int64)) func()
- func (b *ConfigLayerBroker) SubscribeUpdatedAt(callback func(*time.Time)) func()
- type ConfigLayerBrokerState
- type ConfigPartial
- type DatabaseConfig
- type DatabaseConfigPartial
- type Tag
- type TagPartial
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Basic types
Name string `json:"name,omitempty"`
Port int `json:"port,omitempty"`
MaxRetries int32 `json:"max_retries,omitempty"`
Timeout int64 `json:"timeout,omitempty"`
Rate float64 `json:"rate,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Description *string `json:"description,omitempty"`
// Slice types
Hosts []string `json:"hosts,omitempty"`
Tags []Tag `json:"tags,omitempty"`
// Map types
Labels map[string]string `json:"labels,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
// Nested struct
Database *DatabaseConfig `json:"database,omitempty"`
// Time
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}
func (*Config) ApplyPartial ¶
func (c *Config) ApplyPartial(p *ConfigPartial)
type ConfigLayer ¶
type ConfigLayer struct {
// contains filtered or unexported fields
}
ConfigLayer applies partial updates to the LayerBroker.
func (*ConfigLayer) Set ¶
func (l *ConfigLayer) Set(p *ConfigPartial)
Set applies the partial and notifies subscribers for changed fields. Uses copy-on-write: copies the config, applies changes, then atomically swaps.
type ConfigLayerBroker ¶
type ConfigLayerBroker struct {
// contains filtered or unexported fields
}
ConfigLayerBroker provides thread-safe access to Config with ordered layer updates and subscriptions.
func NewConfigLayerBroker ¶
func NewConfigLayerBroker(cfg *Config) *ConfigLayerBroker
NewConfigLayerBroker creates a new LayerBroker wrapping the given config. If cfg is nil, an empty config is used.
func (*ConfigLayerBroker) Get ¶
func (b *ConfigLayerBroker) Get() *Config
Get returns a deep copy of the current configuration. This is a lock-free operation using atomic pointer load.
func (*ConfigLayerBroker) Layer ¶
func (b *ConfigLayerBroker) Layer() *ConfigLayer
Layer returns a new layer for applying partial changes.
func (*ConfigLayerBroker) MarshalJSON ¶
func (b *ConfigLayerBroker) MarshalJSON() ([]byte, error)
MarshalJSON serializes the broker state including base config, all layer partials, and final merged config.
func (*ConfigLayerBroker) SubscribeCreatedAt ¶
func (b *ConfigLayerBroker) SubscribeCreatedAt(callback func(time.Time)) func()
SubscribeCreatedAt subscribes to changes on CreatedAt. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeDatabase ¶
func (b *ConfigLayerBroker) SubscribeDatabase(callback func(*DatabaseConfig)) func()
SubscribeDatabase subscribes to changes on Database. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeDescription ¶
func (b *ConfigLayerBroker) SubscribeDescription(callback func(*string)) func()
SubscribeDescription subscribes to changes on Description. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeEnabled ¶
func (b *ConfigLayerBroker) SubscribeEnabled(callback func(bool)) func()
SubscribeEnabled subscribes to changes on Enabled. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeHosts ¶
func (b *ConfigLayerBroker) SubscribeHosts(callback func([]string)) func()
SubscribeHosts subscribes to changes on Hosts. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeLabels ¶
func (b *ConfigLayerBroker) SubscribeLabels(callback func(map[string]string)) func()
SubscribeLabels subscribes to changes on Labels. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeMaxRetries ¶
func (b *ConfigLayerBroker) SubscribeMaxRetries(callback func(int32)) func()
SubscribeMaxRetries subscribes to changes on MaxRetries. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeMetadata ¶
func (b *ConfigLayerBroker) SubscribeMetadata(callback func(map[string]any)) func()
SubscribeMetadata subscribes to changes on Metadata. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeName ¶
func (b *ConfigLayerBroker) SubscribeName(callback func(string)) func()
SubscribeName subscribes to changes on Name. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribePort ¶
func (b *ConfigLayerBroker) SubscribePort(callback func(int)) func()
SubscribePort subscribes to changes on Port. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeRate ¶
func (b *ConfigLayerBroker) SubscribeRate(callback func(float64)) func()
SubscribeRate subscribes to changes on Rate. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeTags ¶
func (b *ConfigLayerBroker) SubscribeTags(callback func([]Tag)) func()
SubscribeTags subscribes to changes on Tags. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeTimeout ¶
func (b *ConfigLayerBroker) SubscribeTimeout(callback func(int64)) func()
SubscribeTimeout subscribes to changes on Timeout. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
func (*ConfigLayerBroker) SubscribeUpdatedAt ¶
func (b *ConfigLayerBroker) SubscribeUpdatedAt(callback func(*time.Time)) func()
SubscribeUpdatedAt subscribes to changes on UpdatedAt. The callback is invoked immediately if the value is non-zero, and on future changes. Returns an unsubscribe function.
type ConfigLayerBrokerState ¶
type ConfigLayerBrokerState struct {
Base *Config `json:"base"`
Layers []*ConfigPartial `json:"layers"`
Final *Config `json:"final"`
}
ConfigLayerBrokerState represents the serializable state of the broker.
type ConfigPartial ¶
type ConfigPartial struct {
Name *string `json:"name,omitempty"`
Port *int `json:"port,omitempty"`
MaxRetries *int32 `json:"max_retries,omitempty"`
Timeout *int64 `json:"timeout,omitempty"`
Rate *float64 `json:"rate,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Description *string `json:"description,omitempty"`
Hosts []string `json:"hosts,omitempty"`
Tags []Tag `json:"tags,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Database *DatabaseConfigPartial `json:"database,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}
type DatabaseConfig ¶
type DatabaseConfig struct {
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
SSLMode string `json:"ssl_mode,omitempty"`
}
DatabaseConfig represents database connection settings.
func (*DatabaseConfig) ApplyPartial ¶
func (c *DatabaseConfig) ApplyPartial(p *DatabaseConfigPartial)
func (*DatabaseConfig) Copy ¶
func (c *DatabaseConfig) Copy() *DatabaseConfig
func (*DatabaseConfig) Equal ¶ added in v0.0.4
func (c *DatabaseConfig) Equal(other *DatabaseConfig) bool
Equal returns true if c and other have the same values.
type DatabaseConfigPartial ¶
type Tag ¶
Tag represents a key-value tag.
func (*Tag) ApplyPartial ¶
func (c *Tag) ApplyPartial(p *TagPartial)