44 "log/slog"
55 "postgresus-backend/internal/config"
66 backups_config "postgresus-backend/internal/features/backups/config"
7- "postgresus-backend/internal/features/databases"
87 "postgresus-backend/internal/features/storages"
98 "postgresus-backend/internal/util/period"
109 "time"
@@ -13,9 +12,8 @@ import (
1312type BackupBackgroundService struct {
1413 backupService * BackupService
1514 backupRepository * BackupRepository
16- databaseService * databases.DatabaseService
17- storageService * storages.StorageService
1815 backupConfigService * backups_config.BackupConfigService
16+ storageService * storages.StorageService
1917
2018 lastBackupTime time.Time
2119 logger * slog.Logger
@@ -51,7 +49,7 @@ func (s *BackupBackgroundService) Run() {
5149 }
5250}
5351
54- func (s * BackupBackgroundService ) IsBackupsRunning () bool {
52+ func (s * BackupBackgroundService ) IsBackupsWorkerRunning () bool {
5553 // if last backup time is more than 5 minutes ago, return false
5654 return s .lastBackupTime .After (time .Now ().UTC ().Add (- 5 * time .Minute ))
5755}
@@ -90,18 +88,12 @@ func (s *BackupBackgroundService) failBackupsInProgress() error {
9088}
9189
9290func (s * BackupBackgroundService ) cleanOldBackups () error {
93- allDatabases , err := s .databaseService . GetAllDatabases ()
91+ enabledBackupConfigs , err := s .backupConfigService . GetBackupConfigsWithEnabledBackups ()
9492 if err != nil {
9593 return err
9694 }
9795
98- for _ , database := range allDatabases {
99- backupConfig , err := s .backupConfigService .GetBackupConfigByDbId (database .ID )
100- if err != nil {
101- s .logger .Error ("Failed to get backup config by database ID" , "error" , err )
102- continue
103- }
104-
96+ for _ , backupConfig := range enabledBackupConfigs {
10597 backupStorePeriod := backupConfig .StorePeriod
10698
10799 if backupStorePeriod == period .PeriodForever {
@@ -112,14 +104,14 @@ func (s *BackupBackgroundService) cleanOldBackups() error {
112104 dateBeforeBackupsShouldBeDeleted := time .Now ().UTC ().Add (- storeDuration )
113105
114106 oldBackups , err := s .backupRepository .FindBackupsBeforeDate (
115- database . ID ,
107+ backupConfig . DatabaseID ,
116108 dateBeforeBackupsShouldBeDeleted ,
117109 )
118110 if err != nil {
119111 s .logger .Error (
120112 "Failed to find old backups for database" ,
121113 "databaseId" ,
122- database . ID ,
114+ backupConfig . DatabaseID ,
123115 "error" ,
124116 err ,
125117 )
@@ -149,36 +141,36 @@ func (s *BackupBackgroundService) cleanOldBackups() error {
149141 continue
150142 }
151143
152- s .logger .Info ("Deleted old backup" , "backupId" , backup .ID , "databaseId" , database .ID )
144+ s .logger .Info (
145+ "Deleted old backup" ,
146+ "backupId" ,
147+ backup .ID ,
148+ "databaseId" ,
149+ backupConfig .DatabaseID ,
150+ )
153151 }
154152 }
155153
156154 return nil
157155}
158156
159157func (s * BackupBackgroundService ) runPendingBackups () error {
160- allDatabases , err := s .databaseService . GetAllDatabases ()
158+ enabledBackupConfigs , err := s .backupConfigService . GetBackupConfigsWithEnabledBackups ()
161159 if err != nil {
162160 return err
163161 }
164162
165- for _ , database := range allDatabases {
166- backupConfig , err := s .backupConfigService .GetBackupConfigByDbId (database .ID )
167- if err != nil {
168- s .logger .Error ("Failed to get backup config by database ID" , "error" , err )
169- continue
170- }
171-
163+ for _ , backupConfig := range enabledBackupConfigs {
172164 if backupConfig .BackupInterval == nil {
173165 continue
174166 }
175167
176- lastBackup , err := s .backupRepository .FindLastByDatabaseID (database . ID )
168+ lastBackup , err := s .backupRepository .FindLastByDatabaseID (backupConfig . DatabaseID )
177169 if err != nil {
178170 s .logger .Error (
179171 "Failed to get last backup for database" ,
180172 "databaseId" ,
181- database . ID ,
173+ backupConfig . DatabaseID ,
182174 "error" ,
183175 err ,
184176 )
@@ -190,19 +182,71 @@ func (s *BackupBackgroundService) runPendingBackups() error {
190182 lastBackupTime = & lastBackup .CreatedAt
191183 }
192184
193- if backupConfig .BackupInterval .ShouldTriggerBackup (time .Now ().UTC (), lastBackupTime ) {
185+ remainedBackupTryCount := s .GetRemainedBackupTryCount (lastBackup )
186+
187+ if backupConfig .BackupInterval .ShouldTriggerBackup (time .Now ().UTC (), lastBackupTime ) ||
188+ remainedBackupTryCount > 0 {
194189 s .logger .Info (
195190 "Triggering scheduled backup" ,
196191 "databaseId" ,
197- database . ID ,
192+ backupConfig . DatabaseID ,
198193 "intervalType" ,
199194 backupConfig .BackupInterval .Interval ,
200195 )
201196
202- go s .backupService .MakeBackup (database .ID )
203- s .logger .Info ("Successfully triggered scheduled backup" , "databaseId" , database .ID )
197+ go s .backupService .MakeBackup (backupConfig .DatabaseID , remainedBackupTryCount == 1 )
198+ s .logger .Info (
199+ "Successfully triggered scheduled backup" ,
200+ "databaseId" ,
201+ backupConfig .DatabaseID ,
202+ )
204203 }
205204 }
206205
207206 return nil
208207}
208+
209+ // GetRemainedBackupTryCount returns the number of remaining backup tries for a given backup.
210+ // If the backup is not failed or the backup config does not allow retries, it returns 0.
211+ // If the backup is failed and the backup config allows retries, it returns the number of remaining tries.
212+ // If the backup is failed and the backup config does not allow retries, it returns 0.
213+ func (s * BackupBackgroundService ) GetRemainedBackupTryCount (lastBackup * Backup ) int {
214+ if lastBackup == nil {
215+ return 0
216+ }
217+
218+ if lastBackup .Status != BackupStatusFailed {
219+ return 0
220+ }
221+
222+ backupConfig , err := s .backupConfigService .GetBackupConfigByDbId (lastBackup .DatabaseID )
223+ if err != nil {
224+ s .logger .Error ("Failed to get backup config by database ID" , "error" , err )
225+ return 0
226+ }
227+
228+ if ! backupConfig .IsRetryIfFailed {
229+ return 0
230+ }
231+
232+ maxFailedTriesCount := backupConfig .MaxFailedTriesCount
233+
234+ lastBackups , err := s .backupRepository .FindByDatabaseIDWithLimit (
235+ lastBackup .DatabaseID ,
236+ maxFailedTriesCount ,
237+ )
238+ if err != nil {
239+ s .logger .Error ("Failed to find last backups by database ID" , "error" , err )
240+ return 0
241+ }
242+
243+ lastFailedBackups := make ([]* Backup , 0 )
244+
245+ for _ , backup := range lastBackups {
246+ if backup .Status == BackupStatusFailed {
247+ lastFailedBackups = append (lastFailedBackups , backup )
248+ }
249+ }
250+
251+ return maxFailedTriesCount - len (lastFailedBackups )
252+ }
0 commit comments