Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions cmd/tools/gendynamicconfig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,11 @@ func generateType(w io.Writer, tp *settingType, prec *settingPrecedence) {
writeTemplatedCode(w, `
{{ if .T.IsGeneric -}}
type {{.P.Name}}TypedSetting[T any] setting[T, func({{.P.GoArgs}})]
type {{.P.Name}}TypedConstrainedDefaultSetting[T any] constrainedDefaultSetting[T, func({{.P.GoArgs}})]

// New{{.P.Name}}TypedSetting creates a setting that uses mapstructure to handle complex structured
// values. The value from dynamic config will be copied over a shallow copy of 'def', which means
// 'def' must not contain any non-nil slices, maps, or pointers.
// values. The value from dynamic config will be _merged_ over a deep copy of 'def'. Be very careful
// when using non-empty maps or slices as defaults, the result may not be what you want.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if we can runtime assert this and prevent unwanted defaults. It's really easy for devs to miss docstring comments and reviewers will likely not be aware of this detail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we should. I can add a task for it.

func New{{.P.Name}}TypedSetting[T any](key Key, def T, description string) {{.P.Name}}TypedSetting[T] {
s := {{.P.Name}}TypedSetting[T]{
key: key,
Expand All @@ -183,10 +184,10 @@ func New{{.P.Name}}TypedSettingWithConverter[T any](key Key, convert func(any) (
}

// New{{.P.Name}}TypedSettingWithConstrainedDefault creates a setting with a compound default value.
func New{{.P.Name}}TypedSettingWithConstrainedDefault[T any](key Key, convert func(any) (T, error), cdef []TypedConstrainedValue[T], description string) {{.P.Name}}TypedSetting[T] {
s := {{.P.Name}}TypedSetting[T]{
func New{{.P.Name}}TypedSettingWithConstrainedDefault[T any](key Key, convert func(any) (T, error), cdef []TypedConstrainedValue[T], description string) {{.P.Name}}TypedConstrainedDefaultSetting[T] {
s := {{.P.Name}}TypedConstrainedDefaultSetting[T]{
key: key,
cdef: &cdef,
cdef: cdef,
convert: convert,
description: description,
}
Expand All @@ -201,6 +202,13 @@ func (s {{.P.Name}}TypedSetting[T]) Validate(v any) error {
return err
}

func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) Key() Key { return s.key }
func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) Precedence() Precedence { return Precedence{{.P.Name}} }
func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) Validate(v any) error {
_, err := s.convert(v)
return err
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To save me from diving too much into details, how often is Validate() called? Can we save redundant calls to convert or is that not an issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this is only called when loading a new file, or from temporal-server validate-dynamic-config, so not very often.


func (s {{.P.Name}}TypedSetting[T]) WithDefault(v T) {{.P.Name}}TypedSetting[T] {
newS := s
newS.def = v
Expand All @@ -225,6 +233,22 @@ func (s {{.P.Name}}TypedSetting[T]) Get(c *Collection) TypedPropertyFnWith{{.P.N
c,
s.key,
s.def,
s.convert,
prec,
)
}
}

{{if eq .P.Name "Global" -}}
func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) Get(c *Collection) TypedPropertyFn[T] {
{{- else -}}
func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) Get(c *Collection) TypedPropertyFnWith{{.P.Name}}Filter[T] {
{{- end}}
return func({{.P.GoArgs}}) T {
prec := {{.P.Expr}}
return matchAndConvertWithConstrainedDefault(
c,
s.key,
s.cdef,
s.convert,
prec,
Expand All @@ -246,7 +270,7 @@ func (s {{.P.Name}}TypedSetting[T]) Subscribe(c *Collection) TypedSubscribableWi
return func({{.P.GoArgs}}, callback func(T)) (T, func()) {
{{- end}}
prec := {{.P.Expr}}
return subscribe(c, s.key, s.def, s.cdef, s.convert, prec, callback)
return subscribe(c, s.key, s.def, s.convert, prec, callback)
}
}

Expand All @@ -260,6 +284,16 @@ func (s {{.P.Name}}TypedSetting[T]) dispatchUpdate(c *Collection, sub any, cvs [
)
}

func (s {{.P.Name}}TypedConstrainedDefaultSetting[T]) dispatchUpdate(c *Collection, sub any, cvs []ConstrainedValue) {
dispatchUpdate(
c,
s.key,
s.convert,
sub.(*subscription[T]),
cvs,
)
}

{{if eq .P.Name "Global" -}}
func GetTypedPropertyFn[T any](value T) TypedPropertyFn[T] {
{{- else -}}
Expand All @@ -271,12 +305,13 @@ func GetTypedPropertyFnFilteredBy{{.P.Name}}[T any](value T) TypedPropertyFnWith
}
{{- else -}}
type {{.P.Name}}{{.T.Name}}Setting = {{.P.Name}}TypedSetting[{{.T.GoType}}]
type {{.P.Name}}{{.T.Name}}ConstrainedDefaultSetting = {{.P.Name}}TypedConstrainedDefaultSetting[{{.T.GoType}}]

func New{{.P.Name}}{{.T.Name}}Setting(key Key, def {{.T.GoType}}, description string) {{.P.Name}}{{.T.Name}}Setting {
return New{{.P.Name}}TypedSettingWithConverter[{{.T.GoType}}](key, convert{{.T.Name}}, def, description)
}

func New{{.P.Name}}{{.T.Name}}SettingWithConstrainedDefault(key Key, cdef []TypedConstrainedValue[{{.T.GoType}}], description string) {{.P.Name}}{{.T.Name}}Setting {
func New{{.P.Name}}{{.T.Name}}SettingWithConstrainedDefault(key Key, cdef []TypedConstrainedValue[{{.T.GoType}}], description string) {{.P.Name}}{{.T.Name}}ConstrainedDefaultSetting {
return New{{.P.Name}}TypedSettingWithConstrainedDefault[{{.T.GoType}}](key, convert{{.T.Name}}, cdef, description)
}

Expand Down
80 changes: 0 additions & 80 deletions common/dynamicconfig/cachedvalue.go

This file was deleted.

5 changes: 5 additions & 0 deletions common/dynamicconfig/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ type (
// Note that GetValue is called very often! You should not synchronously call out to an
// external system. Instead you should keep a set of all configured values, refresh it
// periodically or when notified, and only do in-memory lookups inside of GetValue.
//
// Implementations should prefer to return the same slice in response to the same key
// as long as the value hasn't changed. Value conversions are cached using weak
// pointers into the returned slice, so new slices will result in unnecessary calls to
// conversion functions.
GetValue(key Key) []ConstrainedValue
}

Expand Down
Loading
Loading