Documentation
¶
Index ¶
- func StringValueMap[T ~string](in ...T) map[string]T
- func StringerValueMap[T fmt.Stringer](in ...T) map[string]T
- type CfgSerial
- type Decoder
- type Dials
- func (d *Dials[T]) EnableVerification(ctx context.Context) (*T, CfgSerial[T], error)
- func (d *Dials[T]) Events() <-chan *T
- func (d *Dials[T]) Fill(blankConfig *T)deprecated
- func (d *Dials[T]) RegisterCallback(ctx context.Context, serial CfgSerial[T], cb NewConfigHandler[T]) UnregisterCBFunc
- func (d *Dials[T]) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (d *Dials[T]) View() *T
- func (d *Dials[T]) ViewVersion() (*T, CfgSerial[T])
- type Enum
- type EnumValuable
- type ErrInvalidEnumValue
- type FuzzyEnum
- type FuzzyEnumComparer
- type NewConfigHandler
- type Params
- type Source
- type Type
- type UnregisterCBFunc
- type ValueMap
- type VerifiedConfig
- type WatchArgs
- type WatchedErrorHandler
- type Watcher
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StringValueMap ¶ added in v1.20.0
StringValueMap is a helper that converts string-ish typed-enums to the mapping table expected by the ValueMap interface.
func StringerValueMap ¶ added in v1.20.0
StringerValueMap is a helper that converts types that implement the fmt.Stringer interface to the mapping table expected by the ValueMap interface.
Types ¶
type CfgSerial ¶
type CfgSerial[T any] struct { // contains filtered or unexported fields }
CfgSerial is an opaque object unique to a config-version
type Decoder ¶
Decoder interface is implemented by different data formats to read the config files, decode the data, and insert the values in the config struct. Dials currently includes implementations for YAML, JSON, and TOML data formats.
type Dials ¶
type Dials[T any] struct { // contains filtered or unexported fields }
Dials is the main access point for your configuration.
func Config ¶
Config populates the passed in config struct by reading the values from the different Sources. The order of the sources denotes the precedence of the formats so the last source passed to the function has the ability to override fields that were set by previous sources This top-level function is present for convenience and backwards compatibility when there is no need to specify an error-handler.
func (*Dials[T]) EnableVerification ¶ added in v0.11.0
EnableVerification enables verification on dials if DelayInitialVerification was set on the Params struct. Returns the config that was verified and a CfgSerial or the error from calling Verify() (if the config type implements VerifiedConfig.
If DelayInitialVerification is not set, returns successfully without verifying the config.
If verification succeeds on the currently installed configuration, all subsequent configuration versions will be verified. (based on re-stacking versions from watching sources)
When there are watching sources (including Blank) the global callbacks may be suppressed with the Params.CallGlobalCallbacksAfterVerificationEnabled option. This suppression expires after verification is re-enabled by this method.
Note: if the context expires while this call is awaiting a response from the background "monitor" goroutine, verification may still happen, but whether it transitions out of the delayed verification state is indeterminate.
func (*Dials[T]) Events ¶
func (d *Dials[T]) Events() <-chan *T
Events returns a channel that will get a message every time the configuration is updated.
NOTE: In general, it is preferable to register a callback with Dials.RegisterCallback, due to a cleaner interface and the ability to register multiple callbacks. Additionally, NewConfigHandler implementations get both the old and new configs, reducing the amount of state required to handle new events.
func (*Dials[T]) RegisterCallback ¶
func (d *Dials[T]) RegisterCallback(ctx context.Context, serial CfgSerial[T], cb NewConfigHandler[T]) UnregisterCBFunc
RegisterCallback registers the callback cb to receive notifications whenever a new configuration is installed. If the "current" version is later than the one represented by the value of CfgSerial, a notification will be delivered immediately. This call is only blocking if the callback handling has filled up an internal channel. (likely because an already-registered callback is slow or blocking) serial must be obtained from Dials.ViewVersion(). Catch-up callbacks are suppressed if passed passed an invalid CfgSerial (including the zero-value)
Just like global callbacks, NewConfigHandler implementations execute serially on a single goroutine. As a result:
- callbacks will see config versions in the order they're installed
- the callbacks _may_ block, but only for time intervals that are short compared to the interval between updates.
May return a nil UnregisterCBFunc if the context expires
The returned UnregisterCBFunc will block until the relevant callback has been removed from the set of callbacks.
Example ¶
// setup a cancelable context so the monitor goroutine gets shutdown.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
type testConfig struct {
Foo string
}
type ptrifiedConfig struct {
Foo *string
}
base := testConfig{
Foo: "foo",
}
// Push a new value, that should overlay on top of the base
foozleStr := "foozle"
foozleConfig := ptrifiedConfig{
Foo: &foozleStr,
}
w := fakeWatchingSource{fakeSource: fakeSource{outVal: foozleConfig}}
d, dialsErr := Config(ctx, &base, &w)
if dialsErr != nil {
panic("unexpected error: " + dialsErr.Error())
}
cfg, serialToken := d.ViewVersion()
fmt.Printf("Foo: %s\n", cfg.Foo)
unregCB := d.RegisterCallback(ctx, serialToken, func(ctx context.Context, oldCfg, newCfg *testConfig) {
panic("not getting called this time")
})
unregCB(ctx)
Output: Foo: foozle
func (*Dials[T]) ServeHTTP ¶ added in v1.19.0
func (d *Dials[T]) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP is only active if [Params.EnableStatusPage] was set to true when creating the dials instance.
This is experimental and may panic while serving, buyer beware!!!
It is heavily recommended that users of this functionality set `statuspage:"-"` tags on any sensitive fields with secrets/credentials, etc.
func (*Dials[T]) View ¶
func (d *Dials[T]) View() *T
View returns the configuration struct populated.
func (*Dials[T]) ViewVersion ¶
ViewVersion returns the configuration struct populated, and an opaque token.
type Enum ¶ added in v1.20.0
type Enum[T ValueMap[T]] struct { Value T }
Enum allows you to treat a certain type like an enumeration. Enums are integrated into the flags packages to automatically amend the `Usage` text to include all allowed values.
func EnumValue ¶ added in v1.20.0
EnumValue is a helper that's particularly useful when setting enum defaults in configuration.
func (Enum[T]) AllowedEnumValues ¶ added in v1.20.0
AllowedEnumValues implements the EnumValuable interface.
func (*Enum[T]) UnmarshalText ¶ added in v1.20.0
UnmarshalText implements encoding.TextUnmarshaler so that we can map from strings to our typed enum. If there is no appropriate mapping, ErrInvalidEnumValue is returned.
type EnumValuable ¶ added in v1.20.0
type EnumValuable interface {
AllowedEnumValues() []string
}
EnumValuable is an interface that is useful to get all the allowed enum values as strings. It is used by the flag packages to adjust the usage text to include all available values.
type ErrInvalidEnumValue ¶ added in v1.20.0
type ErrInvalidEnumValue struct {
// All the allowed inputs.
Allowed []string
// The input that was provided (not in the Allowed list).
Input string
// true if the comparison is case-insensitive.
Fuzzy bool
}
ErrInvalidEnumValue is an error that is returned when there is no mapping for a particular value in the enumeration.
func (*ErrInvalidEnumValue) Error ¶ added in v1.20.0
func (e *ErrInvalidEnumValue) Error() string
Error implements the error interface.
type FuzzyEnum ¶ added in v1.20.0
type FuzzyEnum[T ValueMap[T]] struct { Value T }
FuzzyEnum is just like an Enum, but does case-insensitive comparisons. Just like Enums, FuzzyEnums are integrated into the flags packages to automatically amend the `Usage` text to include all allowed values and will also indicate that the matching is case-insensitive.
func (FuzzyEnum[T]) AllowedEnumValues ¶ added in v1.20.0
AllowedEnumValues implements the EnumValuable interface.
func (*FuzzyEnum[T]) UnmarshalText ¶ added in v1.20.0
UnmarshalText implements encoding.TextUnmarshaler and does a case-insensitive comparison of the string to map back to the appropriate value from the enumeration. If there is no appropriate mapping, ErrInvalidEnumValue is returned.
type FuzzyEnumComparer ¶ added in v1.20.0
type FuzzyEnumComparer interface {
// contains filtered or unexported methods
}
FuzzyEnumComparer is an interface that allows us to detect that case-insensitive comparison has been used.
type NewConfigHandler ¶
NewConfigHandler is a callback that's called after a new config is installed. Callbacks are run on a dedicated Goroutine, so one can do expensive/blocking work in this callback, however, execution should not last longer than the interval between new configs.
type Params ¶
type Params[T any] struct { // OnWatchedError is called when either of several conditions are met: // - There is an error re-stacking the configuration // - One of the Sources implementing the Watcher interface reports an error // - a Verify() method fails after re-stacking when a new version is // provided by a watching source OnWatchedError WatchedErrorHandler[T] // SkipInitialVerification skips the initial call to `Verify()` on any // configurations that implement the [VerifiedConfig] interface. // // In cases where later updates from Watching sources are depended upon to // provide a configuration that will be allowed by Verify(), one should set // this to true. See `sourcewrap.Blank` for more details. // // Unlike DelayInitialVerification, this field only skips the initial Verify() // call, so all watching sources (including Blank) trigger configuration // verification. SkipInitialVerification bool // OnNewConfig is called when a new (valid) configuration is installed. // // OnNewConfig runs on the same "callback" goroutine as the // OnWatchedError callback, with callbacks being executed in-order. // In the event that a call to OnNewConfig blocks too long, some calls // may be dropped. OnNewConfig NewConfigHandler[T] // DelayInitialVerification skips calls to Verify() until the EnableVerification() // method is called. // // Some systems require coalescing the data from multiple Sources, which require // initialization parameters from other sources (e.g. filenames). // // Notably, many use-cases involving sourcewrap.Blank may require multiple steps // to initialize, during which time the configuration will be incomplete and may // not validate. DelayInitialVerification bool // CallGlobalCallbacksAfterVerificationEnabled suppresses calling any registered // global while in the delayed-verification mode. // // In particular, global callbacks (those registered in this struct) are // suppressed under two conditions: // - DelayInitialVerification was set to true when Config was called // - EnableVerification has not been called (without it returning an error) CallGlobalCallbacksAfterVerificationEnabled bool // If enabled, Dials will retain the slice of reported source-values so // it can render a status page using [github.com/vimeo/go-status-page] // // This feature is experimental and go-status-page may generate panics // while rendering pages. // // It is heavily recommended that users of this functionality set // `statuspage:"-"` tags on any sensitive fields with secrets/credentials, etc. EnableStatusPage bool }
Params provides options for setting Dials's behavior in some cases.
func (Params[T]) Config ¶
Config populates the passed in config struct by reading the values from the different Sources. The order of the sources denotes the precedence of the formats so the last source passed to the function has the ability to override fields that were set by previous sources
If present, a Verify() method will be called after each stacking attempt. Blocking/expensive work should not be done in this method. (see the comment on Verify()) in VerifiedConfig for details)
If complicated/blocking initialization/verification is necessary, one can either:
- If not using any watching sources, do any verification with the returned config from Config.
- If using at least one watching source, configure a goroutine to watch the channel returned by the `Dials.Events()` method that does its own installation after verifying the config.
More complicated verification/initialization should be done by consuming from the channel returned by `Events()`.
type Source ¶
type Source interface {
// Value provides the current value for the configuration.
// Value methods should not create any long-lived resources or spin off
// long-lived goroutines.
// Config() will cancel the context passed to this method upon Config's
// return.
// Implementations that need to handle state changes with long-lived
// background goroutines should implement the Watcher interface, which
// explicitly provides a way to supply state updates.
Value(context.Context, *Type) (reflect.Value, error)
}
Source interface is implemented by each configuration source that is used to populate the config struct such as environment variables, command line flags, config files, and more
type Type ¶
type Type struct {
// contains filtered or unexported fields
}
Type is a wrapper for a reflect.Type.
type UnregisterCBFunc ¶
UnregisterCBFunc unregisters a callback from the dials object it was registered with.
type ValueMap ¶ added in v1.20.0
ValueMap provides a mapping from a string to a type of your choice to be used like an enum. Users should implement the `DialsValueMap()` method to provide all possible mappings values. Any values not in the mapping will fail when unmarshaling.
type VerifiedConfig ¶
type VerifiedConfig interface {
// Verify() should return a non-nil error if the configuration is
// invalid.
// As this method is called any time the configuration sources are
// restacked, it should not do any complex or blocking work.
Verify() error
}
VerifiedConfig implements the Verify method, allowing Dials to execute the Verify method before returning/installing a new version of the configuration.
type WatchArgs ¶
type WatchArgs interface {
// ReportNewValue reports a new value. The base implementation returns an
// error if the internal reporting channel is full and the context
// expires/is-canceled, however, wrapping implementations are free to
// return any other error as appropriate.
ReportNewValue(ctx context.Context, val reflect.Value) error
// Done indicates that this watcher has stopped and will not send any
// more updates.
Done(ctx context.Context)
// ReportError reports a problem in the watcher. Returns an error if
// the internal reporting channel is full and the context
// expires/is-canceled.
ReportError(ctx context.Context, err error) error
// BlockingReportNewValue reports a new value. Returns an error if the internal
// reporting channel is full and the context expires/is-canceled.
// Blocks until the new value has been or returns an error.
//
// Most Source implementations should use ReportNewValue(). This was added to
// support [github.com/vimeo/dials/sourcewrap.Blank]. This should only be used
// in similar cases.
BlockingReportNewValue(ctx context.Context, val reflect.Value) error
}
WatchArgs provides methods for a Watcher implementation to update the state of a Dials instance.
type WatchedErrorHandler ¶
WatchedErrorHandler is a callback that's called when something fails when dials is operating in a watching mode. If non-nil, both oldConfig and newConfig are guaranteed to be populated with the same pointer-type that was passed to Config(). newConfig will be nil for errors that prevent stacking.
type Watcher ¶
type Watcher interface {
// Watch will be called in the primary goroutine calling Config(). If
// Watcher implementations need a persistent goroutine, they should
// spawn it themselves.
Watch(context.Context, *Type, WatchArgs) error
}
Watcher should be implemented by Sources that allow their configuration to be watched for changes.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package common provides constants that are used among different dials sources
|
Package common provides constants that are used among different dials sources |
|
decoders
|
|
|
json/jsontypes
Package jsontypes contains helper types used by the JSON and Cue decoders to facilitate more natural decoding.
|
Package jsontypes contains helper types used by the JSON and Cue decoders to facilitate more natural decoding. |
|
sources
|
|