Skip to content

Commit 1c559de

Browse files
committed
fix(rds-refresh): immediate status check and consistent in-progress states
- Add immediate status check before ticker loop in WaitForRefreshComplete to avoid unnecessary delay of up to pollInterval (30s) on first check - Align IsRefreshInProgress with WaitForRefreshComplete by including StatusPending and StatusRenewed as in-progress states, preventing potential duplicate refresh triggers
1 parent ec74bc6 commit 1c559de

File tree

1 file changed

+51
-42
lines changed

1 file changed

+51
-42
lines changed

rds-refresh/dblab.go

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,57 @@ func (c *DBLabClient) TriggerFullRefresh(ctx context.Context) error {
150150
// then waits for it to complete. This prevents race conditions where stale status
151151
// from a previous refresh could cause premature return.
152152
func (c *DBLabClient) WaitForRefreshComplete(ctx context.Context, pollInterval, timeout time.Duration) error {
153-
ticker := time.NewTicker(pollInterval)
154-
defer ticker.Stop()
155-
156153
timeoutTimer := time.NewTimer(timeout)
157154
defer timeoutTimer.Stop()
158155

159156
refreshStarted := false
160157

158+
// checkStatus handles status evaluation and returns (done, error)
159+
checkStatus := func() (bool, error) {
160+
status, err := c.GetStatus(ctx)
161+
if err != nil {
162+
return false, fmt.Errorf("failed to get status: %w", err)
163+
}
164+
165+
switch status.Retrieving.Status {
166+
case StatusRefreshing, StatusSnapshotting, StatusRenewed, StatusPending:
167+
refreshStarted = true
168+
return false, nil
169+
case StatusFinished:
170+
if !refreshStarted {
171+
return false, nil
172+
}
173+
return true, nil
174+
case StatusFailed:
175+
if !refreshStarted {
176+
return false, nil
177+
}
178+
if len(status.Retrieving.Alerts) > 0 {
179+
for _, alert := range status.Retrieving.Alerts {
180+
return false, fmt.Errorf("refresh failed: %s", alert.Message)
181+
}
182+
}
183+
return false, fmt.Errorf("refresh failed (no details available)")
184+
case StatusInactive:
185+
if refreshStarted {
186+
return false, fmt.Errorf("refresh stopped unexpectedly (status: inactive)")
187+
}
188+
return false, nil
189+
default:
190+
return false, nil
191+
}
192+
}
193+
194+
// immediate first check
195+
if done, err := checkStatus(); err != nil {
196+
return err
197+
} else if done {
198+
return nil
199+
}
200+
201+
ticker := time.NewTicker(pollInterval)
202+
defer ticker.Stop()
203+
161204
for {
162205
select {
163206
case <-ctx.Done():
@@ -168,59 +211,25 @@ func (c *DBLabClient) WaitForRefreshComplete(ctx context.Context, pollInterval,
168211
}
169212
return fmt.Errorf("timeout waiting for refresh to complete after %v", timeout)
170213
case <-ticker.C:
171-
status, err := c.GetStatus(ctx)
172-
if err != nil {
173-
return fmt.Errorf("failed to get status: %w", err)
174-
}
175-
176-
retrievalStatus := status.Retrieving.Status
177-
178-
switch retrievalStatus {
179-
case StatusRefreshing, StatusSnapshotting, StatusRenewed, StatusPending:
180-
// refresh is in progress - mark as started
181-
refreshStarted = true
182-
continue
183-
case StatusFinished:
184-
if !refreshStarted {
185-
// still showing old status, refresh hasn't started yet
186-
continue
187-
}
188-
// refresh started and now finished
214+
if done, err := checkStatus(); err != nil {
215+
return err
216+
} else if done {
189217
return nil
190-
case StatusFailed:
191-
if !refreshStarted {
192-
// old failure status, refresh hasn't started yet
193-
continue
194-
}
195-
if len(status.Retrieving.Alerts) > 0 {
196-
for _, alert := range status.Retrieving.Alerts {
197-
return fmt.Errorf("refresh failed: %s", alert.Message)
198-
}
199-
}
200-
return fmt.Errorf("refresh failed (no details available)")
201-
case StatusInactive:
202-
if refreshStarted {
203-
// was running but now inactive - unusual, treat as failure
204-
return fmt.Errorf("refresh stopped unexpectedly (status: inactive)")
205-
}
206-
// not started yet
207-
continue
208-
default:
209-
continue
210218
}
211219
}
212220
}
213221
}
214222

215223
// IsRefreshInProgress checks if a refresh is currently in progress.
224+
// Considers all active states: refreshing, snapshotting, pending, renewed.
216225
func (c *DBLabClient) IsRefreshInProgress(ctx context.Context) (bool, error) {
217226
status, err := c.GetStatus(ctx)
218227
if err != nil {
219228
return false, err
220229
}
221230

222231
switch status.Retrieving.Status {
223-
case StatusRefreshing, StatusSnapshotting:
232+
case StatusRefreshing, StatusSnapshotting, StatusPending, StatusRenewed:
224233
return true, nil
225234
default:
226235
return false, nil

0 commit comments

Comments
 (0)