| 1085 | } |
| 1086 | |
| 1087 | func (c *clusterStateHolder) LazyReload() { |
| 1088 | // If already reloading, mark that another reload is pending |
| 1089 | if !atomic.CompareAndSwapUint32(&c.reloading, 0, 1) { |
| 1090 | atomic.StoreUint32(&c.reloadPending, 1) |
| 1091 | return |
| 1092 | } |
| 1093 | |
| 1094 | go func() { |
| 1095 | for { |
| 1096 | _, err := c.Reload(context.Background()) |
| 1097 | if err != nil { |
| 1098 | atomic.StoreUint32(&c.reloadPending, 0) |
| 1099 | atomic.StoreUint32(&c.reloading, 0) |
| 1100 | return |
| 1101 | } |
| 1102 | |
| 1103 | // Clear pending flag after reload completes, before cooldown |
| 1104 | // This captures notifications that arrived during the reload |
| 1105 | atomic.StoreUint32(&c.reloadPending, 0) |
| 1106 | |
| 1107 | // Wait cooldown period |
| 1108 | time.Sleep(200 * time.Millisecond) |
| 1109 | |
| 1110 | // Check if another reload was requested during cooldown |
| 1111 | if atomic.LoadUint32(&c.reloadPending) == 0 { |
| 1112 | // No pending reload, we're done |
| 1113 | atomic.StoreUint32(&c.reloading, 0) |
| 1114 | return |
| 1115 | } |
| 1116 | |
| 1117 | // Pending reload requested, loop to reload again |
| 1118 | } |
| 1119 | }() |
| 1120 | } |
| 1121 | |
| 1122 | func (c *clusterStateHolder) Get(ctx context.Context) (*clusterState, error) { |
| 1123 | v := c.state.Load() |