Files
David ReissandGitHub 2a38f9584b Dynamic config conversion improvements (#7052)
## What changed?
- Split implementation of "constrained default" settings from "plain
default" settings. This is more code and the diff looks complex, but the
individual paths are both simpler than the mixed version.
- Add conversion cache using a weak map.
- Remove GlobalCachedTypedValue.
- Use "raw" values for subscription dispatch deduping to avoid
unnecessary conversions.
- Deep copy default values when using mapstructure, to avoid problems
with merging over shared default values.

## Why?
- Fixes #6756
- Performance improvement for "plain default" settings (almost all of
them)
- Performance improvement for settings with complex converters
- Remove footgun in defaults that aren't scalar values

## How did you test it?
existing+new unit tests
2025-08-08 08:32:58 -07:00

51 lines
2.0 KiB
Go

//go:generate go run ../../cmd/tools/gendynamicconfig
package dynamicconfig
type (
// Precedence is an enum for the search order precedence of a dynamic config setting.
// E.g., use the global value, check namespace then global, check task queue then
// namespace then global, etc.
Precedence int
// setting is one dynamic config setting. setting should not be used or created directly,
// but use one of the generated constructors for instantiated Setting types in
// setting_gen.go, e.g. NewNamespaceBoolSetting.
// T is the data type of the setting. P is a go type representing the precedence, which is
// just used to make the types more unique.
setting[T any, P any] struct {
key Key // string value of key. case-insensitive.
def T // default value
convert func(any) (T, error) // converter function
description string // documentation
}
constrainedDefaultSetting[T any, P any] struct {
key Key // string value of key. case-insensitive.
cdef []TypedConstrainedValue[T] // default values
convert func(any) (T, error) // converter function
description string // documentation
}
// GenericSetting is an interface that all instances of Setting implement (by generated
// code in setting_gen.go). It can be used to refer to settings of any type and deal with
// them generically..
GenericSetting interface {
Key() Key
Precedence() Precedence
Validate(v any) error
// for internal use:
dispatchUpdate(*Collection, any, []ConstrainedValue)
}
// GenericParseHook is an interface that may be implemented by a setting type or a field
// contained inside a struct setting type.
// It should be implemented with a non-pointer receiver that will be ignored, and return
// the parsed value and any parse error.
// Type "S" is usually "string", and "T" must be the same as the receiver type.
GenericParseHook[S, T any] interface {
DynamicConfigParseHook(S) (T, error)
}
)