Skip to content

Commit 5f07bc5

Browse files
committed
fix(machine): correctly recreate machine in store if missing, improve context handling
1 parent 8aa0a96 commit 5f07bc5

2 files changed

Lines changed: 22 additions & 18 deletions

File tree

‎internal/machine/cluster.go‎

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -523,12 +523,16 @@ func (cc *clusterController) runMachineSync(ctx context.Context) error {
523523
for {
524524
select {
525525
case <-ctx.Done():
526-
return nil
527526
case <-ticker.C: // Scheduled periodic sync.
528527
case <-cc.syncMachineTrigger: // Immediate sync request.
529528
case <-dockerRestarted: // Docker daemon restarted -- engine version may have changed.
530529
}
531530

531+
// A pending restart signal can race with context cancellation and win the select.
532+
if ctx.Err() != nil {
533+
return nil
534+
}
535+
532536
if err := cc.syncMachineInfo(ctx); err != nil {
533537
slog.Error("Failed to sync machine info to cluster store.", "err", err)
534538
}
@@ -548,30 +552,32 @@ func (cc *clusterController) RequestMachineSync() {
548552
// write if the info is unchanged since the last successful write.
549553
func (cc *clusterController) syncMachineInfo(ctx context.Context) error {
550554
publishedInfo, err := cc.store.GetMachine(ctx, cc.state.ID)
551-
if err != nil {
555+
if err != nil && !errors.Is(err, store.ErrMachineNotFound) {
552556
return fmt.Errorf("get machine from store: %w", err)
553557
}
554558

555559
info := cc.machine.Info(ctx)
556-
// Info leaves the Docker engine version empty when the engine is unavailable. Keep the previously
557-
// published version in that case rather than overwriting it with an empty value.
558-
if info.DockerVersion == "" {
559-
info.DockerVersion = publishedInfo.DockerVersion
560-
}
560+
if publishedInfo != nil {
561+
// Info leaves the Docker engine version empty when the engine is unavailable. Keep the previously
562+
// published version in that case rather than overwriting it with an empty value.
563+
if info.DockerVersion == "" {
564+
info.DockerVersion = publishedInfo.DockerVersion
565+
}
561566

562-
if proto.Equal(info, publishedInfo) {
563-
return nil
567+
// Skip the write if nothing changed since the last successful sync.
568+
if proto.Equal(info, publishedInfo) {
569+
return nil
570+
}
564571
}
565572

566573
if err = cc.store.UpdateMachine(ctx, info); err != nil {
567-
if errors.Is(err, store.ErrMachineNotFound) {
568-
// This should not happen but let's try to recreate it.
569-
if createErr := cc.store.CreateMachine(ctx, info); createErr != nil {
570-
return fmt.Errorf("create machine in store: %w", createErr)
571-
}
572-
return nil
574+
if !errors.Is(err, store.ErrMachineNotFound) {
575+
return fmt.Errorf("update machine in store: %w", err)
576+
}
577+
// The machine row is missing (not created yet or lost). Recreate it.
578+
if err = cc.store.CreateMachine(ctx, info); err != nil {
579+
return fmt.Errorf("create machine in store: %w", err)
573580
}
574-
return fmt.Errorf("update machine in store: %w", err)
575581
}
576582

577583
slog.Info("Synced machine info to cluster store.", "id", info.Id, "name", info.Name)

‎internal/machine/docker/service.go‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ func (s *Service) WatchDaemonRestart(ctx context.Context) <-chan struct{} {
4949
ch := make(chan struct{}, 1)
5050

5151
go func() {
52-
defer close(ch)
53-
5452
boff := backoff.WithContext(backoff.NewExponentialBackOff(
5553
backoff.WithInitialInterval(1*time.Second),
5654
backoff.WithMaxInterval(30*time.Second),

0 commit comments

Comments
 (0)