dynamic

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2026 License: Apache-2.0, MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Module = fx.Module("config/dynamic",
	fx.Provide(
		ProvideRegistry,
		ProvideViperBridge,
	),
)

Module provides the dynamic configuration registry and viper bridge. Packages register their own config entries via Registry.RegisterEntries.

Functions

This section is empty.

Types

type ChangeEvent

type ChangeEvent struct {
	// Key is the configuration key that changed.
	Key config.Key
	// OldValue is the previous value.
	OldValue any
	// NewValue is the new value.
	NewValue any
	// Source indicates where the change originated.
	Source ChangeSource
}

ChangeEvent represents a configuration change notification.

type ChangeSource

type ChangeSource string

ChangeSource indicates where a configuration change originated.

const (
	// SourceAPI indicates the change came from the admin API.
	SourceAPI ChangeSource = "api"
	// SourceFile indicates the change came from a config file update.
	SourceFile ChangeSource = "file"
)

type ConfigEntry

type ConfigEntry struct {
	Value  any
	Schema ConfigSchema
}

ConfigEntry holds a configuration value and its schema for validation.

type ConfigSchema

type ConfigSchema interface {
	// ParseAndValidate converts a raw value (from JSON) to a typed value
	// and validates it against constraints.
	// Returns the typed value or a descriptive error.
	ParseAndValidate(raw any) (any, error)

	// TypeDescription returns human-readable type info for error messages.
	TypeDescription() string
}

ConfigSchema handles parsing raw JSON values and validating them.

type DurationSchema

type DurationSchema struct {
	Min time.Duration
	Max time.Duration
}

DurationSchema parses and validates duration values. Accepts string values like "30s", "5m", "1h" or time.Duration directly.

func (DurationSchema) ParseAndValidate

func (s DurationSchema) ParseAndValidate(raw any) (any, error)

func (DurationSchema) TypeDescription

func (s DurationSchema) TypeDescription() string

type IntSchema

type IntSchema struct {
	Min int
	Max int
}

IntSchema parses and validates integer values. Accepts int, int64, float64 (from JSON), or string representations.

func (IntSchema) ParseAndValidate

func (s IntSchema) ParseAndValidate(raw any) (any, error)

func (IntSchema) TypeDescription

func (s IntSchema) TypeDescription() string

type Observer

type Observer interface {
	// OnConfigChange is called when a configuration value changes.
	// Implementations should be non-blocking and return quickly.
	OnConfigChange(event ChangeEvent)
}

Observer is notified when configuration values change.

type ObserverFunc

type ObserverFunc func(event ChangeEvent)

ObserverFunc is a function adapter for the Observer interface.

func (ObserverFunc) OnConfigChange

func (f ObserverFunc) OnConfigChange(event ChangeEvent)

OnConfigChange implements Observer.

type ParseError

type ParseError struct {
	Value    any
	Expected string
	Cause    error
}

ParseError indicates a value could not be parsed to the expected type.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

type PersistError

type PersistError struct {
	Cause error
}

PersistError indicates a failure to persist configuration to file.

func (*PersistError) Error

func (e *PersistError) Error() string

func (*PersistError) Unwrap

func (e *PersistError) Unwrap() error

type Persister

type Persister interface {
	// Persist writes only the specified config changes to persistent storage.
	// This enables surgical updates that preserve existing config file content.
	Persist(updates map[config.Key]any) error
}

Persister handles persisting configuration changes.

type RangeError

type RangeError[T any] struct {
	Value T
	Min   T
	Max   T
}

RangeError indicates a value is outside the allowed range.

func (*RangeError[T]) Error

func (e *RangeError[T]) Error() string

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is the central store for all dynamic configuration values. It provides thread-safe access to configuration and notifies observers of changes.

func NewRegistry

func NewRegistry(cfgs map[config.Key]ConfigEntry, opts ...RegistryOption) *Registry

NewRegistry creates a new Registry with the given configuration entries. If cfgs is nil, an empty registry is created that can be populated via RegisterEntries.

func ProvideRegistry

func ProvideRegistry() *Registry

ProvideRegistry creates an empty Registry. Packages register their own entries via RegisterEntries during fx startup.

func (*Registry) GetAll

func (r *Registry) GetAll() map[string]any

GetAll returns all config values as a map (for API response). Duration values are formatted as strings.

func (*Registry) GetDuration

func (r *Registry) GetDuration(key config.Key, fallback time.Duration) time.Duration

GetDuration returns the duration value for the given key. If the key doesn't exist or the value is not a duration, returns the fallback.

func (*Registry) GetInt

func (r *Registry) GetInt(key config.Key, fallback int) int

GetInt returns the int value for the given key. If the key doesn't exist or the value is not an int, returns the fallback.

func (*Registry) GetUint

func (r *Registry) GetUint(key config.Key, fallback uint) uint

GetUint returns the uint value for the given key. If the key doesn't exist or the value is not a uint, returns the fallback.

func (*Registry) Keys

func (r *Registry) Keys() []config.Key

Keys returns all registered configuration keys.

func (*Registry) RegisterEntries

func (r *Registry) RegisterEntries(entries map[config.Key]ConfigEntry) error

RegisterEntries adds new configuration entries to the registry. This allows packages to register their own dynamic config keys. Returns an error if any key is already registered.

func (*Registry) Subscribe

func (r *Registry) Subscribe(key config.Key, observer Observer) (func(), error)

Subscribe registers an observer for changes to the specified key. Returns a function to unsubscribe the observer.

func (*Registry) SubscribeFunc

func (r *Registry) SubscribeFunc(key config.Key, fn func(ChangeEvent)) (func(), error)

SubscribeFunc is a convenience method that wraps a function as an Observer.

func (*Registry) Update

func (r *Registry) Update(updates map[string]any, persist bool, source ChangeSource) error

Update accepts raw string keys and untyped values from the API. It handles all parsing and validation internally. If persist is true, the changes are written to persistent storage. Returns an error if validation fails for any value.

type RegistryOption

type RegistryOption func(*Registry)

RegistryOption configures a Registry.

func WithPersister

func WithPersister(p Persister) RegistryOption

WithPersister sets the persister for writing config changes to disk.

type TOMLPersister

type TOMLPersister struct {
	// contains filtered or unexported fields
}

TOMLPersister implements surgical TOML file updates. Unlike Viper's WriteConfig which dumps all values, this persister reads the existing file, updates only the changed keys, and writes back preserving all other content.

func NewTOMLPersister

func NewTOMLPersister(filePath string) *TOMLPersister

NewTOMLPersister creates a new TOMLPersister.

func (*TOMLPersister) Persist

func (p *TOMLPersister) Persist(updates map[config.Key]any) error

Persist writes only the specified config changes to the config file.

type TypeError

type TypeError struct {
	Expected string
	Got      string
}

TypeError indicates a type mismatch between expected and actual value.

func (*TypeError) Error

func (e *TypeError) Error() string

type UintSchema

type UintSchema struct {
	Min uint
	Max uint
}

UintSchema parses and validates unsigned integer values. Accepts uint, int, int64, float64 (from JSON), or string representations.

func (UintSchema) ParseAndValidate

func (s UintSchema) ParseAndValidate(raw any) (any, error)

func (UintSchema) TypeDescription

func (s UintSchema) TypeDescription() string

type UnknownKeyError

type UnknownKeyError struct {
	Key string
}

UnknownKeyError indicates an unrecognized configuration key.

func (*UnknownKeyError) Error

func (e *UnknownKeyError) Error() string

type ValidationError

type ValidationError struct {
	Key   config.Key
	Cause error
}

ValidationError wraps a validation failure with the config key context.

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

type ViperBridge

type ViperBridge struct {
	// contains filtered or unexported fields
}

ViperBridge bridges between Viper configuration and the dynamic Registry. It provides methods to explicitly reload configuration from the config file.

func NewViperBridge

func NewViperBridge(v *viper.Viper, registry *Registry) *ViperBridge

NewViperBridge creates a new ViperBridge.

func ProvideViperBridge

func ProvideViperBridge(registry *Registry) *ViperBridge

ProvideViperBridge creates a ViperBridge for config file reloads.

func (*ViperBridge) Reload

func (vb *ViperBridge) Reload() error

Reload explicitly reloads config from the file. Call this in response to admin API request or CLI command. Returns an error if the config file cannot be read or if any value fails validation. On validation failure, no values are updated (fail-fast behavior).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL