Skip to content

Commit de21566

Browse files
committed
feat(core): fail Start when a configured datastore cannot be created
Signed-off-by: Markus Vahlenkamp <markus.vahlenkamp@nokia.com>
1 parent 1dbac72 commit de21566

2 files changed

Lines changed: 35 additions & 10 deletions

File tree

‎pkg/core/core.go‎

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func New(ctx context.Context, cfg *config.Config, opts ...Option) (*Core, error)
7070
// Start initialises the schema store, the cache and the configured datastores,
7171
// then marks the Core ready. It returns when initialisation finished or failed
7272
// and only the first call does work; a failure is also reported by WaitReady.
73+
// Any configured datastore that cannot be created fails Start.
7374
func (c *Core) Start(ctx context.Context) error {
7475
c.startOnce.Do(func() {
7576
c.readyErr = c.start(ctx)
@@ -128,31 +129,39 @@ func (c *Core) start(ctx context.Context) error {
128129
return fmt.Errorf("core init: %w", err)
129130
}
130131

131-
c.createInitialDatastores(ctx)
132+
if err := c.createInitialDatastores(ctx); err != nil {
133+
return fmt.Errorf("core init: %w", err)
134+
}
132135
log.Info("data-server ready")
133136
return nil
134137
}
135138

136-
func (c *Core) createInitialDatastores(ctx context.Context) {
139+
// createInitialDatastores creates the datastores listed in the config and
140+
// returns the joined errors of those that failed.
141+
func (c *Core) createInitialDatastores(ctx context.Context) error {
137142
log := logf.FromContext(ctx)
138143
var wg sync.WaitGroup
139-
for _, dsCfg := range c.cfg.Datastores {
144+
errs := make([]error, len(c.cfg.Datastores))
145+
for i, dsCfg := range c.cfg.Datastores {
140146
dsCfg.Validation = c.cfg.Validation.DeepCopy()
141147
wg.Add(1)
142-
go func(dsCfg *config.DatastoreConfig) {
148+
go func(i int, dsCfg *config.DatastoreConfig) {
143149
defer wg.Done()
144150
ds, err := datastore.New(c.ctx, dsCfg, c.schemaClient, c.cacheClient, c.dialOpts...)
145-
if err != nil {
146-
log.Error(err, "failed to create datastore", "datastore-name", dsCfg.Name)
147-
return
151+
if err == nil {
152+
err = c.addDatastore(ds)
148153
}
149-
if err := c.addDatastore(ds); err != nil {
150-
log.Error(err, "failed to add datastore", "datastore-name", dsCfg.Name)
154+
if err != nil {
155+
errs[i] = fmt.Errorf("datastore %s: %w", dsCfg.Name, err)
151156
}
152-
}(dsCfg)
157+
}(i, dsCfg)
153158
}
154159
wg.Wait()
160+
if err := errors.Join(errs...); err != nil {
161+
return err
162+
}
155163
log.Info("configured datastores initialized")
164+
return nil
156165
}
157166

158167
func (c *Core) addDatastore(ds *datastore.Datastore) error {

‎pkg/core/core_test.go‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,19 @@ func TestStartAfterStopFails(t *testing.T) {
141141
t.Fatalf("got %v", err)
142142
}
143143
}
144+
145+
func TestStartFailsWhenInitialDatastoreFails(t *testing.T) {
146+
cfg := newTestConfig(t)
147+
cfg.Datastores[0].Schema.Name = "missing"
148+
c, err := New(context.Background(), cfg)
149+
if err != nil {
150+
t.Fatal(err)
151+
}
152+
t.Cleanup(func() { _ = c.Stop(context.Background()) })
153+
if err := c.Start(context.Background()); err == nil {
154+
t.Fatal("expected error")
155+
}
156+
if err := c.WaitReady(context.Background()); err == nil {
157+
t.Fatal("WaitReady should report the failure")
158+
}
159+
}

0 commit comments

Comments
 (0)