Skip to content

retry prototype - #5

Draft
reeceyang wants to merge 1 commit into
mainfrom
reece/use-retry-prototype
Draft

reeceyang wants to merge 1 commit into
mainfrom
reece/use-retry-prototype

Conversation

@reeceyang

@reeceyang reeceyang commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

@pkg-pr-new

pkg-pr-new Bot commented Jul 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@convex-dev/batch-worker@5

commit: b69ff71

@ianmacartney ianmacartney left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

biggest question is around monitoring.. whether there's a benefit to having the monitor, and if so how we would structure it, given that there isn't a way to query for the suspended function (we don't have an ID available for that)

Comment thread src/component/kick.ts
* fast-looping worker pushes it back roughly once a minute rather than every
* iteration.
*/
export async function ensureMonitored(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we lost the monitoring entirely with this approach? Is there a way to keep it monitored somehow?

Comment thread src/component/schema.ts
workerMutation: v.string(),
config: vConfig.partial(),
status: vStatus,
stateId: v.id("workerState"),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for backwards compatibility, make it deprecated - a helper that marks it as optional(any)

Comment thread src/component/schema.ts
workerState: defineTable({
// Bumped each iteration & on every (re)start. A scheduled loop whose
// generation no longer matches has been superseded and exits.
generation: v.int64(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any protection against multiple loops running at once?

Comment thread src/component/shared.ts
* resumes it.
*/
export const vStatus = v.union(
v.object({ kind: v.literal("idle") }),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: removing this will prevent pushing while the workers are idle, since it's part of the schema

Comment thread README.md

- **`ping`** creates the worker on first call and resumes it when it's idle.
It's a no-op while the loop is running or stopped.
- **`ping`** creates the worker on first call. It's a no-op afterward — while the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should likely rename ping to ensureExists or something

Comment thread src/component/loop.ts
Comment on lines +97 to +104
} catch (e) {
// A genuine failure in the work query or worker mutation. Suspend and
// retry after a backoff instead of dying (replaces the old monitor).
const backoffMs =
worker.config.retryBackoffMs ?? DEFAULT_CONFIG.retryBackoffMs;
console.error(`[loop] "${name}" failed — retrying in ${backoffMs}ms`, e);
console.event("retry", { name });
requestRetry({ timeoutMs: backoffMs });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this assumes we can catch the error and successfully schedule after they throw? I don't think we'll be able to schedule if the query reads too many documents, or times out. (maybe we should add transactionLimits on the runQuery / runMutation calls to at least catch that case)

Comment thread src/component/loop.ts
Comment on lines -51 to -54
if (state.generation !== generation) {
console.debug(
`[loop] "${name}" superseded (gen ${generation} !== ${state.generation})`,
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need this

Comment thread src/component/loop.ts
queryArgs,
)) as BatchResult<Value>;
if (real && "batch" in real) {
console.warn(`[loop] "${name}" snapshot query mismatch`);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should never happen, right? The new work would need to be in pending writes for it not to show up in snapshot query.. or if there's a future change to snapshot query where it's a different snapshot. Fine to leave it, but we shouldn't imply this is expected today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants