-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[jaeger-v2] Streamline storage initialization #5171
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,8 +13,10 @@ import ( | |
"go.opentelemetry.io/collector/extension" | ||
"go.uber.org/zap" | ||
|
||
memoryCfg "github.com/jaegertracing/jaeger/pkg/memory/config" | ||
"github.com/jaegertracing/jaeger/pkg/metrics" | ||
"github.com/jaegertracing/jaeger/plugin/storage/badger" | ||
badgerCfg "github.com/jaegertracing/jaeger/plugin/storage/badger" | ||
"github.com/jaegertracing/jaeger/plugin/storage/memory" | ||
"github.com/jaegertracing/jaeger/storage" | ||
) | ||
|
@@ -60,35 +62,62 @@ func newStorageExt(config *Config, otel component.TelemetrySettings) *storageExt | |
} | ||
} | ||
|
||
func (s *storageExt) Start(ctx context.Context, host component.Host) error { | ||
for name, mem := range s.config.Memory { | ||
if _, ok := s.factories[name]; ok { | ||
return fmt.Errorf("duplicate memory storage name %s", name) | ||
} | ||
s.factories[name] = memory.NewFactoryWithConfig( | ||
mem, | ||
metrics.NullFactory, | ||
s.logger.With(zap.String("storage_name", name)), | ||
) | ||
} | ||
type starter[Config any, Factory storage.Factory] struct { | ||
ext *storageExt | ||
storageKind string | ||
cfg map[string]Config | ||
builder func(Config, metrics.Factory, *zap.Logger) (Factory, error) | ||
} | ||
|
||
for name, b := range s.config.Badger { | ||
if _, ok := s.factories[name]; ok { | ||
return fmt.Errorf("duplicate badger storage name %s", name) | ||
func (s *starter[Config, Factory]) build(ctx context.Context, host component.Host) error { | ||
for name, cfg := range s.cfg { | ||
if _, ok := s.ext.factories[name]; ok { | ||
return fmt.Errorf("duplicate %s storage name %s", s.storageKind, name) | ||
} | ||
var err error | ||
factory, err := badger.NewFactoryWithConfig( | ||
b, | ||
factory, err := s.builder( | ||
cfg, | ||
metrics.NullFactory, | ||
s.logger.With(zap.String("storage_name", name)), | ||
s.ext.logger.With(zap.String("storage_name", name)), | ||
) | ||
if err != nil { | ||
return fmt.Errorf("failed to initialize badger storage: %w", err) | ||
return fmt.Errorf("failed to initialize %s storage %s: %w", s.storageKind, name, err) | ||
} | ||
s.factories[name] = factory | ||
s.ext.factories[name] = factory | ||
} | ||
return nil | ||
} | ||
|
||
// TODO add support for other backends | ||
func (s *storageExt) Start(ctx context.Context, host component.Host) error { | ||
memStarter := &starter[memoryCfg.Configuration, *memory.Factory]{ | ||
ext: s, | ||
storageKind: "memory", | ||
cfg: s.config.Memory, | ||
// memory factory does not return an error, so need to wrap it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I hate functions that are declared with errors but always return nil. The caller either has to ignore the error, or it has no easy way of unit testing the error handing path (which will never be used). Lose-lose. I think if the function can never return an error it should never declare it as a possibility (unless you're dealing with an interface where there's no choice). |
||
builder: func( | ||
cfg memoryCfg.Configuration, | ||
metricsFactory metrics.Factory, | ||
logger *zap.Logger, | ||
) (*memory.Factory, error) { | ||
return memory.NewFactoryWithConfig(cfg, metricsFactory, logger), nil | ||
}, | ||
} | ||
badgerStarter := &starter[badgerCfg.NamespaceConfig, *badger.Factory]{ | ||
ext: s, | ||
storageKind: "badger", | ||
cfg: s.config.Badger, | ||
builder: badger.NewFactoryWithConfig, | ||
} | ||
|
||
builders := []func(ctx context.Context, host component.Host) error{ | ||
memStarter.build, | ||
badgerStarter.build, | ||
// TODO add support for other backends | ||
} | ||
for _, builder := range builders { | ||
if err := builder(ctx, host); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internal state isn't persisted between method calls so all methods are effectively read-only; we could assert this by using value receivers instead of pointer receivers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, but makes no difference in this context since the code runs exactly once. Don't want to reset the approval just for this fix :-)