@@ -192,40 +192,6 @@ func (c *StoreReconciler) ReconcileAll(ctx context.Context) error {
192
192
return err
193
193
}
194
194
195
- func (c * StoreReconciler ) WithReconciliationLock (ctx context.Context , logger slog.Logger , fn func (ctx context.Context , db database.Store ) error ) error {
196
- // This tx holds a global lock, which prevents any other coderd replica from starting a reconciliation and
197
- // possibly getting an inconsistent view of the state.
198
- //
199
- // The lock MUST be held until ALL modifications have been effected.
200
- //
201
- // It is run with RepeatableRead isolation, so it's effectively snapshotting the data at the start of the tx.
202
- //
203
- // This is a read-only tx, so returning an error (i.e. causing a rollback) has no impact.
204
- return c .store .InTx (func (db database.Store ) error {
205
- start := c .clock .Now ()
206
-
207
- // Try to acquire the lock. If we can't get it, another replica is handling reconciliation.
208
- acquired , err := db .TryAcquireLock (ctx , database .LockIDReconcileTemplatePrebuilds )
209
- if err != nil {
210
- // This is a real database error, not just lock contention
211
- logger .Error (ctx , "failed to acquire reconciliation lock due to database error" , slog .Error (err ))
212
- return err
213
- }
214
- if ! acquired {
215
- // Normal case: another replica has the lock
216
- return nil
217
- }
218
-
219
- logger .Debug (ctx , "acquired top-level reconciliation lock" , slog .F ("acquire_wait_secs" , fmt .Sprintf ("%.4f" , c .clock .Since (start ).Seconds ())))
220
-
221
- return fn (ctx , db )
222
- }, & database.TxOptions {
223
- Isolation : sql .LevelRepeatableRead ,
224
- ReadOnly : true ,
225
- TxIdentifier : "template_prebuilds" ,
226
- })
227
- }
228
-
229
195
// SnapshotState determines the current state of prebuilds & the presets which define them.
230
196
// An application-level lock is used
231
197
func (c * StoreReconciler ) SnapshotState (ctx context.Context , store database.Store ) (* prebuilds.GlobalSnapshot , error ) {
@@ -269,14 +235,6 @@ func (c *StoreReconciler) SnapshotState(ctx context.Context, store database.Stor
269
235
return & state , err
270
236
}
271
237
272
- func (c * StoreReconciler ) CalculateActions (ctx context.Context , snapshot prebuilds.PresetSnapshot ) (* prebuilds.ReconciliationActions , error ) {
273
- if ctx .Err () != nil {
274
- return nil , ctx .Err ()
275
- }
276
-
277
- return snapshot .CalculateActions (c .clock , c .cfg .ReconciliationBackoffInterval .Value ())
278
- }
279
-
280
238
func (c * StoreReconciler ) ReconcilePreset (ctx context.Context , ps prebuilds.PresetSnapshot ) error {
281
239
logger := c .logger .With (
282
240
slog .F ("template_id" , ps .Preset .TemplateID .String ()),
@@ -356,6 +314,48 @@ func (c *StoreReconciler) ReconcilePreset(ctx context.Context, ps prebuilds.Pres
356
314
}
357
315
}
358
316
317
+ func (c * StoreReconciler ) CalculateActions (ctx context.Context , snapshot prebuilds.PresetSnapshot ) (* prebuilds.ReconciliationActions , error ) {
318
+ if ctx .Err () != nil {
319
+ return nil , ctx .Err ()
320
+ }
321
+
322
+ return snapshot .CalculateActions (c .clock , c .cfg .ReconciliationBackoffInterval .Value ())
323
+ }
324
+
325
+ func (c * StoreReconciler ) WithReconciliationLock (ctx context.Context , logger slog.Logger , fn func (ctx context.Context , db database.Store ) error ) error {
326
+ // This tx holds a global lock, which prevents any other coderd replica from starting a reconciliation and
327
+ // possibly getting an inconsistent view of the state.
328
+ //
329
+ // The lock MUST be held until ALL modifications have been effected.
330
+ //
331
+ // It is run with RepeatableRead isolation, so it's effectively snapshotting the data at the start of the tx.
332
+ //
333
+ // This is a read-only tx, so returning an error (i.e. causing a rollback) has no impact.
334
+ return c .store .InTx (func (db database.Store ) error {
335
+ start := c .clock .Now ()
336
+
337
+ // Try to acquire the lock. If we can't get it, another replica is handling reconciliation.
338
+ acquired , err := db .TryAcquireLock (ctx , database .LockIDReconcileTemplatePrebuilds )
339
+ if err != nil {
340
+ // This is a real database error, not just lock contention
341
+ logger .Error (ctx , "failed to acquire reconciliation lock due to database error" , slog .Error (err ))
342
+ return err
343
+ }
344
+ if ! acquired {
345
+ // Normal case: another replica has the lock
346
+ return nil
347
+ }
348
+
349
+ logger .Debug (ctx , "acquired top-level reconciliation lock" , slog .F ("acquire_wait_secs" , fmt .Sprintf ("%.4f" , c .clock .Since (start ).Seconds ())))
350
+
351
+ return fn (ctx , db )
352
+ }, & database.TxOptions {
353
+ Isolation : sql .LevelRepeatableRead ,
354
+ ReadOnly : true ,
355
+ TxIdentifier : "template_prebuilds" ,
356
+ })
357
+ }
358
+
359
359
func (c * StoreReconciler ) createPrebuild (ctx context.Context , prebuildID uuid.UUID , templateID uuid.UUID , presetID uuid.UUID ) error {
360
360
name , err := prebuilds .GenerateName ()
361
361
if err != nil {
0 commit comments