@@ -61,7 +61,45 @@ func checkAndEnqueueRefreshTasks(client *asynq.Client, db *gorm.DB, logger zerol
6161 }
6262 return time.Time {}
6363 }()).
64- Msg ("Config refresh due - creating new database and enqueueing restore task" )
64+ Msg ("Config refresh due - checking if new restore can be created" )
65+
66+ // Check if we're already at or above max_restores limit
67+ // Count restores without branches (eligible for cleanup)
68+ var totalRestores int64
69+ if err := db .Model (& models.Restore {}).Count (& totalRestores ).Error ; err != nil {
70+ logger .Error ().Err (err ).Msg ("Failed to count restores" )
71+ return
72+ }
73+
74+ // Count restores with branches (protected from cleanup)
75+ var restoresWithBranches int64
76+ if err := db .Model (& models.Restore {}).
77+ Joins ("JOIN branches ON branches.restore_id = restores.id" ).
78+ Distinct ("restores.id" ).
79+ Count (& restoresWithBranches ).Error ; err != nil {
80+ logger .Error ().Err (err ).Msg ("Failed to count restores with branches" )
81+ return
82+ }
83+
84+ // Calculate how many restores can be cleaned up
85+ cleanableRestores := totalRestores - restoresWithBranches
86+
87+ // If we're at or above max_restores and have no cleanable restores, skip
88+ if int (totalRestores ) >= config .MaxRestores && cleanableRestores == 0 {
89+ logger .Warn ().
90+ Int64 ("total_restores" , totalRestores ).
91+ Int64 ("restores_with_branches" , restoresWithBranches ).
92+ Int ("max_restores" , config .MaxRestores ).
93+ Msg ("Cannot create new restore - at max_restores limit and all restores have branches" )
94+
95+ // Still update NextRefreshAt to prevent retrying every minute
96+ now := time .Now ()
97+ nextRefresh := calculateNextRefreshTime (config .RefreshSchedule , now )
98+ if nextRefresh != nil {
99+ db .Model (& config ).Update ("next_refresh_at" , nextRefresh )
100+ }
101+ return
102+ }
65103
66104 // Determine schema-only flag
67105 // Note: Crunchy Bridge (pgBackRest) doesn't support schema-only, only logical restore (pg_dump) does
0 commit comments