mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
fix(machine): correctly recreate machine in store if missing, improve context handling
This commit is contained in:
+22
-16
@@ -523,12 +523,16 @@ func (cc *clusterController) runMachineSync(ctx context.Context) error {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil
|
|
||||||
case <-ticker.C: // Scheduled periodic sync.
|
case <-ticker.C: // Scheduled periodic sync.
|
||||||
case <-cc.syncMachineTrigger: // Immediate sync request.
|
case <-cc.syncMachineTrigger: // Immediate sync request.
|
||||||
case <-dockerRestarted: // Docker daemon restarted -- engine version may have changed.
|
case <-dockerRestarted: // Docker daemon restarted -- engine version may have changed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A pending restart signal can race with context cancellation and win the select.
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := cc.syncMachineInfo(ctx); err != nil {
|
if err := cc.syncMachineInfo(ctx); err != nil {
|
||||||
slog.Error("Failed to sync machine info to cluster store.", "err", err)
|
slog.Error("Failed to sync machine info to cluster store.", "err", err)
|
||||||
}
|
}
|
||||||
@@ -548,30 +552,32 @@ func (cc *clusterController) RequestMachineSync() {
|
|||||||
// write if the info is unchanged since the last successful write.
|
// write if the info is unchanged since the last successful write.
|
||||||
func (cc *clusterController) syncMachineInfo(ctx context.Context) error {
|
func (cc *clusterController) syncMachineInfo(ctx context.Context) error {
|
||||||
publishedInfo, err := cc.store.GetMachine(ctx, cc.state.ID)
|
publishedInfo, err := cc.store.GetMachine(ctx, cc.state.ID)
|
||||||
if err != nil {
|
if err != nil && !errors.Is(err, store.ErrMachineNotFound) {
|
||||||
return fmt.Errorf("get machine from store: %w", err)
|
return fmt.Errorf("get machine from store: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
info := cc.machine.Info(ctx)
|
info := cc.machine.Info(ctx)
|
||||||
// Info leaves the Docker engine version empty when the engine is unavailable. Keep the previously
|
if publishedInfo != nil {
|
||||||
// published version in that case rather than overwriting it with an empty value.
|
// Info leaves the Docker engine version empty when the engine is unavailable. Keep the previously
|
||||||
if info.DockerVersion == "" {
|
// published version in that case rather than overwriting it with an empty value.
|
||||||
info.DockerVersion = publishedInfo.DockerVersion
|
if info.DockerVersion == "" {
|
||||||
}
|
info.DockerVersion = publishedInfo.DockerVersion
|
||||||
|
}
|
||||||
|
|
||||||
if proto.Equal(info, publishedInfo) {
|
// Skip the write if nothing changed since the last successful sync.
|
||||||
return nil
|
if proto.Equal(info, publishedInfo) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = cc.store.UpdateMachine(ctx, info); err != nil {
|
if err = cc.store.UpdateMachine(ctx, info); err != nil {
|
||||||
if errors.Is(err, store.ErrMachineNotFound) {
|
if !errors.Is(err, store.ErrMachineNotFound) {
|
||||||
// This should not happen but let's try to recreate it.
|
return fmt.Errorf("update machine in store: %w", err)
|
||||||
if createErr := cc.store.CreateMachine(ctx, info); createErr != nil {
|
}
|
||||||
return fmt.Errorf("create machine in store: %w", createErr)
|
// The machine row is missing (not created yet or lost). Recreate it.
|
||||||
}
|
if err = cc.store.CreateMachine(ctx, info); err != nil {
|
||||||
return nil
|
return fmt.Errorf("create machine in store: %w", err)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("update machine in store: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Info("Synced machine info to cluster store.", "id", info.Id, "name", info.Name)
|
slog.Info("Synced machine info to cluster store.", "id", info.Id, "name", info.Name)
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ func (s *Service) WatchDaemonRestart(ctx context.Context) <-chan struct{} {
|
|||||||
ch := make(chan struct{}, 1)
|
ch := make(chan struct{}, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
|
||||||
|
|
||||||
boff := backoff.WithContext(backoff.NewExponentialBackOff(
|
boff := backoff.WithContext(backoff.NewExponentialBackOff(
|
||||||
backoff.WithInitialInterval(1*time.Second),
|
backoff.WithInitialInterval(1*time.Second),
|
||||||
backoff.WithMaxInterval(30*time.Second),
|
backoff.WithMaxInterval(30*time.Second),
|
||||||
|
|||||||
Reference in New Issue
Block a user