feature(backup): do not trigger retry on manual backup
This commit is contained in:
parent
11bb95db92
commit
8765c5e705
2 changed files with 26 additions and 11 deletions
|
|
@ -389,7 +389,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
const result = await validateBackupExecution(scheduleId, manual);
|
const result = await validateBackupExecution(scheduleId, manual);
|
||||||
|
|
||||||
if (result.type !== "success") {
|
if (result.type !== "success") {
|
||||||
return handleValidationResult(scheduleId, result);
|
return handleValidationResult(scheduleId, result, manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { context: ctx } = result;
|
const { context: ctx } = result;
|
||||||
|
|
@ -426,7 +426,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
|
|
||||||
switch (executionResult.status) {
|
switch (executionResult.status) {
|
||||||
case "unavailable":
|
case "unavailable":
|
||||||
return handleBackupFailure(scheduleId, ctx.organizationId, executionResult.error, ctx);
|
return handleBackupFailure(scheduleId, ctx.organizationId, executionResult.error, manual, ctx);
|
||||||
case "completed":
|
case "completed":
|
||||||
return finalizeSuccessfulBackup(
|
return finalizeSuccessfulBackup(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -435,7 +435,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
executionResult.warningDetails,
|
executionResult.warningDetails,
|
||||||
);
|
);
|
||||||
case "failed":
|
case "failed":
|
||||||
return handleBackupFailure(scheduleId, ctx.organizationId, executionResult.error, ctx);
|
return handleBackupFailure(scheduleId, ctx.organizationId, executionResult.error, manual, ctx);
|
||||||
case "cancelled":
|
case "cancelled":
|
||||||
return handleBackupCancellation(scheduleId, ctx.organizationId, executionResult.message);
|
return handleBackupCancellation(scheduleId, ctx.organizationId, executionResult.message);
|
||||||
}
|
}
|
||||||
|
|
@ -447,7 +447,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleBackupFailure(scheduleId, ctx.organizationId, error, ctx);
|
return handleBackupFailure(scheduleId, ctx.organizationId, error, manual, ctx);
|
||||||
} finally {
|
} finally {
|
||||||
backupExecutor.untrack(scheduleId, abortController);
|
backupExecutor.untrack(scheduleId, abortController);
|
||||||
cache.del(cacheKeys.backup.progress(scheduleId));
|
cache.del(cacheKeys.backup.progress(scheduleId));
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,11 @@ export async function validateBackupExecution(scheduleId: number, manual = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handleValidationResult(scheduleId: number, result: ValidationFailure | ValidationSkipped) {
|
export async function handleValidationResult(
|
||||||
|
scheduleId: number,
|
||||||
|
result: ValidationFailure | ValidationSkipped,
|
||||||
|
manual: boolean,
|
||||||
|
) {
|
||||||
const organizationId = getOrganizationId();
|
const organizationId = getOrganizationId();
|
||||||
|
|
||||||
if (result.type === "skipped") {
|
if (result.type === "skipped") {
|
||||||
|
|
@ -93,7 +97,7 @@ export async function handleValidationResult(scheduleId: number, result: Validat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await handleBackupFailure(scheduleId, organizationId, result.error, result.partialContext);
|
await handleBackupFailure(scheduleId, organizationId, result.error, manual, result.partialContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emitBackupStarted(ctx: BackupContext, scheduleId: number) {
|
export function emitBackupStarted(ctx: BackupContext, scheduleId: number) {
|
||||||
|
|
@ -205,6 +209,7 @@ export async function handleBackupFailure(
|
||||||
scheduleId: number,
|
scheduleId: number,
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
error: unknown,
|
error: unknown,
|
||||||
|
manual: boolean,
|
||||||
partialContext?: Partial<BackupContext>,
|
partialContext?: Partial<BackupContext>,
|
||||||
) {
|
) {
|
||||||
const errorMessage = toMessage(error);
|
const errorMessage = toMessage(error);
|
||||||
|
|
@ -228,7 +233,7 @@ export async function handleBackupFailure(
|
||||||
const nextRetryBackupAt = Date.now() + schedule.retryDelay;
|
const nextRetryBackupAt = Date.now() + schedule.retryDelay;
|
||||||
const nextScheduledBackupAt = calculateNextRun(schedule.cronExpression);
|
const nextScheduledBackupAt = calculateNextRun(schedule.cronExpression);
|
||||||
|
|
||||||
if (shouldRetry && nextRetryBackupAt < nextScheduledBackupAt) {
|
if (!manual && shouldRetry && nextRetryBackupAt < nextScheduledBackupAt) {
|
||||||
await scheduleQueries.updateStatus(scheduleId, organizationId, {
|
await scheduleQueries.updateStatus(scheduleId, organizationId, {
|
||||||
lastBackupAt: Date.now(),
|
lastBackupAt: Date.now(),
|
||||||
lastBackupStatus: "error",
|
lastBackupStatus: "error",
|
||||||
|
|
@ -273,9 +278,15 @@ export async function handleBackupFailure(
|
||||||
|
|
||||||
const { volume, repository } = partialContext;
|
const { volume, repository } = partialContext;
|
||||||
|
|
||||||
logger.error(
|
if (manual) {
|
||||||
`Backup ${schedule.name} failed after ${maxRetries} retries for volume ${volume.name} to repository ${repository.name}: ${errorMessage}`,
|
logger.error(
|
||||||
);
|
`Manual backup ${schedule.name} failed for volume ${volume.name} to repository ${repository.name}: ${errorMessage}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logger.error(
|
||||||
|
`Backup ${schedule.name} failed after ${maxRetries} retries for volume ${volume.name} to repository ${repository.name}: ${errorMessage}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
serverEvents.emit("backup:completed", {
|
serverEvents.emit("backup:completed", {
|
||||||
organizationId,
|
organizationId,
|
||||||
|
|
@ -285,12 +296,16 @@ export async function handleBackupFailure(
|
||||||
status: "error",
|
status: "error",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const errorNotificationMessage = manual
|
||||||
|
? `${errorDetails}`
|
||||||
|
: `${errorDetails}\n\nFailed after ${maxRetries} retry attempts.`;
|
||||||
|
|
||||||
notificationsService
|
notificationsService
|
||||||
.sendBackupNotification(scheduleId, "failure", {
|
.sendBackupNotification(scheduleId, "failure", {
|
||||||
volumeName: volume.name,
|
volumeName: volume.name,
|
||||||
repositoryName: repository.name,
|
repositoryName: repository.name,
|
||||||
scheduleName: schedule.name,
|
scheduleName: schedule.name,
|
||||||
error: `${errorDetails}\n\nFailed after ${maxRetries} retry attempts.`,
|
error: errorNotificationMessage,
|
||||||
})
|
})
|
||||||
.catch((notifyError) => {
|
.catch((notifyError) => {
|
||||||
logger.error(`Failed to send backup failure notification: ${toMessage(notifyError)}`);
|
logger.error(`Failed to send backup failure notification: ${toMessage(notifyError)}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue