feat: add durable asset synchronization worker
This commit is contained in:
@@ -4,6 +4,8 @@ import { session, synchronize } from '$lib/server/application';
|
||||
import { protectMutation } from '$lib/server/http';
|
||||
import { capabilityDisabledReason, capabilityEnabled } from '$lib/server/release-gate';
|
||||
import { configuration } from '$lib/server/config';
|
||||
import { hashSecret } from '$lib/server/security';
|
||||
import { SESSION_COOKIE } from '$lib/server/application';
|
||||
export const POST: RequestHandler = async (event) => {
|
||||
const config = configuration();
|
||||
// Bound origin/session work by the existing anonymous IP bucket first. The
|
||||
@@ -16,8 +18,11 @@ export const POST: RequestHandler = async (event) => {
|
||||
if (current) protectMutation(event, `sync:${current.userId}`, 6);
|
||||
if (!current) return json({ error: 'Connect an EVE character first.' }, { status: 401 });
|
||||
try {
|
||||
const result = await synchronize(current.userId);
|
||||
if (result.failed.length) return json({ ...result, error: `${result.failed.length} character(s) could not synchronize. Previous complete snapshots were preserved; check Characters.` }, { status: 503 });
|
||||
return json(result);
|
||||
const cookie = event.cookies.get(SESSION_COOKIE);
|
||||
if (!cookie) return json({ error: 'Connect an EVE character first.' }, { status: 401 });
|
||||
const result = await synchronize(current.userId, hashSecret(cookie));
|
||||
const failures = result.skipped.filter((entry) => entry.reason !== 'authorization_required');
|
||||
const status = result.queued > 0 ? 202 : failures.some((entry) => entry.reason === 'queue_full') ? 429 : failures.length > 0 ? 503 : 200;
|
||||
return json(result, { status });
|
||||
} catch { return json({ error: 'Synchronization unavailable. Check backend configuration and try again.' }, { status: 503 }); }
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { live, session, SESSION_COOKIE } from '$lib/server/application';
|
||||
import { hashSecret } from '$lib/server/security';
|
||||
import { configuration } from '$lib/server/config';
|
||||
import { boundedJson, protectMutation } from '$lib/server/http';
|
||||
import { capabilityDisabledReason, capabilityEnabled } from '$lib/server/release-gate';
|
||||
|
||||
export const POST: RequestHandler = async (event) => {
|
||||
const config = configuration();
|
||||
protectMutation(event, `sync-cancel:${event.getClientAddress()}`, 6);
|
||||
if (!capabilityEnabled('asset_sync', config.capabilityAllowlist)) return json({ error: capabilityDisabledReason('asset_sync') }, { status: 503 });
|
||||
const current = await session(event);
|
||||
if (current) protectMutation(event, `sync-cancel:${current.userId}`, 6);
|
||||
if (!current) return json({ error: 'Connect an EVE character first.' }, { status: 401 });
|
||||
const body = await boundedJson(event) as { jobId?: unknown } | null;
|
||||
const jobId = body && typeof body.jobId === 'string' ? body.jobId : '';
|
||||
if (!jobId || jobId.length > 128) return json({ error: 'A sync job is required.' }, { status: 400 });
|
||||
const cookie = event.cookies.get(SESSION_COOKIE);
|
||||
if (!cookie) return json({ error: 'Connect an EVE character first.' }, { status: 401 });
|
||||
try {
|
||||
const result = await live().store.cancelSyncJob(current.userId, jobId, hashSecret(cookie));
|
||||
return result ? json(result) : json({ error: 'Sync job not found.' }, { status: 404 });
|
||||
} catch {
|
||||
return json({ error: 'Synchronization cancellation unavailable.' }, { status: 503 });
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { live, session } from '$lib/server/application';
|
||||
import { configuration } from '$lib/server/config';
|
||||
import { capabilityDisabledReason, capabilityEnabled } from '$lib/server/release-gate';
|
||||
|
||||
export const GET: RequestHandler = async (event) => {
|
||||
const config = configuration();
|
||||
if (!capabilityEnabled('asset_sync', config.capabilityAllowlist)) return json({ error: capabilityDisabledReason('asset_sync') }, { status: 503 });
|
||||
const current = await session(event);
|
||||
if (!current) return json({ error: 'Connect an EVE character first.' }, { status: 401 });
|
||||
const jobId = event.url.searchParams.get('job');
|
||||
if (!jobId || jobId.length > 128) return json({ error: 'A sync job is required.' }, { status: 400 });
|
||||
try {
|
||||
const job = await live().store.syncJob(current.userId, jobId);
|
||||
return job ? json(job) : json({ error: 'Sync job not found.' }, { status: 404 });
|
||||
} catch {
|
||||
return json({ error: 'Synchronization status unavailable.' }, { status: 503 });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user