Skip to content

Add cluster integration test suite - #6800

Merged
tim-smart merged 9 commits into
mainfrom
test/cluster-integration-suite
Jul 31, 2026
Merged

Add cluster integration test suite#6800
tim-smart merged 9 commits into
mainfrom
test/cluster-integration-suite

Conversation

@tim-smart

@tim-smart tim-smart commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an opt-in Vitest project with suite-wide PostgreSQL and MySQL containers
  • add the in-process socket cluster harness, lifecycle controls, diagnostics, and storage assertions
  • cover entity routing and failover, persistence primitives, and durable workflows against both SQL backends
  • add the manual workflow and contributor documentation

Testing

  • pnpm lint
  • pnpm check
  • EFFECT_CLUSTER_TESTS=1 pnpm test-cluster
  • default @effect/platform-node project exclusion check

Closes EFF-248

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Jul 30, 2026
@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 10f570f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 30 packages
Name Type
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@effect-slopcop effect-slopcop Bot added 4.0 enhancement New feature or request labels Jul 30, 2026
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
basic.ts 6.63 KB 6.63 KB 0.00 KB (0.00%)
batching.ts 9.42 KB 9.42 KB 0.00 KB (0.00%)
brand.ts 6.31 KB 6.31 KB 0.00 KB (0.00%)
cache.ts 10.12 KB 10.12 KB 0.00 KB (0.00%)
config.ts 20.04 KB 20.04 KB 0.00 KB (0.00%)
differ.ts 19.93 KB 19.93 KB 0.00 KB (0.00%)
http-client.ts 20.97 KB 20.97 KB 0.00 KB (0.00%)
logger.ts 10.28 KB 10.28 KB 0.00 KB (0.00%)
metric.ts 8.55 KB 8.55 KB 0.00 KB (0.00%)
optic.ts 7.33 KB 7.33 KB 0.00 KB (0.00%)
pubsub.ts 14.26 KB 14.26 KB 0.00 KB (0.00%)
queue.ts 11.09 KB 11.09 KB 0.00 KB (0.00%)
schedule.ts 10.27 KB 10.27 KB 0.00 KB (0.00%)
schema-class.ts 18.86 KB 18.86 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 28.67 KB 28.67 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 24.99 KB 24.99 KB 0.00 KB (0.00%)
schema-string-transformation.ts 12.95 KB 12.95 KB 0.00 KB (0.00%)
schema-string.ts 10.65 KB 10.65 KB 0.00 KB (0.00%)
schema-template-literal.ts 14.85 KB 14.85 KB 0.00 KB (0.00%)
schema-toArbitraryLazy.ts 21.66 KB 21.66 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.08 KB 24.08 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 18.91 KB 18.91 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 18.73 KB 18.73 KB 0.00 KB (0.00%)
schema-toFormatter.ts 18.59 KB 18.59 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 22.33 KB 22.33 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 19.25 KB 19.25 KB 0.00 KB (0.00%)
schema.ts 18.12 KB 18.12 KB 0.00 KB (0.00%)
stm.ts 12.05 KB 12.05 KB 0.00 KB (0.00%)
stream.ts 9.37 KB 9.37 KB 0.00 KB (0.00%)

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes

  • Cluster integration Vitest project: adds an opt-in cluster-integration project gated behind EFFECT_CLUSTER_TESTS=1 and isNode, with serial execution and a 60-second test timeout.
  • Test container global setup: globalSetup.ts starts one postgres:alpine and one mysql:lts container for the entire suite lifecycle and provides connection URIs via project.provide.
  • Cluster test harness (harness.ts): a scoped multi-runner harness with in-process socket runners, freeze/kill lifecycle controls, deadline-based polling helpers (waitUntil, waitForStableAssignments), and SQL-backed storage assertions (messageCounts, repliedMessageCount, failedMessageCount).
  • Smoke test: starts a 3-runner cluster on both PostgreSQL and MySQL backends, verifies entity RPC delivery, freezes and kills the owning runner, then asserts rebalancing and message persistence.
  • Manual CI workflow: workflow_dispatch-only GitHub Actions job with Docker image pre-pulling and pnpm test-cluster.
  • Vitest config: extends the project helper with projectExclude/projectInclude and excludes test/cluster-integration/** from all non-cluster projects.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏


const registrations = (yield* cluster.diagnostics()).registrations
assert.strictEqual(registrations.length, runners.length)
}).pipe(Effect.scoped))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it.live scopes the effects for you, so this isn't needed

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes

  • Entity integration test suite: adds Entity.test.ts with nine test cases covering entity state isolation and routing, mailbox saturation and idle entity revival, rebalancing across runner addition/graceful stop/abrupt death, row-lock and advisory-lock expiry modes, shard-group-targeted entity assignment, singleton migration on owner death, and EntityResource persistence across movement with explicit release.
  • Configurable shard groups and per-runner options: harness.ts now accepts config in MakeOptions and StartOptions (assignedShardGroups, runnerShardWeight) in start(), updating runnerConfig and makeRunnerStorage per-runner so the shard-group and lock-mode tests can tune the cluster without affecting the default harness setup.
  • New harness helpers: exposes clientSharding (the client-side Sharding service), ownersOfShard(ShardId, includeInactive?) for direct ownership assertions on frozen/killed runners, and shardOfEntity as a factored-out alias used by both ownerOfEntity and the entity tests.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes

  • Entity.test.ts closing brace fix: restored the missing }) that closes the outer describe block and for loop, fixing the unterminated module from commit 68e2521.
  • Persistence.test.ts: new test file with seven cases covering the persistence contract end-to-end on both PostgreSQL and MySQL backends — exactly-once delivery after runner restart, stored-reply deduplication by primary key, uninterruptible-request handoff during graceful shutdown, volatile (non-persisted) request discard after abrupt death, typed-failure and defect replay without re-execution, streamed-reply round-trip, and scheduled-message delivery timing.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes since prior Pullfrog review (5769808):

  • Workflow integration test suite: Workflow.test.ts adds seven test cases covering end-to-end execution with caller deduplication, completed-activity replay after abrupt owner death, deferred workflow resume across a whole-cluster restart resolved from another runner, activity retry policy with both success and exhausted-error paths, durable-clock wake after restart, DurableQueue persistence and once-only consumption across restart, and interruption persistence.

  • Cluster cron integration test suite: ClusterCron.test.ts adds five test cases covering per-second cron execution with failure recovery, calculateNextRunFromPrevious mode difference (next-run-from-previous vs next-run-from-current-time), catch-up vs skipIfOlderThan behavior across cluster restart, singleton owner failover without duplicate or missing ticks, and shard-group-targeted singleton assignment with per-group runner isolation.

  • CI script entry: package.json gains the test-cluster script mapping to vitest run --project cluster-integration.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes since prior Pullfrog review (e6de6e7):

  • SqlMessageStorage.replyFromRow null-safety fix: replyKind.WithExit maps to 0, and Number(null) also evaluates to 0, so a null row kind (representing a Chunk reply) was incorrectly deserialized as a WithExit reply, breaking persisted stream recovery. The fix adds a row.kind !== null guard before the comparison.

  • Stream recovery integration test: added a test to Persistence.test.ts that streams chunks from a runner, kills it mid-stream at the third value, starts a replacement, and verifies the stream resumes from lastSentChunkValue with correct deduplication — all five values arrive and message counts are clean. The Streamed handler was updated to respect lastSentChunkValue for subset replay and includes a Latch gate so the test can precisely control when the persisted stream blocks and resumes.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

Comment thread packages/platform-node/test/cluster-integration/ClusterCron.test.ts Outdated
Comment thread packages/platform-node/test/cluster-integration/ClusterCron.test.ts Outdated
@tim-smart
tim-smart merged commit 4dc35f6 into main Jul 31, 2026
18 checks passed
@tim-smart
tim-smart deleted the test/cluster-integration-suite branch July 31, 2026 02:20
@github-project-automation github-project-automation Bot moved this from Discussion Ongoing to Done in PR Backlog Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant