Skip to content

Add @fedify/netlify for async workloads#934

Open
dahlia wants to merge 13 commits into
fedify-dev:mainfrom
dahlia:packages/netlify
Open

Add @fedify/netlify for async workloads#934
dahlia wants to merge 13 commits into
fedify-dev:mainfrom
dahlia:packages/netlify

Conversation

@dahlia

@dahlia dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member

Closes #930.

Why this integration has two halves

Netlify Functions can already serve Fedify's HTTP endpoints, and Netlify Database can provide persistent state through PostgreSQL. The missing part was queue consumption: a request-scoped Function cannot keep MessageQueue.listen() running between invocations.

This integration follows Netlify's execution model instead of trying to recreate a long-lived worker. NetlifyMessageQueue submits Fedify jobs as Async Workloads events, including delayed jobs, while createNetlifyQueueHandler() turns a Function under netlify/functions/ into the consumer. The handler builds a fresh Federation for each invocation, passes the job to processQueuedTask(), and lets processing errors escape so Async Workloads owns retries and dead-letter handling. Invalid envelopes are marked non-retryable because another attempt cannot repair them.

Ordering without expiring locks

Async Workloads routes events in FIFO order, but it may process several events concurrently. A simple lease would still allow a later job to overtake an earlier one, expire during a long task, or spend every retry attempt merely waiting for another invocation.

For each orderingKey, the producer instead reserves a monotonic sequence in a CAS-capable KvStore. Consumers wait for the preceding sequence with the workload's durable step.sleep(). Waiting therefore does not hold a Function open or consume the failure-retry budget, and exclusivity lasts for the whole task rather than for a guessed lease duration.

The PostgreSQL adapter now supplies the CAS operation needed by this protocol. Its table is logged by default, and an existing unlogged table is migrated during initialization, because losing sequence state during PostgreSQL crash recovery could leave accepted events blocked indefinitely. Applications that only store disposable data can still opt into an unlogged table.

Recovery favors delivery safety

An ordered job that reaches its last configured processing attempt releases its sequence before Netlify dead-letters it, which lets later jobs continue. Timeouts and abrupt termination cannot run that cleanup, so skipOrderingSequence() provides an explicit recovery path after an operator has confirmed that the event is permanently dead-lettered.

The producer takes the opposite approach when a send is not acknowledged. A missing response does not prove that Netlify rejected the event, so its sequence remains reserved and NetlifyMessageQueueSendError exposes the ordering metadata for later investigation. Advancing automatically could let subsequent work pass an accepted event and then discard that event when it eventually arrives.

Verification and operating guidance

Portable unit tests use a narrow AsyncWorkloadsClient interface and cover event encoding, delays, retries, malformed input, concurrent ordering, dead-letter progress, ambiguous sends, and manual recovery. A Node.js integration test starts Netlify Dev against a fixture and exercises real delivery, retry, FIFO processing, and continuation after dead-lettering. It loads NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID from the root .env file and skips itself when either value is absent. Deno and Bun report a conditional skip through the same test command.

The package README.md, message queue manual, and deployment manual explain provisioning, retry configuration, the 500 KB event limit, and the need to keep preview federation isolated or disabled. The Astro example applies the same production guard to both its web middleware and workload consumer so a deploy preview cannot publish as the production actor or enqueue work that no consumer will process.

The branch was checked with mise run check, the cross-runtime package suites, the live Netlify Dev integration test, and the package build.

dahlia added 2 commits July 11, 2026 10:22
Introduce @fedify/netlify for durable Fedify queue delivery through
Netlify Functions.  Preserve per-key FIFO processing with crash-safe CAS
state, durable workload sleeps, dead-letter recovery, and conservative
handling of ambiguous sends.

Make PostgresKvStore CAS-capable and logged by default so ordering state
survives PostgreSQL crash recovery.  Add portable unit coverage, a live
Netlify Dev integration test, an Astro example, and deployment docs.

fedify-dev#930

Assisted-by: Codex:gpt-5.6-sol
The Netlify Async Workloads dependency emits the same non-actionable
binary setup warning from every Deno validation process.  Suppress
that diagnostic chatter during code generation, linting, and type
checking while leaving command failures and error output intact.

fedify-dev#930

Assisted-by: Codex:gpt-5.6-sol
@dahlia dahlia added this to the Fedify 2.4 milestone Jul 11, 2026
@dahlia dahlia self-assigned this Jul 11, 2026
@dahlia dahlia added the component/mq Message queue related label Jul 11, 2026
@dahlia dahlia requested review from 2chanhaeng and sij411 as code owners July 11, 2026 01:44
@dahlia dahlia added examples Example code related runtime/netlify Netlify related labels Jul 11, 2026
@netlify

netlify Bot commented Jul 11, 2026

Copy link
Copy Markdown

Deploy Preview for fedify-json-schema canceled.

Name Link
🔨 Latest commit 3331d30
🔍 Latest deploy log https://app.netlify.com/projects/fedify-json-schema/deploys/6a5280c00f69ad0008321800

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c729354-2e7e-4db6-b7fd-d6d04cdaeb3c

📥 Commits

Reviewing files that changed from the base of the PR and between cf18ddf and 3331d30.

📒 Files selected for processing (4)
  • packages/netlify/src/handler.ts
  • packages/netlify/src/mq.ts
  • packages/netlify/test/handler.test.ts
  • packages/netlify/test/mq.test.ts

📝 Walkthrough

Walkthrough

Adds the @fedify/netlify package for Netlify Async Workloads, ordered queue processing, Postgres CAS and persistence updates, deployment documentation, an Astro/Netlify example, workspace configuration, and automated coverage.

Changes

Netlify integration

