Prepare worker and Discord snapshots through bounded catch-up
This commit is contained in:
@@ -54,15 +54,17 @@ export function createDiscordRoutes(db: AppDatabase, config: CommandConfig, now
|
||||
// Help needs no account creation, habit synchronization, or saved UI state.
|
||||
if (i.type === 2 && i.data?.name === 'help') return c.json(help(!!i.guild_id, config.origin));
|
||||
let pending: (() => Promise<DeferredMessage>) | undefined;
|
||||
const reply = db.transaction((): Reply => {
|
||||
const existing = db.select().from(users).where(eq(users.discordId, profile.id)).get();
|
||||
const userId = existing?.id ?? crypto.randomUUID();
|
||||
if (!existing) db.insert(users).values({ id: userId, discordId: profile.id, username: profile.username, globalName: profile.global_name, avatarHash: profile.avatar, createdAt: now(), updatedAt: now() }).run();
|
||||
// Resolve the account before queueing catch-up; no transaction is held across yields.
|
||||
const existing = db.select().from(users).where(eq(users.discordId, profile.id)).get();
|
||||
const userId = existing?.id ?? crypto.randomUUID();
|
||||
if (!existing) db.insert(users).values({ id: userId, discordId: profile.id, username: profile.username, globalName: profile.global_name, avatarHash: profile.avatar, createdAt: now(), updatedAt: now() }).run();
|
||||
const receipt = db.select().from(discordReceipts).where(eq(discordReceipts.id, i.id)).get();
|
||||
if (receipt && receipt.expiresAt > now()) return c.json(receipt.response);
|
||||
const owner = publicUser(db.select().from(users).where(eq(users.id, userId)).get()!);
|
||||
const reply = await HabitService.withPrepared(db, owner, now, service => db.transaction((): Reply => {
|
||||
const receipt = db.select().from(discordReceipts).where(eq(discordReceipts.id, i.id)).get();
|
||||
if (receipt && receipt.expiresAt > now()) return receipt.response;
|
||||
const user = publicUser(db.select().from(users).where(eq(users.id, userId)).get()!);
|
||||
const controls = new ControlStore(db, userId, now()); controls.prune();
|
||||
const service = new HabitService(db, user, now()); service.sync();
|
||||
const ctx: Context = { db, service, controls, interaction: i, now: now(), origin: config.origin, remindersAvailable: config.remindersAvailable ?? false, changed: () => changed(userId), progress: dispatch.progress, defer: i.token ? job => { pending = job; } : undefined };
|
||||
let result: Reply;
|
||||
try {
|
||||
@@ -83,7 +85,7 @@ export function createDiscordRoutes(db: AppDatabase, config: CommandConfig, now
|
||||
}
|
||||
db.insert(discordReceipts).values({ id: i.id, userId, response: result, expiresAt: now() + 86400000 }).run();
|
||||
return result;
|
||||
});
|
||||
}));
|
||||
if (pending) {
|
||||
const work = pending;
|
||||
const job = async () => {
|
||||
|
||||
Reference in New Issue
Block a user