syncReplicaWithRetry attempts to sync the replica with retry logic for shutdown. It retries until success, timeout, or context cancellation. If db.Done is non-nil, closing it cancels any in-flight sync attempt and exits the retry loop. If ShutdownSyncTimeout is 0, it performs a single sync attempt w
(ctx context.Context)
| 824 | // closing it cancels any in-flight sync attempt and exits the retry loop. |
| 825 | // If ShutdownSyncTimeout is 0, it performs a single sync attempt without retries. |
| 826 | func (db *DB) syncReplicaWithRetry(ctx context.Context) error { |
| 827 | if db.Replica == nil { |
| 828 | return nil |
| 829 | } |
| 830 | |
| 831 | timeout := db.ShutdownSyncTimeout |
| 832 | interval := db.ShutdownSyncInterval |
| 833 | |
| 834 | // If timeout is zero, just try once (no retry) |
| 835 | if timeout == 0 { |
| 836 | return db.Replica.Sync(ctx) |
| 837 | } |
| 838 | |
| 839 | // Use default interval if not set |
| 840 | if interval == 0 { |
| 841 | interval = DefaultShutdownSyncInterval |
| 842 | } |
| 843 | |
| 844 | // Create deadline context for total retry duration. |
| 845 | deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) |
| 846 | defer deadlineCancel() |
| 847 | |
| 848 | // If db.Done is set, derive a context that cancels when done is closed |
| 849 | // so that in-flight Replica.Sync calls are interrupted immediately. |
| 850 | syncCtx := deadlineCtx |
| 851 | if db.Done != nil { |
| 852 | var syncCancel context.CancelFunc |
| 853 | syncCtx, syncCancel = context.WithCancel(deadlineCtx) |
| 854 | go func() { |
| 855 | select { |
| 856 | case <-db.Done: |
| 857 | syncCancel() |
| 858 | case <-deadlineCtx.Done(): |
| 859 | syncCancel() |
| 860 | } |
| 861 | }() |
| 862 | } |
| 863 | |
| 864 | var lastErr error |
| 865 | attempt := 0 |
| 866 | startTime := time.Now() |
| 867 | |
| 868 | for { |
| 869 | // Check if done is already closed before attempting sync |
| 870 | if db.Done != nil { |
| 871 | select { |
| 872 | case <-db.Done: |
| 873 | db.Logger.Warn("shutdown sync skipped, interrupted by signal", |
| 874 | "attempts", attempt, |
| 875 | "duration", time.Since(startTime)) |
| 876 | return fmt.Errorf("after %d attempts: %w", attempt, ErrShutdownInterrupted) |
| 877 | default: |
| 878 | } |
| 879 | } |
| 880 | |
| 881 | attempt++ |
| 882 | |
| 883 | // Try sync |