Layer / File(s) Summary
Package integration and documentation
.github/*, deno.json, pnpm-workspace.yaml, packages/netlify/*, docs/manual/*, CHANGES.md
Registers and packages the Netlify integration, documents setup and queue behavior, and updates release and repository configuration.
Netlify queue and workload runtime
packages/netlify/src/*, packages/fedify/src/federation/*, packages/amqp/src/*, packages/postgres/src/mq.*
Implements Netlify queue submission, ordered processing, workload handling, public exports, and atomic batch capability propagation.
Postgres CAS and persistence behavior
packages/postgres/src/kv.*, packages/postgres/README.md
Adds TTL-aware CAS operations, concurrent initialization, logged-table defaults, unlogged opt-in, and persistence tests.
Astro and Netlify example
examples/netlify-astro/*, examples/test-examples/mod.ts
Adds an Astro federation example with Netlify services, queue consumption, middleware, deployment configuration, and example registration.
Fixtures and automated validation
packages/netlify/fixtures/*, packages/netlify/test/*
Adds Netlify Dev fixtures and tests for enqueueing, retries, ordering, recovery, exports, and integration behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FederationApp
  participant NetlifyMessageQueue
  participant AsyncWorkloads
  participant QueueHandler
  participant PostgresKvStore
  FederationApp->>NetlifyMessageQueue: enqueue message
  NetlifyMessageQueue->>PostgresKvStore: reserve ordering sequence
  NetlifyMessageQueue->>AsyncWorkloads: send workload event
  AsyncWorkloads->>QueueHandler: deliver event
  QueueHandler->>PostgresKvStore: wait for prior sequence
  QueueHandler->>FederationApp: process queued task
  QueueHandler->>PostgresKvStore: complete or skip sequence
Loading

Possibly related PRs

Suggested labels: component/integration, component/build, component/tasks, component/testing

Suggested reviewers: 2chanhaeng, sij411

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the new @fedify/netlify async-workloads integration and matches the main change.
Description check ✅ Passed The description is directly about the Netlify Async Workloads integration and its behavior.
Linked Issues check ✅ Passed The changes cover the requested package, producer/consumer helpers, ordering, docs, tests, workspace integration, and example.
Out of Scope Changes check ✅ Passed No clearly unrelated changes stand out; the extra repo and docs updates support the Netlify integration.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the new @fedify/netlify package, which integrates Fedify's message queue with Netlify Async Workloads, and adds a corresponding Astro example. It also updates @fedify/postgres's PostgresKvStore to support atomic Compare-And-Swap (cas()) operations and to use crash-safe logged tables by default. The review feedback highlights three key improvements: correcting a premature sequence-skipping condition in the Netlify workload handler due to 1-based attempt counting, updating the corresponding unit test to reflect this fix, and replacing to_regclass with a direct ::regclass cast in PostgreSQL to robustly handle mixed-case table names.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/netlify/src/handler.ts
Comment thread packages/netlify/test/handler.test.ts
Comment thread packages/postgres/src/kv.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1642f88ef8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/netlify/src/mq.ts
Comment thread packages/netlify/src/handler.ts Outdated
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.17836% with 54 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/netlify/src/mq.ts 87.96% 19 Missing and 13 partials ⚠️
packages/netlify/src/handler.ts 89.20% 12 Missing and 3 partials ⚠️
packages/postgres/src/kv.ts 90.78% 5 Missing and 2 partials ⚠️
Files with missing lines Coverage Δ
packages/amqp/src/mq.ts 85.60% <100.00%> (+0.57%) ⬆️
packages/fedify/src/federation/mq.ts 86.99% <100.00%> (+0.21%) ⬆️
packages/fedify/src/federation/tasks/enqueue.ts 97.46% <100.00%> (ø)
packages/netlify/src/mod.ts 100.00% <100.00%> (ø)
packages/postgres/src/mq.ts 91.97% <100.00%> (+0.31%) ⬆️
packages/postgres/src/kv.ts 93.82% <90.78%> (-3.09%) ⬇️
packages/netlify/src/handler.ts 89.20% <89.20%> (ø)
packages/netlify/src/mq.ts 87.96% <87.96%> (ø)

... and 9 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/netlify-astro/src/lib/federation.ts`:
- Around line 52-53: Replace the comma operator in the created-value assignment
within the federation key-pair creation logic with a clearer if/else structure:
when context.data.kv.cas is null, await context.data.kv.set(keyPairKey,
serialized) and set created to true; otherwise preserve the existing behavior.

In `@packages/netlify/src/handler.ts`:
- Around line 146-157: Wrap the await options.queue.skipOrderingSequence call in
the catch block of the handler with its own try-catch, preserving and rethrowing
the original processing error even if skipping the ordering sequence fails;
optionally log the skip failure without allowing it to replace the original
error.

In `@packages/postgres/src/kv.ts`:
- Around line 244-262: Document the operational cost in the initialization path
around PostgresKvStore.initialize: note that converting an existing unlogged
table via SET LOGGED rewrites the table and takes an ACCESS EXCLUSIVE lock, and
that the relpersistence probe plus CREATE TABLE check run whenever `#initialized`
is false. Also document that per-invocation callers such as
createNetlifyQueueHandler should pass initialized: true when initialization is
already known to avoid repeated startup round trips.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8acfed68-5cf9-4709-93f8-cd8032a86521

📥 Commits

Reviewing files that changed from the base of the PR and between 5885824 and 1642f88.

⛔ Files ignored due to path filters (2)
  • deno.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (49)
  • .github/CODEOWNERS
  • .gitignore
  • .hongdown.toml
  • AGENTS.md
  • CHANGES.md
  • CONTRIBUTING.md
  • cspell.json
  • deno.json
  • docs/manual/deploy.md
  • docs/manual/mq.md
  • docs/package.json
  • examples/netlify-astro/.gitignore
  • examples/netlify-astro/README.md
  • examples/netlify-astro/astro.config.ts
  • examples/netlify-astro/netlify.toml
  • examples/netlify-astro/netlify/functions/fedify-queue.ts
  • examples/netlify-astro/package.json
  • examples/netlify-astro/src/lib/federation.ts
  • examples/netlify-astro/src/lib/runtime.ts
  • examples/netlify-astro/src/middleware.ts
  • examples/netlify-astro/src/pages/index.astro
  • examples/netlify-astro/tsconfig.json
  • examples/test-examples/mod.ts
  • mise.toml
  • packages/fedify/README.md
  • packages/netlify/README.md
  • packages/netlify/deno.json
  • packages/netlify/fixtures/netlify-dev/.gitignore
  • packages/netlify/fixtures/netlify-dev/netlify.toml
  • packages/netlify/fixtures/netlify-dev/netlify/functions/enqueue.mts
  • packages/netlify/fixtures/netlify-dev/netlify/functions/status.mts
  • packages/netlify/fixtures/netlify-dev/netlify/functions/workload.mts
  • packages/netlify/fixtures/netlify-dev/netlify/lib/runtime.ts
  • packages/netlify/fixtures/netlify-dev/public/index.html
  • packages/netlify/package.json
  • packages/netlify/src/handler.ts
  • packages/netlify/src/mod.ts
  • packages/netlify/src/mq.ts
  • packages/netlify/src/types.ts
  • packages/netlify/test/handler.test.ts
  • packages/netlify/test/integration/netlify.test.ts
  • packages/netlify/test/mq.test.ts
  • packages/netlify/test/package.test.ts
  • packages/netlify/tsdown.config.ts
  • packages/postgres/README.md
  • packages/postgres/src/kv.test.ts
  • packages/postgres/src/kv.ts
  • pnpm-workspace.yaml
  • scripts/check_types.ts

Comment thread examples/netlify-astro/src/lib/federation.ts Outdated
Comment thread packages/netlify/src/handler.ts
Comment thread packages/postgres/src/kv.ts
dahlia added 5 commits July 11, 2026 11:16
Do not let a partially accepted Async Workloads batch masquerade as an
atomic enqueue when Fedify applies one deduplication marker.  Preserve
ordered progress for malformed events, and resolve quoted PostgreSQL
table names correctly during logged-table migration.

fedify-dev#934

Assisted-by: Codex:gpt-5.6-sol
A ParallelMessageQueue that fans out to a backend without enqueueMany is
not atomic itself.  Report that inherited limitation directly so every
caller, not only Fedify's task enqueue path, sees the correct capability.

fedify-dev#934

Assisted-by: Codex:gpt-5.6-sol
PostgreSQL and AMQP enqueueMany implementations send messages one at a
time.  Declare that limitation so batch-level task deduplication rejects
before either backend can accept only part of a batch.

fedify-dev#934

Assisted-by: Codex:gpt-5.6-sol
A queue without enqueueMany cannot pass an atomic batch capability through
the parallel wrapper.  Make the shared adapter test assert the wrapper's
effective capability instead of requiring a literal property copy.

Assisted-by: Codex:gpt-5.6-sol
Keep the ordering-key support table consistent with the new Netlify queue
section, including the CAS-capable store required for strict sequencing.

fedify-dev#934

Assisted-by: Codex:gpt-5.6-sol
@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the @fedify/netlify package, integrating Fedify message queues with Netlify Async Workloads, and adds a corresponding Astro example. It also implements PostgresKvStore.cas() for atomic compare-and-swap operations, changes PostgreSQL tables to be logged by default with automatic migration, and introduces the atomicEnqueueMany property to enforce atomic batch enqueues during deduplication. The review feedback suggests simplifying the PostgreSQL table persistence check by using a native ::regclass cast, which would also allow the removal of the custom quoteIdentifier helper.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/postgres/src/kv.ts
Comment thread packages/postgres/src/kv.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 775f583a04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/netlify/src/mq.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/netlify/README.md (1)

33-38: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep installation instructions consistent with the examples.

Both documentation paths omit dependencies required by their PostgreSQL/Netlify Database examples:

  • packages/netlify/README.md#L33-L38: add @netlify/database, @fedify/postgres, and postgres, or mark them as optional example dependencies.
  • docs/manual/mq.md#L664-L686: add @fedify/postgres and postgres, or separate the PostgreSQL setup into an optional installation path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/netlify/README.md` around lines 33 - 38, Update the installation
instructions in packages/netlify/README.md (lines 33-38) to include
`@netlify/database`, `@fedify/postgres`, and postgres, or clearly mark those
dependencies as optional example requirements. Also update docs/manual/mq.md
(lines 664-686) to include `@fedify/postgres` and postgres, or separate the
PostgreSQL setup into an optional installation path, keeping both documentation
flows consistent with their examples.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/netlify/src/mq.ts`:
- Line 307: Add a concise JSDoc comment directly above the public
atomicEnqueueMany property, documenting that it indicates whether atomic
enqueue-many operations are supported. Keep the existing readonly property and
value unchanged.

---

Outside diff comments:
In `@packages/netlify/README.md`:
- Around line 33-38: Update the installation instructions in
packages/netlify/README.md (lines 33-38) to include `@netlify/database`,
`@fedify/postgres`, and postgres, or clearly mark those dependencies as optional
example requirements. Also update docs/manual/mq.md (lines 664-686) to include
`@fedify/postgres` and postgres, or separate the PostgreSQL setup into an optional
installation path, keeping both documentation flows consistent with their
examples.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ab77acde-c3fd-4624-8374-1b1f2d994cf2

📥 Commits

Reviewing files that changed from the base of the PR and between 1642f88 and 775f583.

📒 Files selected for processing (20)
  • CHANGES.md
  • docs/manual/mq.md
  • docs/manual/tasks.md
  • examples/netlify-astro/src/lib/federation.ts
  • packages/amqp/src/mq.test.ts
  • packages/amqp/src/mq.ts
  • packages/fedify/src/federation/mq.test.ts
  • packages/fedify/src/federation/mq.ts
  • packages/fedify/src/federation/tasks/enqueue.test.ts
  • packages/fedify/src/federation/tasks/enqueue.ts
  • packages/netlify/README.md
  • packages/netlify/src/handler.ts
  • packages/netlify/src/mq.ts
  • packages/netlify/test/handler.test.ts
  • packages/netlify/test/mq.test.ts
  • packages/postgres/README.md
  • packages/postgres/src/kv.test.ts
  • packages/postgres/src/kv.ts
  • packages/postgres/src/mq.test.ts
  • packages/postgres/src/mq.ts

Comment thread packages/netlify/src/mq.ts
Keep the base queue installation small while listing every dependency used
by the PostgreSQL ordering examples.  Separate commands make it clear that
the database packages are needed only for that setup.

fedify-dev#934 (review)

Assisted-by: Codex:gpt-5.6-sol
@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

Addressed the optional PostgreSQL installation documentation in 723d4bd. Both examples now list the dependencies they import without making them mandatory for the base Netlify queue setup.

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the @fedify/netlify package, which integrates Fedify's message queue with Netlify Async Workloads for Netlify Functions. It also adds PostgresKvStore.cas() to @fedify/postgres for atomic key-value operations and updates PostgresKvStore to use logged tables by default. Additionally, a new atomicEnqueueMany property is added to the MessageQueue interface to indicate atomic batch capabilities. A critical PostgreSQL syntax issue was identified in the PostgresKvStore.cas() implementation where schema-qualified table names in the ON CONFLICT DO UPDATE WHERE clause will fail at runtime; a suggestion has been provided to remove the table qualification.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/postgres/src/kv.ts Outdated
dahlia added 3 commits July 11, 2026 22:07
Separate sequence counters for queues that share a key-value store but route
to different workload event names.  Normalize the case-insensitive event
name so equivalent routes still share one ordering namespace.

fedify-dev#934 (comment)

Assisted-by: Codex:gpt-5.6-sol
Expose the inherited MessageQueue documentation on the public capability
flag so generated API references explain why Netlify batches are non-atomic.

fedify-dev#934 (comment)

Assisted-by: Codex:gpt-5.6-sol
Alias the INSERT target before the conflict update so expired-row replacement
can reference the existing row without emitting an invalid schema-qualified
FROM-clause reference.

fedify-dev#934 (comment)

Assisted-by: Codex:gpt-5.6-sol
@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the @fedify/netlify package, which integrates Fedify's message queue with Netlify Async Workloads, and includes a new Astro example. It also implements PostgresKvStore.cas() for atomic key-value operations, changes PostgresKvStore to use logged tables by default, and introduces the atomicEnqueueMany property to the MessageQueue interface to prevent non-atomic batch deduplication. Feedback on the changes suggests optimizing cancelOrderingSequence in NetlifyMessageQueue to avoid redundant database writes when a sequence is already completed or cancelled.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/netlify/src/mq.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf18ddfed7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/netlify/src/handler.ts Outdated
dahlia added 2 commits July 12, 2026 02:43
Let ordering-state updates report that no write is needed, so repeated
completion or cancellation does not issue a redundant CAS operation.

fedify-dev#934 (comment)

Assisted-by: Codex:gpt-5.6-sol
Run ordered task processing as a durable Async Workloads step so a
transient ordering-state completion failure can retry cleanup without
repeating the task side effects.

fedify-dev#934 (comment)

Assisted-by: Codex:gpt-5.6-sol
@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

@dahlia

dahlia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the @fedify/netlify package, enabling integration with Netlify Async Workloads via NetlifyMessageQueue and createNetlifyQueueHandler. It also adds PostgresKvStore.cas() for atomic operations, updates PostgreSQL tables to be logged by default, and introduces the MessageQueue.atomicEnqueueMany property. Feedback on the changes highlights potential runtime errors when handling Temporal.DurationLike plain objects for delay and TTL options, which should be normalized using Temporal.Duration.from. Additionally, a compatibility concern was raised regarding the ALTER TABLE ... SET LOGGED migration, which requires PostgreSQL 15 or later.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

message: Message,
options?: MessageQueueEnqueueOptions,
): Promise<void> {
const delay = options?.delay?.total("milliseconds");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If options.delay is passed as a Temporal.DurationLike plain object (e.g., { seconds: 5 }), options.delay?.total will be undefined, and invoking it as a function will throw a TypeError: options.delay.total is not a function at runtime. Normalizing it with Temporal.Duration.from first ensures safe handling of both Temporal.Duration instances and plain objects.

    const delay = options?.delay == null
      ? undefined
      : Temporal.Duration.from(options.delay).total("milliseconds");

options?: KvStoreSetOptions,
): Promise<boolean> {
await this.initialize();
const ttl = options?.ttl == null ? null : options.ttl.toString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If options.ttl is passed as a Temporal.DurationLike plain object (e.g., { seconds: 10 }), calling options.ttl.toString() will return "[object Object]". This is an invalid interval format for PostgreSQL and will cause a database error at runtime. Normalizing it with Temporal.Duration.from first ensures that we always get a valid ISO 8601 duration string (e.g., PT10S).

    const ttl = options?.ttl == null
      ? null
      : Temporal.Duration.from(options.ttl).toString();

Comment on lines +261 to +265
if (persistence[0]?.relpersistence === "u") {
await this.#sql`
ALTER TABLE ${this.#sql(this.#tableName)} SET LOGGED;
`;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Note that ALTER TABLE ... SET LOGGED is only supported in PostgreSQL 15 and later. If users are running PostgreSQL 14 or older, this migration will fail with a syntax error on startup. Consider documenting this requirement or gracefully handling the error if older PostgreSQL versions need to be supported.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 3331d30236

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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

Labels

component/mq Message queue related examples Example code related runtime/netlify Netlify related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@fedify/netlify for Netlify Async Workloads

1 participant