mirror of
https://github.com/modrinth/code.git
synced 2026-09-03 13:36:48 +00:00
feat: use split up backup cancel endpoints (#6217)
This commit is contained in:
@@ -37,6 +37,14 @@ export class ArchonBackupsQueueV1Module extends AbstractModule {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/cancel */
|
||||||
|
public async cancelCreate(serverId: string, worldId: string, operationId: number): Promise<void> {
|
||||||
|
await this.client.request<void>(
|
||||||
|
`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/cancel`,
|
||||||
|
{ api: 'archon', version: 1, method: 'POST' },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/ack */
|
/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/ack */
|
||||||
public async ackRestore(serverId: string, worldId: string, operationId: number): Promise<void> {
|
public async ackRestore(serverId: string, worldId: string, operationId: number): Promise<void> {
|
||||||
await this.client.request<void>(
|
await this.client.request<void>(
|
||||||
@@ -45,6 +53,18 @@ export class ArchonBackupsQueueV1Module extends AbstractModule {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/cancel */
|
||||||
|
public async cancelRestore(
|
||||||
|
serverId: string,
|
||||||
|
worldId: string,
|
||||||
|
operationId: number,
|
||||||
|
): Promise<void> {
|
||||||
|
await this.client.request<void>(
|
||||||
|
`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/cancel`,
|
||||||
|
{ api: 'archon', version: 1, method: 'POST' },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/** DELETE /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id */
|
/** DELETE /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id */
|
||||||
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
|
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
|
||||||
await this.client.request<void>(
|
await this.client.request<void>(
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ export class ArchonBackupsV1Module extends AbstractModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use `client.archon.backups_queue_v1.delete` instead.
|
* @deprecated Use `client.archon.backups_queue_v1.delete` for backup deletion, or
|
||||||
|
* `client.archon.backups_queue_v1.cancelCreate` / `cancelRestore` for active operations.
|
||||||
*/
|
*/
|
||||||
/** DELETE /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */
|
/** DELETE /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */
|
||||||
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
|
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
|
||||||
|
|||||||
@@ -314,7 +314,21 @@ async function onBackupCancel(item: BackupAdmonitionEntry) {
|
|||||||
if (cancellingIds.has(item.key)) return
|
if (cancellingIds.has(item.key)) return
|
||||||
cancellingIds.add(item.key)
|
cancellingIds.add(item.key)
|
||||||
try {
|
try {
|
||||||
await client.archon.backups_v1.delete(ctx.serverId, ctx.worldId.value!, item.backupId)
|
if (item.operationId == null) {
|
||||||
|
await client.archon.backups_v1.delete(ctx.serverId, ctx.worldId.value!, item.backupId)
|
||||||
|
} else if (item.type === 'create') {
|
||||||
|
await client.archon.backups_queue_v1.cancelCreate(
|
||||||
|
ctx.serverId,
|
||||||
|
ctx.worldId.value!,
|
||||||
|
item.operationId,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await client.archon.backups_queue_v1.cancelRestore(
|
||||||
|
ctx.serverId,
|
||||||
|
ctx.worldId.value!,
|
||||||
|
item.operationId,
|
||||||
|
)
|
||||||
|
}
|
||||||
await invalidate()
|
await invalidate()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
cancellingIds.delete(item.key)
|
cancellingIds.delete(item.key)
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export function useInlineBackup(backupName: string | (() => string)) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const createdBackupId = ref<string | null>(null)
|
const createdBackupId = ref<string | null>(null)
|
||||||
|
const createdOperationId = ref<number | null>(null)
|
||||||
const pendingCreate = ref(false)
|
const pendingCreate = ref(false)
|
||||||
const backupFailed = ref(false)
|
const backupFailed = ref(false)
|
||||||
const backupComplete = ref(false)
|
const backupComplete = ref(false)
|
||||||
@@ -102,6 +103,16 @@ export function useInlineBackup(backupName: string | (() => string)) {
|
|||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
myActiveOp,
|
||||||
|
(op) => {
|
||||||
|
if (op?.operation_id != null) {
|
||||||
|
createdOperationId.value = op.operation_id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
async function startBackup() {
|
async function startBackup() {
|
||||||
if (!worldId.value) return
|
if (!worldId.value) return
|
||||||
|
|
||||||
@@ -112,6 +123,7 @@ export function useInlineBackup(backupName: string | (() => string)) {
|
|||||||
backupCancelled.value = false
|
backupCancelled.value = false
|
||||||
isCancelling.value = false
|
isCancelling.value = false
|
||||||
createdBackupId.value = null
|
createdBackupId.value = null
|
||||||
|
createdOperationId.value = null
|
||||||
pendingCreate.value = true
|
pendingCreate.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -137,7 +149,18 @@ export function useInlineBackup(backupName: string | (() => string)) {
|
|||||||
|
|
||||||
isCancelling.value = true
|
isCancelling.value = true
|
||||||
try {
|
try {
|
||||||
await client.archon.backups_v1.delete(serverId, worldId.value, createdBackupId.value)
|
let operationId = createdOperationId.value ?? myActiveOp.value?.operation_id ?? null
|
||||||
|
if (operationId == null) {
|
||||||
|
const queue = await client.archon.backups_queue_v1.list(serverId, worldId.value)
|
||||||
|
const operation = queue.active_operations.find(
|
||||||
|
(op) => op.backup_id === createdBackupId.value && op.operation_type === 'create',
|
||||||
|
)
|
||||||
|
operationId = operation?.operation_id ?? null
|
||||||
|
}
|
||||||
|
if (operationId == null) {
|
||||||
|
throw new Error('Could not find the backup creation operation to cancel.')
|
||||||
|
}
|
||||||
|
await client.archon.backups_queue_v1.cancelCreate(serverId, worldId.value, operationId)
|
||||||
backupCancelled.value = true
|
backupCancelled.value = true
|
||||||
isCancelling.value = false
|
isCancelling.value = false
|
||||||
await invalidate()
|
await invalidate()
|
||||||
|
|||||||
@@ -347,10 +347,11 @@ const serverId = route.params.id as string
|
|||||||
|
|
||||||
defineEmits(['onDownload'])
|
defineEmits(['onDownload'])
|
||||||
|
|
||||||
const { backups, invalidate, hasActiveCreate, hasActiveRestore, query } = useServerBackupsQueue(
|
const { backups, invalidate, activeOperationByBackupId, hasActiveCreate, hasActiveRestore, query } =
|
||||||
computed(() => serverId),
|
useServerBackupsQueue(
|
||||||
worldId,
|
computed(() => serverId),
|
||||||
)
|
worldId,
|
||||||
|
)
|
||||||
|
|
||||||
const error = computed(() => {
|
const error = computed(() => {
|
||||||
const err = query.error.value
|
const err = query.error.value
|
||||||
@@ -386,17 +387,37 @@ const deleteQueueMutation = useMutation({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
/** In-progress / incomplete backups: legacy cancel + delete path. */
|
const cancelOperationMutation = useMutation({
|
||||||
const deleteLegacyMutation = useMutation({
|
mutationFn: async (backup: Archon.BackupsQueue.v1.BackupQueueBackup) => {
|
||||||
mutationFn: (backupId: string) =>
|
const activeOperation = activeOperationByBackupId.value.get(backup.id)
|
||||||
client.archon.backups_v1.delete(serverId, worldId.value!, backupId),
|
const historyOperation = backup.history.find(
|
||||||
|
(op) => (op.state === 'pending' || op.state === 'ongoing') && op.operation_id != null,
|
||||||
|
)
|
||||||
|
const operation = activeOperation?.operation_id != null ? activeOperation : historyOperation
|
||||||
|
|
||||||
|
if (operation?.operation_id == null) {
|
||||||
|
await client.archon.backups_v1.delete(serverId, worldId.value!, backup.id)
|
||||||
|
} else if (operation.operation_type === 'create') {
|
||||||
|
await client.archon.backups_queue_v1.cancelCreate(
|
||||||
|
serverId,
|
||||||
|
worldId.value!,
|
||||||
|
operation.operation_id,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await client.archon.backups_queue_v1.cancelRestore(
|
||||||
|
serverId,
|
||||||
|
worldId.value!,
|
||||||
|
operation.operation_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
await invalidate()
|
await invalidate()
|
||||||
await queryClient.invalidateQueries({ queryKey: ['servers', 'detail', serverId] })
|
await queryClient.invalidateQueries({ queryKey: ['servers', 'detail', serverId] })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
/** Bulk delete via queue API — handles both completed and in-progress backups (cancels the latter). */
|
/** Bulk delete selected backups via queue API. */
|
||||||
const deleteManyMutation = useMutation({
|
const deleteManyMutation = useMutation({
|
||||||
mutationFn: (backupIds: string[]) =>
|
mutationFn: (backupIds: string[]) =>
|
||||||
client.archon.backups_queue_v1.deleteMany(serverId, worldId.value!, backupIds),
|
client.archon.backups_queue_v1.deleteMany(serverId, worldId.value!, backupIds),
|
||||||
@@ -557,18 +578,20 @@ function deleteBackup(backup?: Archon.BackupsQueue.v1.BackupQueueBackup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutation = useQueueDeleteFor(backup) ? deleteQueueMutation : deleteLegacyMutation
|
const onError = (err: unknown) => {
|
||||||
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
|
addNotification({
|
||||||
|
type: 'error',
|
||||||
|
title: 'Error deleting backup',
|
||||||
|
text: message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
mutation.mutate(backup.id, {
|
if (useQueueDeleteFor(backup)) {
|
||||||
onError: (err) => {
|
deleteQueueMutation.mutate(backup.id, { onError })
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
} else {
|
||||||
addNotification({
|
cancelOperationMutation.mutate(backup, { onError })
|
||||||
type: 'error',
|
}
|
||||||
title: 'Error deleting backup',
|
|
||||||
text: message,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user