Documentation
¶
Index ¶
- Constants
- Variables
- func ContextNamespace(ctx context.Context) string
- func ContextWithManager(ctx context.Context, mgr Manager) context.Context
- func ContextWithNamespace(ctx context.Context, namespace string) context.Context
- func IsBulkWritePartial(err error) bool
- func IsInvalidKey(err error) bool
- func IsKeyExists(err error) bool
- func IsNotFound(err error) bool
- func IsTypeMismatch(err error) bool
- func IsUnsupportedCodec(err error) bool
- func IsWatchUnhealthy(err error) bool
- func Set(ctx context.Context, key string, value any, opts ...SetOption) error
- func ValidateKey(key string) error
- func ValidateNamespace(namespace string) error
- func WrapStoreError(op, backend, key string, err error) error
- type BulkStore
- type BulkWriteError
- type CacheStats
- type ChangeEvent
- type ChangeType
- type CodecValidator
- type Config
- type Filter
- type FilterBuilder
- type HealthChecker
- type InvalidKeyError
- type KeyExistsError
- type KeyNotFoundError
- type Manager
- type ManagerObserver
- type Metadata
- type Option
- type Page
- type Reader
- type SetOption
- type StatsProvider
- type Store
- type StoreError
- type StoreStats
- type Type
- type TypeMismatchError
- type UnsupportedCodecError
- type Value
- type ValueOption
- func WithValueCodec(c codec.Codec) ValueOption
- func WithValueEntryID(id string) ValueOption
- func WithValueMetadata(version int64, createdAt, updatedAt time.Time) ValueOption
- func WithValueStale(stale bool) ValueOption
- func WithValueType(t Type) ValueOption
- func WithValueWriteMode(mode WriteMode) ValueOption
- type WatchFilter
- type WatchHealthError
- type WatchStatus
- type WriteMode
- type WriteModer
- type Writer
Examples ¶
Constants ¶
const DefaultNamespace = ""
DefaultNamespace is the default namespace (empty string). Use this when you don't need namespace separation.
Variables ¶
var ( // ErrNotFound is returned when a config key does not exist. ErrNotFound = errors.New("config: key not found") // ErrTypeMismatch is returned when attempting to convert a value to an incompatible type. ErrTypeMismatch = errors.New("config: type mismatch") // ErrInvalidKey is returned when a config key is empty or malformed. ErrInvalidKey = errors.New("config: invalid key") // ErrInvalidNamespace is returned when a namespace is malformed. ErrInvalidNamespace = errors.New("config: invalid namespace") // ErrInvalidValue is returned when a value cannot be stored. ErrInvalidValue = errors.New("config: invalid value") // ErrStoreNotConnected is returned when operating on a disconnected store. ErrStoreNotConnected = errors.New("config: store not connected") // ErrStoreClosed is returned when operating on a closed store. ErrStoreClosed = errors.New("config: store closed") // ErrWatchNotSupported is returned when the store does not support watching. ErrWatchNotSupported = errors.New("config: watch not supported") // ErrManagerClosed is returned when operating on a closed manager. ErrManagerClosed = errors.New("config: manager closed") // ErrCodecNotFound is returned when a codec is not registered. ErrCodecNotFound = errors.New("config: codec not found") // ErrReadOnly is returned when attempting to write to a read-only store. ErrReadOnly = errors.New("config: store is read-only") // ErrKeyExists is returned when attempting to create a key that already exists. ErrKeyExists = errors.New("config: key already exists") // ErrUnsupportedCodec is returned when a store does not support the requested codec. ErrUnsupportedCodec = errors.New("config: unsupported codec") )
Sentinel errors for config operations. Use errors.Is() to check for these errors as they may be wrapped.
var ErrBulkWritePartial = errors.New("config: bulk write partially failed")
ErrBulkWritePartial is returned when a bulk write operation partially fails.
var ErrWatchUnhealthy = errors.New("config: watch unhealthy")
ErrWatchUnhealthy is returned by Health() when watch has consecutive failures.
Functions ¶
func ContextNamespace ¶
ContextNamespace retrieves the namespace from context. Returns empty string if no namespace is set.
func ContextWithManager ¶
ContextWithManager adds a Manager to the context. This allows handlers to access configuration without explicit dependency injection.
Example ¶
package main
import (
"context"
"fmt"
"github.com/rbaliyan/config"
"github.com/rbaliyan/config/memory"
)
func main() {
ctx := context.Background()
mgr, _ := config.New(config.WithStore(memory.NewStore()))
_ = mgr.Connect(ctx)
defer mgr.Close(ctx)
// Add manager and namespace to context
ctx = config.ContextWithManager(ctx, mgr)
ctx = config.ContextWithNamespace(ctx, "myapp")
// Set and get via context convenience functions
_ = config.Set(ctx, "greeting", "hello")
val, _ := config.Get(ctx, "greeting")
s, _ := val.String()
fmt.Println(s)
}
Output: hello
func ContextWithNamespace ¶
ContextWithNamespace adds a namespace to the context. Operations will use this namespace.
func IsBulkWritePartial ¶
IsBulkWritePartial checks if an error indicates a partial bulk write failure. Use errors.As() to get the BulkWriteError for details about which keys failed.
func IsInvalidKey ¶
IsInvalidKey checks if an error indicates an invalid key.
func IsKeyExists ¶
IsKeyExists checks if an error indicates a key already exists.
func IsNotFound ¶
IsNotFound checks if an error indicates a missing key.
func IsTypeMismatch ¶
IsTypeMismatch checks if an error indicates a type mismatch.
func IsUnsupportedCodec ¶ added in v0.4.2
IsUnsupportedCodec checks if an error indicates an unsupported codec.
func IsWatchUnhealthy ¶
IsWatchUnhealthy checks if an error indicates watch connection issues.
func Set ¶
Set is a convenience function that sets a value using the Manager from context. Returns ErrManagerClosed if no manager is in context. Uses the namespace from context, or "" (default) if not set.
func ValidateKey ¶
ValidateKey validates a configuration key. Keys must:
- Not be empty
- Contain only alphanumeric characters, underscores, dashes, dots, and slashes
- Not contain path traversal sequences (..)
- Not start or end with a slash
Returns an InvalidKeyError if the key is invalid.
func ValidateNamespace ¶
ValidateNamespace validates a namespace name. Empty namespaces are allowed (represents the default namespace). Returns ErrInvalidNamespace if the namespace contains invalid characters.
func WrapStoreError ¶
WrapStoreError creates a StoreError from a backend error.
Types ¶
type BulkStore ¶
type BulkStore interface {
// GetMany retrieves multiple values in a single operation.
// Returns a map of key -> Value. Missing keys are not included in the result.
GetMany(ctx context.Context, namespace string, keys []string) (map[string]Value, error)
// SetMany creates or updates multiple values in a single operation.
SetMany(ctx context.Context, namespace string, values map[string]Value) error
// DeleteMany removes multiple values in a single operation.
// Returns the number of entries actually deleted.
DeleteMany(ctx context.Context, namespace string, keys []string) (int64, error)
}
BulkStore is an optional interface for stores that support batch operations. Implementing this interface allows efficient bulk reads and writes.
type BulkWriteError ¶
type BulkWriteError struct {
// Errors maps keys to their specific errors. Only failed keys are included.
Errors map[string]error
// Succeeded contains keys that were written successfully.
Succeeded []string
}
BulkWriteError provides details about partial failures in bulk operations. Use KeyErrors() to see which keys failed and which succeeded.
func (*BulkWriteError) Error ¶
func (e *BulkWriteError) Error() string
func (*BulkWriteError) FailedKeys ¶
func (e *BulkWriteError) FailedKeys() []string
FailedKeys returns the list of keys that failed.
func (*BulkWriteError) KeyErrors ¶
func (e *BulkWriteError) KeyErrors() map[string]error
KeyErrors returns the map of key -> error for failed keys.
func (*BulkWriteError) Unwrap ¶
func (e *BulkWriteError) Unwrap() error
type CacheStats ¶
type CacheStats struct {
// Hits is the number of successful cache lookups.
Hits int64 `json:"hits"`
// Misses is the number of cache lookups that found no entry.
Misses int64 `json:"misses"`
// Size is the current number of entries in the cache.
Size int64 `json:"size"`
// Capacity is the maximum number of entries (0 = unbounded).
Capacity int64 `json:"capacity"`
// Evictions is the number of entries evicted due to capacity limits.
Evictions int64 `json:"evictions"`
}
CacheStats contains cache statistics.
func (*CacheStats) HitRate ¶
func (s *CacheStats) HitRate() float64
HitRate returns the cache hit rate as a percentage (0.0 to 1.0). Returns 0 if there have been no lookups.
type ChangeEvent ¶
type ChangeEvent struct {
// Type indicates the kind of change.
Type ChangeType
// Namespace is the namespace of the changed key.
Namespace string
// Key is the key that changed.
Key string
// Value is the new value (nil for Delete events).
Value Value
// Timestamp is when the change occurred.
Timestamp time.Time
}
ChangeEvent represents a configuration change notification.
type ChangeType ¶
type ChangeType int
ChangeType represents the type of configuration change.
const ( // ChangeTypeSet indicates a create or update operation. ChangeTypeSet ChangeType = iota // ChangeTypeDelete indicates a delete operation. ChangeTypeDelete )
func (ChangeType) String ¶
func (c ChangeType) String() string
String returns the string representation of the change type.
type CodecValidator ¶ added in v0.4.2
CodecValidator is an optional interface for stores that restrict supported codecs. Stores that do not implement this accept all codecs (backward compatible).
type Filter ¶
type Filter interface {
// Keys returns specific keys to retrieve (mutually exclusive with Prefix).
Keys() []string
// Prefix returns the prefix to match (mutually exclusive with Keys).
Prefix() string
// Limit returns the maximum number of results (0 = no limit).
Limit() int
// Cursor returns the pagination cursor (entry ID) for continuing from a previous result.
Cursor() string
}
Filter defines criteria for listing configuration entries. Use NewFilter() to create a FilterBuilder and construct filters.
Filters support two mutually exclusive modes:
- Keys mode: retrieve specific keys by exact match
- Prefix mode: retrieve all keys matching a prefix
Example:
// Get specific keys
filter := config.NewFilter().WithKeys("db/host", "db/port").Build()
// Get all keys with prefix
filter := config.NewFilter().WithPrefix("db/").WithLimit(100).Build()
// Paginate with cursor
page, _ := cfg.Find(ctx, config.NewFilter().WithPrefix("").WithLimit(50).Build())
nextPage, _ := cfg.Find(ctx, config.NewFilter().WithPrefix("").WithLimit(50).WithCursor(page.NextCursor()).Build())
type FilterBuilder ¶
type FilterBuilder struct {
// contains filtered or unexported fields
}
FilterBuilder builds Filter instances using a fluent API.
func (*FilterBuilder) WithCursor ¶
func (b *FilterBuilder) WithCursor(cursor string) *FilterBuilder
WithCursor sets the pagination cursor for continuing from a previous result.
func (*FilterBuilder) WithKeys ¶
func (b *FilterBuilder) WithKeys(keys ...string) *FilterBuilder
WithKeys sets specific keys to retrieve. Cannot be used with WithPrefix - calling this clears any prefix.
func (*FilterBuilder) WithLimit ¶
func (b *FilterBuilder) WithLimit(limit int) *FilterBuilder
WithLimit sets the maximum number of results.
func (*FilterBuilder) WithPrefix ¶
func (b *FilterBuilder) WithPrefix(prefix string) *FilterBuilder
WithPrefix sets a prefix to match keys. Cannot be used with WithKeys - calling this clears any keys.
type HealthChecker ¶
type HealthChecker interface {
// Health performs a health check on the store.
// Returns nil if healthy, or an error describing the issue.
Health(ctx context.Context) error
}
HealthChecker is an optional interface for stores that support health checks.
type InvalidKeyError ¶
InvalidKeyError provides details about an invalid key.
func (*InvalidKeyError) Error ¶
func (e *InvalidKeyError) Error() string
func (*InvalidKeyError) Unwrap ¶
func (e *InvalidKeyError) Unwrap() error
type KeyExistsError ¶
KeyExistsError provides details about a key that already exists.
func (*KeyExistsError) Error ¶
func (e *KeyExistsError) Error() string
func (*KeyExistsError) Unwrap ¶
func (e *KeyExistsError) Unwrap() error
type KeyNotFoundError ¶
KeyNotFoundError provides details about a missing key.
func (*KeyNotFoundError) Error ¶
func (e *KeyNotFoundError) Error() string
func (*KeyNotFoundError) Unwrap ¶
func (e *KeyNotFoundError) Unwrap() error
type Manager ¶
type Manager interface {
// Connect establishes connection to the backend and starts watching.
// Must be called before any other operations.
Connect(ctx context.Context) error
// Close stops watching and releases resources.
Close(ctx context.Context) error
// Namespace returns a Config for the specified namespace.
// Use "" for the default namespace.
Namespace(name string) Config
// Refresh forces a cache refresh for a specific key.
Refresh(ctx context.Context, namespace, key string) error
// Health performs a health check on the manager and underlying store.
// Returns nil if healthy, or an error describing the issue.
// Includes watch status - returns an error if watch has consecutive failures.
Health(ctx context.Context) error
}
Manager manages configuration across namespaces.
The Manager wraps a Store with caching and automatic cache invalidation. It provides access to namespaced configuration via the Namespace method.
Example:
// Create manager
mgr := config.New(
config.WithStore(memory.NewStore()),
)
// Connect to backend
if err := mgr.Connect(ctx); err != nil {
return err
}
defer mgr.Close(ctx)
// Get configuration for a namespace (use "" for default)
prodConfig := mgr.Namespace("production")
// Use Reader interface in application code
val, err := prodConfig.Get(ctx, "app/database/timeout")
if err != nil {
return err
}
var timeout int
if err := val.Unmarshal(&timeout); err != nil {
return err
}
// Use Writer interface for management
if err := prodConfig.Set(ctx, "app/database/timeout", 30); err != nil {
return err
}
func ContextManager ¶
ContextManager retrieves the Manager from context. Returns nil if no manager is set.
func New ¶
New creates a new configuration Manager.
The manager is created but not connected. Call Connect() before use. This follows the New/Connect split pattern for better error handling.
The manager always maintains an internal cache for resilience. If the backend store becomes temporarily unavailable, cached values will continue to be served. This ensures your application keeps working during database outages.
Returns an error if cache initialization fails.
Example ¶
package main
import (
"context"
"fmt"
"github.com/rbaliyan/config"
"github.com/rbaliyan/config/memory"
)
func main() {
ctx := context.Background()
// Create a manager with an in-memory store
mgr, err := config.New(config.WithStore(memory.NewStore()))
if err != nil {
fmt.Println("Error:", err)
return
}
// Connect to the backend
if err := mgr.Connect(ctx); err != nil {
fmt.Println("Error:", err)
return
}
defer mgr.Close(ctx)
// Get a namespaced config and set a value
cfg := mgr.Namespace("production")
if err := cfg.Set(ctx, "app/timeout", 30); err != nil {
fmt.Println("Error:", err)
return
}
// Read the value back
val, err := cfg.Get(ctx, "app/timeout")
if err != nil {
fmt.Println("Error:", err)
return
}
i, _ := val.Int64()
fmt.Println("timeout:", i)
}
Output: timeout: 30
type ManagerObserver ¶
type ManagerObserver interface {
// CacheStats returns statistics about the internal cache.
CacheStats() CacheStats
// WatchStatus returns the current status of the watch connection.
WatchStatus() WatchStatus
}
ManagerObserver provides observability into the Manager's internal state. Use a type assertion to access these methods:
if obs, ok := mgr.(config.ManagerObserver); ok {
stats := obs.CacheStats()
status := obs.WatchStatus()
}
type Metadata ¶
type Metadata interface {
// Version returns the version number of the value.
Version() int64
// CreatedAt returns when the value was first created.
CreatedAt() time.Time
// UpdatedAt returns when the value was last modified.
UpdatedAt() time.Time
// IsStale returns true if this value was served from cache due to a store error.
// When true, the value may be outdated. Applications can use this to:
// - Log warnings about stale data
// - Show degraded UI indicators
// - Trigger background refresh
IsStale() bool
}
Metadata provides version and timestamp information for stored values.
type Option ¶
type Option func(*managerOptions)
Option configures the Manager.
func WithCodec ¶
WithCodec sets the default codec for encoding/decoding values. Default is JSON if not specified.
func WithStore ¶
WithStore sets the configuration store backend. This is required - the manager will fail to connect without a store.
func WithWatchBackoffFactor ¶ added in v0.1.12
WithWatchBackoffFactor sets the multiplier applied to backoff after each watch failure. Default: 2.0.
func WithWatchInitialBackoff ¶ added in v0.1.12
WithWatchInitialBackoff sets the initial wait time between watch reconnection attempts. Default: 100ms.
func WithWatchMaxBackoff ¶ added in v0.1.12
WithWatchMaxBackoff sets the maximum wait time between watch reconnection attempts. Default: 30s.
type Page ¶
type Page interface {
// Results returns the values in this page as a map of key -> Value.
Results() map[string]Value
// NextCursor returns the cursor for fetching the next page.
// This is typically the last key in the results.
NextCursor() string
// Limit returns the actual limit used by the server.
// The server may adjust the requested limit. Clients should check
// len(Results()) < Limit() to determine if there are more results.
Limit() int
}
Page represents a page of results from a Find operation. It provides access to the results and pagination information.
Example usage for pagination:
limit := 100
filter := config.NewFilter().WithPrefix("app/").WithLimit(limit).Build()
for {
page, err := cfg.Find(ctx, filter)
if err != nil {
return err
}
for key, val := range page.Results() {
// Process each entry
}
// No more results if returned count < limit
if len(page.Results()) < page.Limit() {
break
}
filter = config.NewFilter().WithPrefix("app/").WithLimit(limit).WithCursor(page.NextCursor()).Build()
}
type Reader ¶
type Reader interface {
// Get retrieves a configuration value by key.
//
// Get uses an internal cache for resilience. If the store is unavailable,
// it will return a cached value if one exists. This is intentional - for
// use cases like feature flags and rate limits, having slightly stale
// configuration is better than failing completely.
Get(ctx context.Context, key string) (Value, error)
// Find returns a page of keys and values matching the filter.
// Use Page.NextCursor() to paginate through results.
Find(ctx context.Context, filter Filter) (Page, error)
}
Reader provides read-only access to configuration. Use this interface in application code to read config values.
The Reader automatically uses an internal cache for resilience. If the backend store is temporarily unavailable, cached values will be returned. This ensures your application continues working even during database outages.
type SetOption ¶
type SetOption func(*setOptions)
SetOption configures Set operations.
func WithIfExists ¶
func WithIfExists() SetOption
WithIfExists configures Set to only update the key if it already exists. Returns ErrNotFound if the key doesn't exist.
This is useful for implementing "update-only" semantics where you want to ensure the key was previously created.
Example:
err := cfg.Set(ctx, "app/timeout", 60, config.WithIfExists())
if config.IsNotFound(err) {
// Key doesn't exist, need to create it first
}
func WithIfNotExists ¶
func WithIfNotExists() SetOption
WithIfNotExists configures Set to only create the key if it doesn't exist. Returns ErrKeyExists if the key already exists.
This is useful for implementing "create-only" semantics where you want to ensure you don't accidentally overwrite an existing value.
Example:
err := cfg.Set(ctx, "lock/owner", "instance-1", config.WithIfNotExists())
if config.IsKeyExists(err) {
// Key was already taken by another instance
}
func WithSetCodec ¶
WithSetCodec sets the codec for encoding the value.
type StatsProvider ¶
type StatsProvider interface {
// Stats returns store statistics.
Stats(ctx context.Context) (*StoreStats, error)
}
StatsProvider is an optional interface for stores that provide statistics.
type Store ¶
type Store interface {
// Connect establishes connection to the storage backend.
// Must be called before any other operations.
Connect(ctx context.Context) error
// Close releases resources and closes the connection.
Close(ctx context.Context) error
// Get retrieves a configuration value by namespace and key.
// Returns ErrNotFound if the entry does not exist.
Get(ctx context.Context, namespace, key string) (Value, error)
// Set creates or updates a configuration value.
// The version is auto-incremented on each update.
// Returns the stored Value with updated metadata (version, timestamps).
Set(ctx context.Context, namespace, key string, value Value) (Value, error)
// Delete removes a configuration value by namespace and key.
// Returns ErrNotFound if the entry does not exist.
Delete(ctx context.Context, namespace, key string) error
// Find returns a page of keys and values matching the filter within a namespace.
// Use Page.NextCursor() to paginate through results.
Find(ctx context.Context, namespace string, filter Filter) (Page, error)
// Watch returns a channel that receives change events for cache invalidation.
// The channel is closed when the context is cancelled.
// This is used by the Manager for automatic cache synchronization.
// For stores that don't support real-time watching (e.g., file-based),
// return ErrWatchNotSupported.
Watch(ctx context.Context, filter WatchFilter) (<-chan ChangeEvent, error)
}
Store defines the interface for configuration storage backends.
Implementations must be safe for concurrent use by multiple goroutines. The store is responsible for persistence and versioning.
Design Philosophy ¶
This library is designed for use cases like feature flags, rate limits, and dynamic configuration where eventual consistency is acceptable. The key principle is: having some configuration (even slightly stale) is better than having no configuration at all.
The library maintains an internal in-memory cache that serves as a resilience layer. If the backend store becomes temporarily unavailable, the application can continue operating with cached values. This cache is NOT meant for sharing state across multiple application instances - each instance maintains its own cache that is kept in sync with the backend via the store's Watch mechanism.
For multi-instance deployments, each instance independently watches the backend (e.g., MongoDB Change Streams, PostgreSQL LISTEN/NOTIFY) to invalidate its local cache. This provides eventual consistency without requiring external dependencies like Redis.
Implementations:
- memory.Store: For testing and single-instance deployments
- mongodb.Store: For MongoDB databases (uses Change Streams internally)
- postgres.Store: For PostgreSQL databases (uses LISTEN/NOTIFY internally)
type StoreError ¶
type StoreError struct {
Op string // Operation that failed
Key string // Key involved (if applicable)
Backend string // Backend name (memory, mongodb, postgres)
Err error // Underlying error
}
StoreError wraps backend-specific errors with domain context.
func (*StoreError) Error ¶
func (e *StoreError) Error() string
func (*StoreError) Unwrap ¶
func (e *StoreError) Unwrap() error
type StoreStats ¶
type StoreStats struct {
TotalEntries int64 `json:"total_entries"`
EntriesByType map[Type]int64 `json:"entries_by_type"`
EntriesByNamespace map[string]int64 `json:"entries_by_namespace"`
}
StoreStats contains storage statistics.
type Type ¶
type Type int
Type represents the type of a configuration value.
const ( // TypeUnknown indicates an unknown or unsupported type. TypeUnknown Type = iota // TypeInt represents an integer value. TypeInt // TypeFloat represents a floating-point value. TypeFloat // TypeString represents a string value. TypeString // TypeBool represents a boolean value. TypeBool // TypeMapStringInt represents a map[string]int value. TypeMapStringInt // TypeMapStringFloat represents a map[string]float64 value. TypeMapStringFloat // TypeMapStringString represents a map[string]string value. TypeMapStringString // TypeListInt represents a []int value. TypeListInt // TypeListFloat represents a []float64 value. TypeListFloat // TypeListString represents a []string value. TypeListString // TypeCustom represents a custom type that requires Unmarshal. TypeCustom )
func ParseType ¶
ParseType parses a string into a Type. Returns TypeUnknown for unrecognized strings.
func (Type) IsPrimitive ¶
IsPrimitive returns true if the type is a primitive (int, float, string, bool).
type TypeMismatchError ¶
TypeMismatchError provides details about a type conversion failure.
func (*TypeMismatchError) Error ¶
func (e *TypeMismatchError) Error() string
func (*TypeMismatchError) Unwrap ¶
func (e *TypeMismatchError) Unwrap() error
type UnsupportedCodecError ¶ added in v0.4.2
UnsupportedCodecError provides details about a codec that is not supported by the store.
func (*UnsupportedCodecError) Error ¶ added in v0.4.2
func (e *UnsupportedCodecError) Error() string
func (*UnsupportedCodecError) Unwrap ¶ added in v0.4.2
func (e *UnsupportedCodecError) Unwrap() error
type Value ¶
type Value interface {
// Marshal serializes the value to bytes using the configured codec.
Marshal() ([]byte, error)
// Unmarshal deserializes the value into the target.
Unmarshal(v any) error
// Type returns the detected type of the value.
Type() Type
// Codec returns the codec name used for this value.
Codec() string
// Int64 returns the value as int64.
Int64() (int64, error)
// Float64 returns the value as float64.
Float64() (float64, error)
// String returns the value as string.
String() (string, error)
// Bool returns the value as bool.
Bool() (bool, error)
// Metadata returns associated metadata, if any.
Metadata() Metadata
}
Value provides type-safe access to configuration values. This interface is focused on read operations. Write-related concerns like WriteMode are accessed via the WriteModer interface.
func Get ¶
Get is a convenience function that retrieves a value using the Manager from context. Returns ErrManagerClosed if no manager is in context. Uses the namespace from context, or "" (default) if not set.
func MarkStale ¶
MarkStale returns a copy of the value with the stale flag set. This is used when serving cached values due to store errors. The returned value's Metadata().IsStale() will return true.
func NewValue ¶
func NewValue(data any, opts ...ValueOption) Value
NewValue creates a Value from any data with optional configuration.
Example ¶
package main
import (
"fmt"
"github.com/rbaliyan/config"
)
func main() {
// Create a value and inspect its type
val := config.NewValue(42)
fmt.Println("type:", val.Type())
i, err := val.Int64()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("value:", i)
}
Output: type: int value: 42
func NewValueFromBytes ¶
func NewValueFromBytes(data []byte, codecName string, opts ...ValueOption) (Value, error)
NewValueFromBytes creates a Value from encoded bytes.
type ValueOption ¶
type ValueOption func(*val)
ValueOption configures a value during construction.
func WithValueCodec ¶
func WithValueCodec(c codec.Codec) ValueOption
WithCodec sets the codec for the value.
func WithValueEntryID ¶
func WithValueEntryID(id string) ValueOption
WithValueEntryID sets the internal entry ID for the value. This is used by store implementations to track the database-level ID. Not intended for end-user code.
func WithValueMetadata ¶
func WithValueMetadata(version int64, createdAt, updatedAt time.Time) ValueOption
WithValueMetadata sets metadata for the value.
func WithValueStale ¶
func WithValueStale(stale bool) ValueOption
WithValueStale marks the value as stale (served from cache due to store error). This is used internally by the Manager when falling back to cached values.
func WithValueType ¶
func WithValueType(t Type) ValueOption
WithValueType sets the type for the value.
func WithValueWriteMode ¶
func WithValueWriteMode(mode WriteMode) ValueOption
WithValueWriteMode sets the write mode for the value.
type WatchFilter ¶
type WatchFilter struct {
// Namespaces to watch (empty = all namespaces).
Namespaces []string
// Prefixes to watch within namespaces (empty = all keys).
Prefixes []string
}
WatchFilter specifies criteria for watching changes.
type WatchHealthError ¶
WatchHealthError provides details about watch connection failures. Returned by Manager.Health() when watch has multiple consecutive failures.
func (*WatchHealthError) Error ¶
func (e *WatchHealthError) Error() string
func (*WatchHealthError) Unwrap ¶
func (e *WatchHealthError) Unwrap() error
type WatchStatus ¶
type WatchStatus struct {
// Connected indicates if the manager is connected to the store.
Connected bool `json:"connected"`
// ConsecutiveFailures is the number of consecutive watch failures.
// Resets to 0 when watch successfully connects.
ConsecutiveFailures int32 `json:"consecutive_failures"`
// LastError is the most recent watch error message (empty if no error).
LastError string `json:"last_error,omitempty"`
// LastAttempt is when the last watch connection was attempted.
LastAttempt time.Time `json:"last_attempt,omitempty"`
// Cache contains cache statistics for correlation with watch health.
Cache CacheStats `json:"cache"`
}
WatchStatus provides observability into the watch connection state. Applications can use this to monitor watch health and implement their own alerting or circuit breaking logic if needed.
type WriteMode ¶
type WriteMode int
WriteMode specifies the conditional behavior for Set operations.
const ( // WriteModeUpsert creates or updates the key (default behavior). WriteModeUpsert WriteMode = iota // WriteModeCreate only creates the key if it doesn't exist. // Returns ErrKeyExists if the key already exists. WriteModeCreate // WriteModeUpdate only updates the key if it already exists. // Returns ErrNotFound if the key doesn't exist. WriteModeUpdate )
func GetWriteMode ¶
GetWriteMode extracts the write mode from a Value. Returns WriteModeUpsert (default) if the value does not implement WriteModer. Store implementations should use this instead of calling WriteMode() directly.
type WriteModer ¶
type WriteModer interface {
WriteMode() WriteMode
}
WriteModer is an optional interface for values that carry write mode hints. Store implementations check for this interface in Set operations to determine conditional write behavior (create-only, update-only, or upsert).
type Writer ¶
type Writer interface {
// Set creates or updates a configuration value.
Set(ctx context.Context, key string, value any, opts ...SetOption) error
// Delete removes a configuration value by key.
Delete(ctx context.Context, key string) error
}
Writer provides write access to configuration. Use this interface for gRPC/HTTP servers to manage config.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package bind provides struct binding and validation for the config library.
|
Package bind provides struct binding and validation for the config library. |
|
json
Package json provides a JSON codec for the config library.
|
Package json provides a JSON codec for the config library. |
|
toml
Package toml provides a TOML codec for the config library.
|
Package toml provides a TOML codec for the config library. |
|
yaml
Package yaml provides a YAML codec for the config library.
|
Package yaml provides a YAML codec for the config library. |
|
Package file provides file-based configuration loading and a read-only config.Store backed by YAML, TOML, or JSON files.
|
Package file provides file-based configuration loading and a read-only config.Store backed by YAML, TOML, or JSON files. |
|
Package memory provides an in-memory configuration store for testing and single-instance deployments.
|
Package memory provides an in-memory configuration store for testing and single-instance deployments. |
|
Package mongodb provides a MongoDB-backed configuration store with change stream notifications.
|
Package mongodb provides a MongoDB-backed configuration store with change stream notifications. |
|
Package multi provides a multi-store wrapper that supports fallback patterns.
|
Package multi provides a multi-store wrapper that supports fallback patterns. |
|
Package otel provides OpenTelemetry instrumentation for the config library.
|
Package otel provides OpenTelemetry instrumentation for the config library. |
|
Package postgres provides a PostgreSQL-backed configuration store with LISTEN/NOTIFY change notifications.
|
Package postgres provides a PostgreSQL-backed configuration store with LISTEN/NOTIFY change notifications. |
|
Package sqlite provides a SQLite-backed configuration store with application-level change notifications.
|
Package sqlite provides a SQLite-backed configuration store with application-level change notifications. |