@rikalabs/akter 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +116 -0
- package/dist/actor/codecs.d.ts +77 -0
- package/dist/actor/codecs.js +87 -0
- package/dist/actor/connections.d.ts +34 -0
- package/dist/actor/connections.js +145 -0
- package/dist/actor/definition.d.ts +893 -0
- package/dist/actor/definition.js +147 -0
- package/dist/actor/descriptor.d.ts +172 -0
- package/dist/actor/descriptor.js +367 -0
- package/dist/actor/handles.d.ts +77 -0
- package/dist/actor/handles.js +265 -0
- package/dist/actor/jobs.d.ts +10 -0
- package/dist/actor/jobs.js +137 -0
- package/dist/actor/layers.d.ts +41 -0
- package/dist/actor/layers.js +177 -0
- package/dist/actor/reads.d.ts +47 -0
- package/dist/actor/reads.js +224 -0
- package/dist/actor/served.d.ts +120 -0
- package/dist/actor/served.js +72 -0
- package/dist/actor/turns.d.ts +13 -0
- package/dist/actor/turns.js +332 -0
- package/dist/actor/workflows.d.ts +16 -0
- package/dist/actor/workflows.js +37 -0
- package/dist/client/calls.d.ts +47 -0
- package/dist/client/calls.js +425 -0
- package/dist/client/clock.d.ts +56 -0
- package/dist/client/clock.js +119 -0
- package/dist/client/fleet-page.d.ts +15 -0
- package/dist/client/fleet-page.js +13 -0
- package/dist/client/fleet.d.ts +29 -0
- package/dist/client/fleet.js +51 -0
- package/dist/client/index.d.ts +17 -0
- package/dist/client/index.js +6 -0
- package/dist/client/make.d.ts +157 -0
- package/dist/client/make.js +221 -0
- package/dist/client/offline/queue.d.ts +118 -0
- package/dist/client/offline/queue.js +292 -0
- package/dist/client/offline/store.d.ts +74 -0
- package/dist/client/offline/store.js +78 -0
- package/dist/client/optimistic.d.ts +57 -0
- package/dist/client/optimistic.js +136 -0
- package/dist/client/report.d.ts +2 -0
- package/dist/client/report.js +8 -0
- package/dist/client/sessions/connection.d.ts +118 -0
- package/dist/client/sessions/connection.js +162 -0
- package/dist/client/sessions/feed.d.ts +42 -0
- package/dist/client/sessions/feed.js +43 -0
- package/dist/client/sessions/sse.d.ts +47 -0
- package/dist/client/sessions/sse.js +112 -0
- package/dist/client/sessions/stream.d.ts +28 -0
- package/dist/client/sessions/stream.js +35 -0
- package/dist/client/sessions/watch.d.ts +34 -0
- package/dist/client/sessions/watch.js +40 -0
- package/dist/client/transport.d.ts +37 -0
- package/dist/client/transport.js +66 -0
- package/dist/contexts/command.d.ts +132 -0
- package/dist/contexts/command.js +20 -0
- package/dist/contexts/connection.d.ts +68 -0
- package/dist/contexts/connection.js +0 -0
- package/dist/contexts/job.d.ts +49 -0
- package/dist/contexts/job.js +0 -0
- package/dist/contexts/workflow.d.ts +147 -0
- package/dist/contexts/workflow.js +22 -0
- package/dist/errors/actor.d.ts +200 -0
- package/dist/errors/actor.js +271 -0
- package/dist/errors/content.d.ts +19 -0
- package/dist/errors/content.js +14 -0
- package/dist/errors/database.d.ts +22 -0
- package/dist/errors/database.js +23 -0
- package/dist/errors/events.d.ts +17 -0
- package/dist/errors/events.js +14 -0
- package/dist/errors/subscription.d.ts +12 -0
- package/dist/errors/subscription.js +8 -0
- package/dist/errors/workflow.d.ts +28 -0
- package/dist/errors/workflow.js +17 -0
- package/dist/handles/actors.d.ts +17 -0
- package/dist/handles/actors.js +7 -0
- package/dist/handles/content.d.ts +59 -0
- package/dist/handles/content.js +36 -0
- package/dist/handles/intents.d.ts +164 -0
- package/dist/handles/intents.js +214 -0
- package/dist/handles/run.d.ts +31 -0
- package/dist/handles/run.js +21 -0
- package/dist/handles/workflow.d.ts +27 -0
- package/dist/handles/workflow.js +23 -0
- package/dist/identity/caller.d.ts +105 -0
- package/dist/identity/caller.js +68 -0
- package/dist/identity/child.d.ts +18 -0
- package/dist/identity/child.js +39 -0
- package/dist/identity/command.d.ts +19 -0
- package/dist/identity/command.js +21 -0
- package/dist/identity/connection.d.ts +24 -0
- package/dist/identity/connection.js +29 -0
- package/dist/identity/content.d.ts +18 -0
- package/dist/identity/content.js +12 -0
- package/dist/identity/digest.d.ts +4 -0
- package/dist/identity/digest.js +5 -0
- package/dist/identity/execution.d.ts +32 -0
- package/dist/identity/execution.js +63 -0
- package/dist/identity/mint.d.ts +51 -0
- package/dist/identity/mint.js +76 -0
- package/dist/identity/version.d.ts +2 -0
- package/dist/identity/version.js +3 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +97 -0
- package/dist/members/blob.d.ts +43 -0
- package/dist/members/blob.js +29 -0
- package/dist/members/command.d.ts +109 -0
- package/dist/members/command.js +61 -0
- package/dist/members/connection.d.ts +55 -0
- package/dist/members/connection.js +49 -0
- package/dist/members/event.d.ts +36 -0
- package/dist/members/event.js +24 -0
- package/dist/members/job.d.ts +157 -0
- package/dist/members/job.js +67 -0
- package/dist/members/payload.d.ts +93 -0
- package/dist/members/payload.js +145 -0
- package/dist/members/reducer.d.ts +64 -0
- package/dist/members/reducer.js +27 -0
- package/dist/members/stream.d.ts +36 -0
- package/dist/members/stream.js +14 -0
- package/dist/members/subscription.d.ts +182 -0
- package/dist/members/subscription.js +91 -0
- package/dist/members/workflow.d.ts +99 -0
- package/dist/members/workflow.js +2 -0
- package/dist/policies/access.d.ts +35 -0
- package/dist/policies/access.js +6 -0
- package/dist/policies/command.d.ts +127 -0
- package/dist/policies/command.js +45 -0
- package/dist/policies/job.d.ts +28 -0
- package/dist/policies/job.js +60 -0
- package/dist/policies/schedules.d.ts +33 -0
- package/dist/policies/schedules.js +131 -0
- package/dist/protocol/frames.d.ts +66 -0
- package/dist/protocol/frames.js +55 -0
- package/dist/protocol/inspection.d.ts +807 -0
- package/dist/protocol/inspection.js +243 -0
- package/dist/protocol/wire.d.ts +184 -0
- package/dist/protocol/wire.js +150 -0
- package/dist/runtime/actors.d.ts +155 -0
- package/dist/runtime/actors.js +4 -0
- package/dist/runtime/admission.d.ts +34 -0
- package/dist/runtime/admission.js +72 -0
- package/dist/runtime/adoption/backfill.d.ts +27 -0
- package/dist/runtime/adoption/backfill.js +144 -0
- package/dist/runtime/adoption/enforce.d.ts +55 -0
- package/dist/runtime/adoption/enforce.js +241 -0
- package/dist/runtime/adoption/observe.d.ts +43 -0
- package/dist/runtime/adoption/observe.js +139 -0
- package/dist/runtime/adoption/plan.d.ts +45 -0
- package/dist/runtime/adoption/plan.js +192 -0
- package/dist/runtime/adoption/startup.d.ts +32 -0
- package/dist/runtime/adoption/startup.js +76 -0
- package/dist/runtime/adoption/status.d.ts +23 -0
- package/dist/runtime/adoption/status.js +47 -0
- package/dist/runtime/adoption/target.d.ts +33 -0
- package/dist/runtime/adoption/target.js +49 -0
- package/dist/runtime/connections/holder.d.ts +221 -0
- package/dist/runtime/connections/holder.js +816 -0
- package/dist/runtime/connections/owner.d.ts +263 -0
- package/dist/runtime/connections/owner.js +896 -0
- package/dist/runtime/connections/protocol.d.ts +441 -0
- package/dist/runtime/connections/protocol.js +222 -0
- package/dist/runtime/connections/reads.d.ts +24 -0
- package/dist/runtime/connections/reads.js +19 -0
- package/dist/runtime/connections/streams.d.ts +62 -0
- package/dist/runtime/connections/streams.js +128 -0
- package/dist/runtime/connections/transport.d.ts +40 -0
- package/dist/runtime/connections/transport.js +68 -0
- package/dist/runtime/connections/watch.d.ts +52 -0
- package/dist/runtime/connections/watch.js +159 -0
- package/dist/runtime/content/grant.d.ts +34 -0
- package/dist/runtime/content/grant.js +58 -0
- package/dist/runtime/content/store.d.ts +63 -0
- package/dist/runtime/content/store.js +294 -0
- package/dist/runtime/cron/key.d.ts +2 -0
- package/dist/runtime/cron/key.js +2 -0
- package/dist/runtime/cron/schedule.d.ts +69 -0
- package/dist/runtime/cron/schedule.js +144 -0
- package/dist/runtime/database/bounded.d.ts +43 -0
- package/dist/runtime/database/bounded.js +108 -0
- package/dist/runtime/database/connection.d.ts +8 -0
- package/dist/runtime/database/connection.js +18 -0
- package/dist/runtime/database/coordination.d.ts +19 -0
- package/dist/runtime/database/coordination.js +72 -0
- package/dist/runtime/database/flock.d.ts +10 -0
- package/dist/runtime/database/flock.js +60 -0
- package/dist/runtime/database/gate.d.ts +26 -0
- package/dist/runtime/database/gate.js +54 -0
- package/dist/runtime/database/keepalive.d.ts +11 -0
- package/dist/runtime/database/keepalive.js +22 -0
- package/dist/runtime/database/migrations.d.ts +177 -0
- package/dist/runtime/database/migrations.js +1018 -0
- package/dist/runtime/database/neki/migrations.d.ts +31 -0
- package/dist/runtime/database/neki/migrations.js +276 -0
- package/dist/runtime/database/neki/session.d.ts +23 -0
- package/dist/runtime/database/neki/session.js +31 -0
- package/dist/runtime/database/pglite.d.ts +21 -0
- package/dist/runtime/database/pglite.js +74 -0
- package/dist/runtime/database/replica.d.ts +41 -0
- package/dist/runtime/database/replica.js +51 -0
- package/dist/runtime/database/shards.d.ts +21 -0
- package/dist/runtime/database/shards.js +37 -0
- package/dist/runtime/database/snapshot.d.ts +7 -0
- package/dist/runtime/database/snapshot.js +7 -0
- package/dist/runtime/database/tenancy.d.ts +69 -0
- package/dist/runtime/database/tenancy.js +145 -0
- package/dist/runtime/database/transient.d.ts +10 -0
- package/dist/runtime/database/transient.js +25 -0
- package/dist/runtime/drain.d.ts +132 -0
- package/dist/runtime/drain.js +109 -0
- package/dist/runtime/entity/mailbox.d.ts +86 -0
- package/dist/runtime/entity/mailbox.js +121 -0
- package/dist/runtime/entity/register.d.ts +424 -0
- package/dist/runtime/entity/register.js +669 -0
- package/dist/runtime/events/append.d.ts +192 -0
- package/dist/runtime/events/append.js +128 -0
- package/dist/runtime/events/cursor.d.ts +2 -0
- package/dist/runtime/events/cursor.js +5 -0
- package/dist/runtime/events/replay.d.ts +20 -0
- package/dist/runtime/events/replay.js +45 -0
- package/dist/runtime/feeds.d.ts +26 -0
- package/dist/runtime/feeds.js +100 -0
- package/dist/runtime/fleet/checks.d.ts +17 -0
- package/dist/runtime/fleet/checks.js +106 -0
- package/dist/runtime/fleet/maintainer.d.ts +38 -0
- package/dist/runtime/fleet/maintainer.js +383 -0
- package/dist/runtime/fleet/pgoutput.d.ts +41 -0
- package/dist/runtime/fleet/pgoutput.js +102 -0
- package/dist/runtime/fleet/setup.d.ts +36 -0
- package/dist/runtime/fleet/setup.js +58 -0
- package/dist/runtime/fleet/subscribe.d.ts +42 -0
- package/dist/runtime/fleet/subscribe.js +147 -0
- package/dist/runtime/index.d.ts +66 -0
- package/dist/runtime/index.js +37 -0
- package/dist/runtime/inspector/http.d.ts +19 -0
- package/dist/runtime/inspector/http.js +36 -0
- package/dist/runtime/inspector/layer.d.ts +46 -0
- package/dist/runtime/inspector/layer.js +180 -0
- package/dist/runtime/inspector/queries.d.ts +711 -0
- package/dist/runtime/inspector/queries.js +494 -0
- package/dist/runtime/jobs/attempt.d.ts +254 -0
- package/dist/runtime/jobs/attempt.js +413 -0
- package/dist/runtime/jobs/isolation.d.ts +20 -0
- package/dist/runtime/jobs/isolation.js +10 -0
- package/dist/runtime/jobs/progress.d.ts +95 -0
- package/dist/runtime/jobs/progress.js +144 -0
- package/dist/runtime/layer.d.ts +260 -0
- package/dist/runtime/layer.js +876 -0
- package/dist/runtime/members.d.ts +381 -0
- package/dist/runtime/members.js +8 -0
- package/dist/runtime/operators/audit.d.ts +64 -0
- package/dist/runtime/operators/audit.js +56 -0
- package/dist/runtime/operators/auth.d.ts +29 -0
- package/dist/runtime/operators/auth.js +42 -0
- package/dist/runtime/operators/export.d.ts +68 -0
- package/dist/runtime/operators/export.js +137 -0
- package/dist/runtime/operators/grants.d.ts +45 -0
- package/dist/runtime/operators/grants.js +40 -0
- package/dist/runtime/operators/repair.d.ts +206 -0
- package/dist/runtime/operators/repair.js +226 -0
- package/dist/runtime/operators/routes.d.ts +35 -0
- package/dist/runtime/operators/routes.js +190 -0
- package/dist/runtime/operators/seed.d.ts +123 -0
- package/dist/runtime/operators/seed.js +123 -0
- package/dist/runtime/payloads/versions.d.ts +65 -0
- package/dist/runtime/payloads/versions.js +240 -0
- package/dist/runtime/peering/authority.d.ts +42 -0
- package/dist/runtime/peering/authority.js +132 -0
- package/dist/runtime/peering/credentials.d.ts +21 -0
- package/dist/runtime/peering/credentials.js +13 -0
- package/dist/runtime/peering/transport.d.ts +51 -0
- package/dist/runtime/peering/transport.js +175 -0
- package/dist/runtime/queries.d.ts +18 -0
- package/dist/runtime/queries.js +169 -0
- package/dist/runtime/readiness.d.ts +36 -0
- package/dist/runtime/readiness.js +44 -0
- package/dist/runtime/registration.d.ts +58 -0
- package/dist/runtime/registration.js +186 -0
- package/dist/runtime/request.d.ts +158 -0
- package/dist/runtime/request.js +102 -0
- package/dist/runtime/retry.d.ts +8 -0
- package/dist/runtime/retry.js +11 -0
- package/dist/runtime/runner.d.ts +93 -0
- package/dist/runtime/runner.js +122 -0
- package/dist/runtime/storage/codec.d.ts +39 -0
- package/dist/runtime/storage/codec.js +41 -0
- package/dist/runtime/storage/generation.d.ts +69 -0
- package/dist/runtime/storage/generation.js +49 -0
- package/dist/runtime/storage/placements.d.ts +15 -0
- package/dist/runtime/storage/placements.js +38 -0
- package/dist/runtime/storage/platform.d.ts +6 -0
- package/dist/runtime/storage/platform.js +9 -0
- package/dist/runtime/storage/retention.d.ts +73 -0
- package/dist/runtime/storage/retention.js +158 -0
- package/dist/runtime/subscriptions/identity.d.ts +31 -0
- package/dist/runtime/subscriptions/identity.js +45 -0
- package/dist/runtime/subscriptions/relay.d.ts +175 -0
- package/dist/runtime/subscriptions/relay.js +763 -0
- package/dist/runtime/subscriptions/storage.d.ts +40 -0
- package/dist/runtime/subscriptions/storage.js +98 -0
- package/dist/runtime/sweeps.d.ts +39 -0
- package/dist/runtime/sweeps.js +54 -0
- package/dist/runtime/telemetry/defects.d.ts +57 -0
- package/dist/runtime/telemetry/defects.js +43 -0
- package/dist/runtime/telemetry/metrics.d.ts +52 -0
- package/dist/runtime/telemetry/metrics.js +138 -0
- package/dist/runtime/telemetry/routes.d.ts +19 -0
- package/dist/runtime/telemetry/routes.js +18 -0
- package/dist/runtime/telemetry/sampler.d.ts +26 -0
- package/dist/runtime/telemetry/sampler.js +101 -0
- package/dist/runtime/telemetry/spans.d.ts +38 -0
- package/dist/runtime/telemetry/spans.js +44 -0
- package/dist/runtime/telemetry/usage.d.ts +52 -0
- package/dist/runtime/telemetry/usage.js +30 -0
- package/dist/runtime/topology/admission.d.ts +13 -0
- package/dist/runtime/topology/admission.js +36 -0
- package/dist/runtime/topology/locks.d.ts +56 -0
- package/dist/runtime/topology/locks.js +81 -0
- package/dist/runtime/topology/messages.d.ts +15 -0
- package/dist/runtime/topology/messages.js +32 -0
- package/dist/runtime/turn/admission.d.ts +22 -0
- package/dist/runtime/turn/admission.js +41 -0
- package/dist/runtime/turn/blobs.d.ts +38 -0
- package/dist/runtime/turn/blobs.js +215 -0
- package/dist/runtime/turn/execute.d.ts +208 -0
- package/dist/runtime/turn/execute.js +972 -0
- package/dist/runtime/turn/group.d.ts +165 -0
- package/dist/runtime/turn/group.js +326 -0
- package/dist/runtime/turn/hooks.d.ts +44 -0
- package/dist/runtime/turn/hooks.js +28 -0
- package/dist/runtime/turn/outbox.d.ts +159 -0
- package/dist/runtime/turn/outbox.js +269 -0
- package/dist/runtime/turn/pipeline.d.ts +68 -0
- package/dist/runtime/turn/pipeline.js +83 -0
- package/dist/runtime/turn/receipt.d.ts +81 -0
- package/dist/runtime/turn/receipt.js +32 -0
- package/dist/runtime/turn/relay.d.ts +179 -0
- package/dist/runtime/turn/relay.js +685 -0
- package/dist/runtime/turn/rows.d.ts +43 -0
- package/dist/runtime/turn/rows.js +592 -0
- package/dist/runtime/workflows/compatibility.d.ts +125 -0
- package/dist/runtime/workflows/compatibility.js +285 -0
- package/dist/runtime/workflows/engine.d.ts +107 -0
- package/dist/runtime/workflows/engine.js +826 -0
- package/dist/runtime/workflows/manifest.d.ts +34 -0
- package/dist/runtime/workflows/manifest.js +39 -0
- package/dist/runtime/workflows/steps.d.ts +33 -0
- package/dist/runtime/workflows/steps.js +152 -0
- package/dist/serve/api.d.ts +99 -0
- package/dist/serve/api.js +403 -0
- package/dist/serve/assertion/binding.d.ts +41 -0
- package/dist/serve/assertion/binding.js +92 -0
- package/dist/serve/assertion/verify.d.ts +93 -0
- package/dist/serve/assertion/verify.js +189 -0
- package/dist/serve/auth.d.ts +200 -0
- package/dist/serve/auth.js +92 -0
- package/dist/serve/clock.d.ts +10 -0
- package/dist/serve/clock.js +25 -0
- package/dist/serve/jwt.d.ts +65 -0
- package/dist/serve/jwt.js +202 -0
- package/dist/serve/layer.d.ts +98 -0
- package/dist/serve/layer.js +809 -0
- package/dist/serve/mcp/endpoint.d.ts +39 -0
- package/dist/serve/mcp/endpoint.js +187 -0
- package/dist/serve/mcp/tools.d.ts +37 -0
- package/dist/serve/mcp/tools.js +125 -0
- package/dist/serve/origin.d.ts +6 -0
- package/dist/serve/origin.js +21 -0
- package/dist/serve/sessions/feed.d.ts +79 -0
- package/dist/serve/sessions/feed.js +115 -0
- package/dist/serve/sessions/socket.d.ts +56 -0
- package/dist/serve/sessions/socket.js +212 -0
- package/dist/serve/sessions/sse.d.ts +27 -0
- package/dist/serve/sessions/sse.js +26 -0
- package/dist/serve/sessions/stream.d.ts +9 -0
- package/dist/serve/sessions/stream.js +9 -0
- package/dist/serve/sessions/watch.d.ts +12 -0
- package/dist/serve/sessions/watch.js +11 -0
- package/dist/serve/wire.d.ts +16 -0
- package/dist/serve/wire.js +50 -0
- package/dist/state/blob.d.ts +71 -0
- package/dist/state/blob.js +0 -0
- package/dist/state/migration.d.ts +53 -0
- package/dist/state/migration.js +29 -0
- package/dist/tables/fleet.d.ts +170 -0
- package/dist/tables/fleet.js +214 -0
- package/dist/tables/owned.d.ts +250 -0
- package/dist/tables/owned.js +233 -0
- package/dist/testing/actor-test.d.ts +360 -0
- package/dist/testing/actor-test.js +337 -0
- package/dist/testing/cluster.d.ts +93 -0
- package/dist/testing/cluster.js +296 -0
- package/dist/testing/conformance/access.d.ts +5 -0
- package/dist/testing/conformance/access.js +531 -0
- package/dist/testing/conformance/admission.d.ts +11 -0
- package/dist/testing/conformance/admission.js +182 -0
- package/dist/testing/conformance/adoption.d.ts +2 -0
- package/dist/testing/conformance/adoption.js +1019 -0
- package/dist/testing/conformance/assertions.d.ts +202 -0
- package/dist/testing/conformance/assertions.js +849 -0
- package/dist/testing/conformance/batches.d.ts +41 -0
- package/dist/testing/conformance/batches.js +388 -0
- package/dist/testing/conformance/blobs.d.ts +14 -0
- package/dist/testing/conformance/blobs.js +405 -0
- package/dist/testing/conformance/capacity.d.ts +8 -0
- package/dist/testing/conformance/capacity.js +433 -0
- package/dist/testing/conformance/client.d.ts +5 -0
- package/dist/testing/conformance/client.js +719 -0
- package/dist/testing/conformance/cold-serve.d.ts +16 -0
- package/dist/testing/conformance/cold-serve.js +254 -0
- package/dist/testing/conformance/connections/actors.d.ts +1143 -0
- package/dist/testing/conformance/connections/actors.js +180 -0
- package/dist/testing/conformance/connections/harness.d.ts +1754 -0
- package/dist/testing/conformance/connections/harness.js +142 -0
- package/dist/testing/conformance/connections/holders.d.ts +4 -0
- package/dist/testing/conformance/connections/holders.js +165 -0
- package/dist/testing/conformance/connections/lifecycle.d.ts +4 -0
- package/dist/testing/conformance/connections/lifecycle.js +113 -0
- package/dist/testing/conformance/connections/limits.d.ts +4 -0
- package/dist/testing/conformance/connections/limits.js +127 -0
- package/dist/testing/conformance/connections/reauthorization.d.ts +4 -0
- package/dist/testing/conformance/connections/reauthorization.js +170 -0
- package/dist/testing/conformance/connections/resync.d.ts +4 -0
- package/dist/testing/conformance/connections/resync.js +360 -0
- package/dist/testing/conformance/connections/takeover.d.ts +4 -0
- package/dist/testing/conformance/connections/takeover.js +287 -0
- package/dist/testing/conformance/connections.d.ts +4 -0
- package/dist/testing/conformance/connections.js +15 -0
- package/dist/testing/conformance/content-blobs.d.ts +16 -0
- package/dist/testing/conformance/content-blobs.js +534 -0
- package/dist/testing/conformance/counter.d.ts +16 -0
- package/dist/testing/conformance/counter.js +813 -0
- package/dist/testing/conformance/cron.d.ts +5 -0
- package/dist/testing/conformance/cron.js +665 -0
- package/dist/testing/conformance/drain.d.ts +26 -0
- package/dist/testing/conformance/drain.js +540 -0
- package/dist/testing/conformance/effect-control.d.ts +38 -0
- package/dist/testing/conformance/effect-control.js +1059 -0
- package/dist/testing/conformance/effects.d.ts +23 -0
- package/dist/testing/conformance/effects.js +432 -0
- package/dist/testing/conformance/events.d.ts +28 -0
- package/dist/testing/conformance/events.js +335 -0
- package/dist/testing/conformance/export.d.ts +2 -0
- package/dist/testing/conformance/export.js +368 -0
- package/dist/testing/conformance/fleet.d.ts +444 -0
- package/dist/testing/conformance/fleet.js +1009 -0
- package/dist/testing/conformance/groups.d.ts +7 -0
- package/dist/testing/conformance/groups.js +353 -0
- package/dist/testing/conformance/heap.d.ts +3 -0
- package/dist/testing/conformance/heap.js +149 -0
- package/dist/testing/conformance/http.d.ts +2809 -0
- package/dist/testing/conformance/http.js +1234 -0
- package/dist/testing/conformance/inspection-views.d.ts +8 -0
- package/dist/testing/conformance/inspection-views.js +272 -0
- package/dist/testing/conformance/inspector.d.ts +7 -0
- package/dist/testing/conformance/inspector.js +650 -0
- package/dist/testing/conformance/mint.d.ts +58 -0
- package/dist/testing/conformance/mint.js +692 -0
- package/dist/testing/conformance/multi-runner.d.ts +8 -0
- package/dist/testing/conformance/multi-runner.js +403 -0
- package/dist/testing/conformance/neki/plan.d.ts +19 -0
- package/dist/testing/conformance/neki/plan.js +30 -0
- package/dist/testing/conformance/observability.d.ts +3 -0
- package/dist/testing/conformance/observability.js +343 -0
- package/dist/testing/conformance/offline.d.ts +4 -0
- package/dist/testing/conformance/offline.js +474 -0
- package/dist/testing/conformance/operator-harness.d.ts +57 -0
- package/dist/testing/conformance/operator-harness.js +78 -0
- package/dist/testing/conformance/operator.d.ts +3 -0
- package/dist/testing/conformance/operator.js +379 -0
- package/dist/testing/conformance/outbox-cross-shard.d.ts +14 -0
- package/dist/testing/conformance/outbox-cross-shard.js +160 -0
- package/dist/testing/conformance/outbox.d.ts +36 -0
- package/dist/testing/conformance/outbox.js +437 -0
- package/dist/testing/conformance/payload-migrations.d.ts +3 -0
- package/dist/testing/conformance/payload-migrations.js +612 -0
- package/dist/testing/conformance/pipeline.d.ts +3 -0
- package/dist/testing/conformance/pipeline.js +1040 -0
- package/dist/testing/conformance/placement.d.ts +22 -0
- package/dist/testing/conformance/placement.js +539 -0
- package/dist/testing/conformance/platform.d.ts +40 -0
- package/dist/testing/conformance/platform.js +101 -0
- package/dist/testing/conformance/progress.d.ts +39 -0
- package/dist/testing/conformance/progress.js +666 -0
- package/dist/testing/conformance/properties.d.ts +6 -0
- package/dist/testing/conformance/properties.js +295 -0
- package/dist/testing/conformance/protocols.d.ts +4 -0
- package/dist/testing/conformance/protocols.js +618 -0
- package/dist/testing/conformance/provider/advertise.d.ts +21 -0
- package/dist/testing/conformance/provider/advertise.js +44 -0
- package/dist/testing/conformance/read-your-writes.d.ts +20 -0
- package/dist/testing/conformance/read-your-writes.js +192 -0
- package/dist/testing/conformance/reducers.d.ts +8 -0
- package/dist/testing/conformance/reducers.js +258 -0
- package/dist/testing/conformance/relay.d.ts +42 -0
- package/dist/testing/conformance/relay.js +1115 -0
- package/dist/testing/conformance/restore.d.ts +43 -0
- package/dist/testing/conformance/restore.js +341 -0
- package/dist/testing/conformance/retention.d.ts +14 -0
- package/dist/testing/conformance/retention.js +463 -0
- package/dist/testing/conformance/rls.d.ts +24 -0
- package/dist/testing/conformance/rls.js +576 -0
- package/dist/testing/conformance/simulation.d.ts +31 -0
- package/dist/testing/conformance/simulation.js +167 -0
- package/dist/testing/conformance/single-shard.d.ts +2 -0
- package/dist/testing/conformance/single-shard.js +125 -0
- package/dist/testing/conformance/singleton.d.ts +3 -0
- package/dist/testing/conformance/singleton.js +293 -0
- package/dist/testing/conformance/statements.d.ts +60 -0
- package/dist/testing/conformance/statements.js +108 -0
- package/dist/testing/conformance/streams.d.ts +7 -0
- package/dist/testing/conformance/streams.js +280 -0
- package/dist/testing/conformance/subscriptions/access.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/access.js +98 -0
- package/dist/testing/conformance/subscriptions/actors.d.ts +4910 -0
- package/dist/testing/conformance/subscriptions/actors.js +372 -0
- package/dist/testing/conformance/subscriptions/cluster.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/cluster.js +89 -0
- package/dist/testing/conformance/subscriptions/delivery.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/delivery.js +253 -0
- package/dist/testing/conformance/subscriptions/deploys.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/deploys.js +162 -0
- package/dist/testing/conformance/subscriptions/epochs.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/epochs.js +169 -0
- package/dist/testing/conformance/subscriptions/failures.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/failures.js +108 -0
- package/dist/testing/conformance/subscriptions/feeds.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/feeds.js +218 -0
- package/dist/testing/conformance/subscriptions/harness.d.ts +124 -0
- package/dist/testing/conformance/subscriptions/harness.js +143 -0
- package/dist/testing/conformance/subscriptions/operator.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/operator.js +128 -0
- package/dist/testing/conformance/subscriptions/retention.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/retention.js +288 -0
- package/dist/testing/conformance/subscriptions/routing.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/routing.js +179 -0
- package/dist/testing/conformance/subscriptions.d.ts +4 -0
- package/dist/testing/conformance/subscriptions.js +19 -0
- package/dist/testing/conformance/tables.d.ts +125 -0
- package/dist/testing/conformance/tables.js +664 -0
- package/dist/testing/conformance/transports/actors.d.ts +1907 -0
- package/dist/testing/conformance/transports/actors.js +163 -0
- package/dist/testing/conformance/transports/client.d.ts +3 -0
- package/dist/testing/conformance/transports/client.js +237 -0
- package/dist/testing/conformance/transports/feeds.d.ts +3 -0
- package/dist/testing/conformance/transports/feeds.js +232 -0
- package/dist/testing/conformance/transports/harness.d.ts +93 -0
- package/dist/testing/conformance/transports/harness.js +84 -0
- package/dist/testing/conformance/transports/streams.d.ts +3 -0
- package/dist/testing/conformance/transports/streams.js +96 -0
- package/dist/testing/conformance/transports/websocket.d.ts +3 -0
- package/dist/testing/conformance/transports/websocket.js +384 -0
- package/dist/testing/conformance/transports/wire.d.ts +141 -0
- package/dist/testing/conformance/transports/wire.js +204 -0
- package/dist/testing/conformance/transports.d.ts +3 -0
- package/dist/testing/conformance/transports.js +11 -0
- package/dist/testing/conformance/watch.d.ts +59 -0
- package/dist/testing/conformance/watch.js +879 -0
- package/dist/testing/conformance/workflow-engine.d.ts +97 -0
- package/dist/testing/conformance/workflow-engine.js +253 -0
- package/dist/testing/conformance/workflow-versions.d.ts +3 -0
- package/dist/testing/conformance/workflow-versions.js +545 -0
- package/dist/testing/conformance/workflows/access.d.ts +4 -0
- package/dist/testing/conformance/workflows/access.js +147 -0
- package/dist/testing/conformance/workflows/actors.d.ts +2317 -0
- package/dist/testing/conformance/workflows/actors.js +305 -0
- package/dist/testing/conformance/workflows/basics.d.ts +4 -0
- package/dist/testing/conformance/workflows/basics.js +144 -0
- package/dist/testing/conformance/workflows/engine.d.ts +4 -0
- package/dist/testing/conformance/workflows/engine.js +80 -0
- package/dist/testing/conformance/workflows/guards.d.ts +4 -0
- package/dist/testing/conformance/workflows/guards.js +172 -0
- package/dist/testing/conformance/workflows/harness.d.ts +14 -0
- package/dist/testing/conformance/workflows/harness.js +44 -0
- package/dist/testing/conformance/workflows/recovery.d.ts +4 -0
- package/dist/testing/conformance/workflows/recovery.js +181 -0
- package/dist/testing/conformance/workflows/starts.d.ts +4 -0
- package/dist/testing/conformance/workflows/starts.js +57 -0
- package/dist/testing/conformance/workflows/suspension.d.ts +4 -0
- package/dist/testing/conformance/workflows/suspension.js +106 -0
- package/dist/testing/conformance/workflows/waits.d.ts +4 -0
- package/dist/testing/conformance/workflows/waits.js +284 -0
- package/dist/testing/conformance/workflows.d.ts +4 -0
- package/dist/testing/conformance/workflows.js +19 -0
- package/dist/testing/conformance.d.ts +330 -0
- package/dist/testing/conformance.js +364 -0
- package/dist/testing/database.d.ts +31 -0
- package/dist/testing/database.js +70 -0
- package/dist/testing/foundation.d.ts +41 -0
- package/dist/testing/foundation.js +517 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/property.d.ts +40 -0
- package/dist/testing/property.js +95 -0
- package/dist/testing/simulate-cluster.d.ts +112 -0
- package/dist/testing/simulate-cluster.js +257 -0
- package/dist/testing/simulate.d.ts +90 -0
- package/dist/testing/simulate.js +127 -0
- package/package.json +1 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ActorTest } from "../../actor-test.js";
|
|
3
|
+
import { CLAIM_LEASE } from "../outbox.js";
|
|
4
|
+
import { SubFollower, SubOrder } from "./actors.js";
|
|
5
|
+
import { drain, followerLog, handlerRuns, logOf, run, sourceRows } from "./harness.js";
|
|
6
|
+
/** Blocking, ordering, and backoff of failing subscription deliveries. */
|
|
7
|
+
export const subscriptionFailureConformance = [
|
|
8
|
+
{
|
|
9
|
+
name: "holds later events behind a failing one on the same row only, and interleaves two sources",
|
|
10
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
11
|
+
const test = yield* ActorTest;
|
|
12
|
+
const follower = yield* SubFollower.get("hold-follower");
|
|
13
|
+
yield* follower.Follow({ source: "hold-a" });
|
|
14
|
+
yield* follower.Follow({ source: "hold-b" });
|
|
15
|
+
yield* drain;
|
|
16
|
+
fixture.behave = (entry) => (entry.includes("/hold-a#1:") ? "defect" : "apply");
|
|
17
|
+
yield* (yield* SubOrder.get("hold-a")).PlaceMany({ customerId: "h", count: 2 });
|
|
18
|
+
yield* (yield* SubOrder.get("hold-b")).PlaceMany({ customerId: "h", count: 2 });
|
|
19
|
+
yield* drain;
|
|
20
|
+
expect(yield* followerLog("hold-follower")).toEqual([
|
|
21
|
+
"hold-b#1:OrderPlaced",
|
|
22
|
+
"hold-b#2:OrderPlaced",
|
|
23
|
+
]);
|
|
24
|
+
const [held] = yield* sourceRows("hold-a");
|
|
25
|
+
expect(held).toMatchObject({ delivered: "0", attempts: 1 });
|
|
26
|
+
expect(held.last_error?.includes("Handler defect")).toBe(true);
|
|
27
|
+
fixture.behave = () => "apply";
|
|
28
|
+
yield* test.advance(CLAIM_LEASE);
|
|
29
|
+
expect(yield* followerLog("hold-follower")).toEqual([
|
|
30
|
+
"hold-b#1:OrderPlaced",
|
|
31
|
+
"hold-b#2:OrderPlaced",
|
|
32
|
+
"hold-a#1:OrderPlaced",
|
|
33
|
+
"hold-a#2:OrderPlaced",
|
|
34
|
+
]);
|
|
35
|
+
})),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "holds a routed source's later events for every routed subscriber while one is blocked, and lets other subscriptions of the same source proceed",
|
|
39
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
40
|
+
const test = yield* ActorTest;
|
|
41
|
+
const order = yield* SubOrder.get("blocked-order");
|
|
42
|
+
fixture.behave = (entry) => entry.startsWith("SubSummary/blocked-first/") ? "defect" : "apply";
|
|
43
|
+
yield* order.Place({ customerId: "blocked-first", amount: 1 });
|
|
44
|
+
yield* order.Place({ customerId: "blocked-second", amount: 1 });
|
|
45
|
+
yield* drain;
|
|
46
|
+
expect(yield* logOf("SubSummary", "blocked-first")).toEqual([]);
|
|
47
|
+
expect(yield* logOf("SubSummary", "blocked-second")).toEqual([]);
|
|
48
|
+
expect(yield* logOf("SubAuditor", "blocked-first")).toEqual([
|
|
49
|
+
"blocked-order#1:OrderPlaced",
|
|
50
|
+
]);
|
|
51
|
+
expect(yield* logOf("SubAuditor", "blocked-second")).toEqual([
|
|
52
|
+
"blocked-order#2:OrderPlaced",
|
|
53
|
+
]);
|
|
54
|
+
const [summary] = yield* sourceRows("blocked-order", "SubSummary");
|
|
55
|
+
expect(summary.attempts).toBe(1);
|
|
56
|
+
expect(summary.last_error?.includes("Handler defect")).toBe(true);
|
|
57
|
+
fixture.behave = () => "apply";
|
|
58
|
+
yield* test.advance(CLAIM_LEASE);
|
|
59
|
+
expect(yield* logOf("SubSummary", "blocked-first")).toEqual([
|
|
60
|
+
"blocked-order#1:OrderPlaced",
|
|
61
|
+
]);
|
|
62
|
+
expect(yield* logOf("SubSummary", "blocked-second")).toEqual([
|
|
63
|
+
"blocked-order#2:OrderPlaced",
|
|
64
|
+
]);
|
|
65
|
+
})),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "retries a defecting delivery with capped backoff and records last_error",
|
|
69
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
70
|
+
const test = yield* ActorTest;
|
|
71
|
+
yield* (yield* SubFollower.get("poison-follower")).Follow({ source: "poison-order" });
|
|
72
|
+
yield* drain;
|
|
73
|
+
fixture.behave = (entry) => entry.startsWith("SubFollower/poison-follower/") ? "defect" : "apply";
|
|
74
|
+
yield* (yield* SubOrder.get("poison-order")).Place({ customerId: "p", amount: 1 });
|
|
75
|
+
yield* drain;
|
|
76
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
77
|
+
const [row] = yield* sourceRows("poison-order");
|
|
78
|
+
expect(row).toMatchObject({ attempts: attempt, delivered: "0", due: true });
|
|
79
|
+
expect(row.last_error?.includes("Handler defect on poison-order#1")).toBe(true);
|
|
80
|
+
yield* test.advance(CLAIM_LEASE);
|
|
81
|
+
}
|
|
82
|
+
expect(handlerRuns(fixture, "SubFollower/poison-follower")).toBe(4);
|
|
83
|
+
expect(yield* followerLog("poison-follower")).toEqual([]);
|
|
84
|
+
fixture.behave = () => "apply";
|
|
85
|
+
yield* test.advance("300 seconds");
|
|
86
|
+
expect(yield* followerLog("poison-follower")).toEqual(["poison-order#1:OrderPlaced"]);
|
|
87
|
+
expect(yield* sourceRows("poison-order")).toMatchObject([
|
|
88
|
+
{ attempts: 0, last_error: null, delivered: "1" },
|
|
89
|
+
]);
|
|
90
|
+
})),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "backs a routed row off with last_error when route returns an id the key schema rejects",
|
|
94
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
95
|
+
const test = yield* ActorTest;
|
|
96
|
+
const order = yield* SubOrder.get("badroute-order");
|
|
97
|
+
yield* order.Place({ customerId: "", amount: 1 });
|
|
98
|
+
yield* order.Place({ customerId: "badroute-ok", amount: 1 });
|
|
99
|
+
yield* drain;
|
|
100
|
+
const [summary] = yield* sourceRows("badroute-order", "SubSummary");
|
|
101
|
+
expect(summary.delivered).toBe("0");
|
|
102
|
+
expect(summary.last_error?.startsWith("Route failed")).toBe(true);
|
|
103
|
+
expect(yield* logOf("SubSummary", "badroute-ok")).toEqual([]);
|
|
104
|
+
yield* test.advance(CLAIM_LEASE);
|
|
105
|
+
expect(yield* logOf("SubSummary", "badroute-ok")).toEqual([]);
|
|
106
|
+
})),
|
|
107
|
+
},
|
|
108
|
+
];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConformanceCase } from "../../conformance.ts";
|
|
2
|
+
import { type SubscriptionsFixture } from "./actors.ts";
|
|
3
|
+
/** Feed rows, the tag summary, and wake-ups of event subscriptions. */
|
|
4
|
+
export declare const subscriptionFeedConformance: ReadonlyArray<ConformanceCase<SubscriptionsFixture>>;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { Deferred, Effect, Fiber, Schema } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { ActorTest } from "../../actor-test.js";
|
|
4
|
+
import { CLAIM_LEASE, ExplainOutput, planNodes } from "../outbox.js";
|
|
5
|
+
import { SubFollower, SubOrder } from "./actors.js";
|
|
6
|
+
import { crashOnce, drain, followerLog, handlerRuns, outboxOf, query, run, sourceRows, tagMismatches, } from "./harness.js";
|
|
7
|
+
/** Feed rows, the tag summary, and wake-ups of event subscriptions. */
|
|
8
|
+
export const subscriptionFeedConformance = [
|
|
9
|
+
{
|
|
10
|
+
name: "reactivates a subscription over its tombstone, so the source's next event is delivered",
|
|
11
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
12
|
+
const follower = yield* SubFollower.get("revive-follower");
|
|
13
|
+
yield* follower.Follow({ source: "revive-order" });
|
|
14
|
+
yield* drain;
|
|
15
|
+
yield* follower.Unfollow("revive-order");
|
|
16
|
+
yield* drain;
|
|
17
|
+
expect(yield* sourceRows("revive-order")).toMatchObject([
|
|
18
|
+
{ subscriber_id: "revive-follower", epoch: "2", active: false, due: false },
|
|
19
|
+
]);
|
|
20
|
+
expect(yield* tagMismatches).toEqual([]);
|
|
21
|
+
yield* follower.Follow({ source: "revive-order" });
|
|
22
|
+
yield* drain;
|
|
23
|
+
yield* (yield* SubOrder.get("revive-order")).Place({ customerId: "r", amount: 1 });
|
|
24
|
+
yield* drain;
|
|
25
|
+
expect(yield* followerLog("revive-follower")).toEqual(["revive-order#1:OrderPlaced"]);
|
|
26
|
+
expect(yield* sourceRows("revive-order")).toMatchObject([
|
|
27
|
+
{ subscriber_id: "revive-follower", epoch: "3", active: true, delivered: "1" },
|
|
28
|
+
]);
|
|
29
|
+
expect(yield* tagMismatches).toEqual([]);
|
|
30
|
+
})),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "tombstones a caught-up row and delivers Rejected when a resubscribe names a cursor above the source's head",
|
|
34
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
35
|
+
const follower = yield* SubFollower.get("above-follower");
|
|
36
|
+
const order = yield* SubOrder.get("above-order");
|
|
37
|
+
yield* follower.Follow({ source: "above-order" });
|
|
38
|
+
yield* drain;
|
|
39
|
+
yield* order.Place({ customerId: "a", amount: 1 });
|
|
40
|
+
yield* drain;
|
|
41
|
+
expect(yield* sourceRows("above-order")).toMatchObject([
|
|
42
|
+
{ epoch: "1", active: true, delivered: "1", due: false },
|
|
43
|
+
]);
|
|
44
|
+
yield* follower.Follow({ source: "above-order", from: "9" });
|
|
45
|
+
yield* drain;
|
|
46
|
+
yield* order.Place({ customerId: "a", amount: 2 });
|
|
47
|
+
yield* drain;
|
|
48
|
+
expect(yield* followerLog("above-follower")).toEqual([
|
|
49
|
+
"above-order#1:OrderPlaced",
|
|
50
|
+
"above-order!rejected:9",
|
|
51
|
+
]);
|
|
52
|
+
expect(yield* sourceRows("above-order")).toMatchObject([
|
|
53
|
+
{ subscriber_id: "above-follower", epoch: "2", active: false, due: false },
|
|
54
|
+
]);
|
|
55
|
+
expect(yield* tagMismatches).toEqual([]);
|
|
56
|
+
})),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "expands a feed row once its lease ends when the relay dies after claiming it",
|
|
60
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
61
|
+
const test = yield* ActorTest;
|
|
62
|
+
yield* (yield* SubFollower.get("feeddie-follower")).Follow({ source: "feeddie-order" });
|
|
63
|
+
yield* drain;
|
|
64
|
+
const crash = crashOnce(fixture, "afterClaim", (request) => request.command === "$feed" && request.ref.id === "feeddie-order");
|
|
65
|
+
yield* (yield* SubOrder.get("feeddie-order")).Place({ customerId: "f", amount: 1 });
|
|
66
|
+
yield* drain;
|
|
67
|
+
expect(crash.crashed).toBe(true);
|
|
68
|
+
expect(yield* followerLog("feeddie-follower")).toEqual([]);
|
|
69
|
+
expect(yield* outboxOf("SubOrder", "feeddie-order", "feed")).toBe(1);
|
|
70
|
+
yield* test.advance(CLAIM_LEASE);
|
|
71
|
+
expect(yield* followerLog("feeddie-follower")).toEqual(["feeddie-order#1:OrderPlaced"]);
|
|
72
|
+
expect(handlerRuns(fixture, "SubFollower/feeddie-follower")).toBe(1);
|
|
73
|
+
expect(yield* outboxOf("SubOrder", "feeddie-order", "feed")).toBe(0);
|
|
74
|
+
})),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "writes one feed row per publishing turn whatever the subscriber count",
|
|
78
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
79
|
+
const test = yield* ActorTest;
|
|
80
|
+
for (const [source, followers] of [
|
|
81
|
+
["feed-one", 1],
|
|
82
|
+
["feed-many", 12],
|
|
83
|
+
]) {
|
|
84
|
+
for (let index = 0; index < followers; index++)
|
|
85
|
+
yield* (yield* SubFollower.get(`${source}-f${index}`)).Follow({ source });
|
|
86
|
+
yield* drain;
|
|
87
|
+
const pause = yield* test.pauseNext("afterClaim");
|
|
88
|
+
yield* (yield* SubOrder.get(source)).PlaceMany({ customerId: "f", count: 3 });
|
|
89
|
+
const draining = yield* drain.pipe(Effect.forkChild);
|
|
90
|
+
yield* pause.reached;
|
|
91
|
+
expect(yield* outboxOf("SubOrder", source, "feed")).toBe(1);
|
|
92
|
+
expect((yield* test.inspect({ tenant: test.tenant, actor: "SubOrder", id: source })).outbox).toBe(0);
|
|
93
|
+
yield* pause.release;
|
|
94
|
+
yield* Fiber.join(draining);
|
|
95
|
+
expect(yield* outboxOf("SubOrder", source, "feed")).toBe(0);
|
|
96
|
+
for (let index = 0; index < followers; index++)
|
|
97
|
+
expect((yield* followerLog(`${source}-f${index}`)).length).toBe(3);
|
|
98
|
+
}
|
|
99
|
+
})),
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "writes no feed row for an actor with no subscriptions",
|
|
103
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
104
|
+
yield* (yield* SubOrder.get("quiet-order")).Note("nobody listens");
|
|
105
|
+
expect(yield* outboxOf("SubOrder", "quiet-order", "feed")).toBe(0);
|
|
106
|
+
expect(yield* sourceRows("quiet-order")).toEqual([]);
|
|
107
|
+
})),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "probes the tag summary by key with 10^5 non-matching rows",
|
|
111
|
+
requiresIndependentConnections: true,
|
|
112
|
+
timeoutMs: 120_000,
|
|
113
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
114
|
+
const test = yield* ActorTest;
|
|
115
|
+
const sql = yield* SqlClient.SqlClient;
|
|
116
|
+
const routingKey = "1";
|
|
117
|
+
yield* sql `INSERT INTO actor_generations (routing_key, tenant_id, actor_type, actor_id)
|
|
118
|
+
SELECT ${routingKey}::bigint, ${test.tenant}, 'SubProbe', 'p' || n
|
|
119
|
+
FROM generate_series(1, 100000) AS n`.pipe(Effect.orDie);
|
|
120
|
+
yield* sql `INSERT INTO actor_subscription_tags (routing_key, tenant_id, source_type, source_id, event, rows)
|
|
121
|
+
SELECT ${routingKey}::bigint, ${test.tenant}, 'SubProbe', 'p' || n, 'OrderPlaced', 1
|
|
122
|
+
FROM generate_series(1, 100000) AS n`.pipe(Effect.orDie);
|
|
123
|
+
yield* sql `ANALYZE actor_subscription_tags`.pipe(Effect.orDie);
|
|
124
|
+
const [row] = yield* sql `EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
|
|
125
|
+
SELECT 1 FROM actor_subscription_tags t
|
|
126
|
+
WHERE t.routing_key = ${routingKey}::bigint AND t.tenant_id = ${test.tenant}
|
|
127
|
+
AND t.source_type = 'SubProbe' AND t.source_id = 'missing' AND t.event IN ('OrderPlaced', 'OrderCancelled')`.pipe(Effect.orDie);
|
|
128
|
+
const [explained] = yield* Schema.decodeUnknownEffect(ExplainOutput)(row["QUERY PLAN"]).pipe(Effect.orDie);
|
|
129
|
+
const nodes = planNodes(explained.Plan);
|
|
130
|
+
expect(nodes.some((node) => node["Index Name"] === "actor_subscription_tags_pkey")).toBe(true);
|
|
131
|
+
expect(nodes.some((node) => node["Node Type"] === "Seq Scan")).toBe(false);
|
|
132
|
+
expect(explained.Plan["Actual Rows"]).toBe(0);
|
|
133
|
+
expect(nodes.reduce((sum, node) => sum + node["Shared Hit Blocks"] + node["Shared Read Blocks"], 0) < 16).toBe(true);
|
|
134
|
+
yield* sql `DELETE FROM actor_subscription_tags WHERE source_type = 'SubProbe'`.pipe(Effect.orDie);
|
|
135
|
+
yield* sql `DELETE FROM actor_generations WHERE actor_type = 'SubProbe'`.pipe(Effect.orDie);
|
|
136
|
+
})),
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "leases the rows an expansion makes due and starts their delivery without a claim pass",
|
|
140
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
141
|
+
yield* (yield* SubFollower.get("lease-follower")).Follow({ source: "lease-order" });
|
|
142
|
+
yield* drain;
|
|
143
|
+
const order = [];
|
|
144
|
+
const claimed = yield* Deferred.make();
|
|
145
|
+
fixture.hook = (point, request) => {
|
|
146
|
+
if (point === "afterClaim" && request.commandId === "lease-follower") {
|
|
147
|
+
order.push("delivery");
|
|
148
|
+
return Deferred.succeed(claimed, undefined).pipe(Effect.asVoid);
|
|
149
|
+
}
|
|
150
|
+
if (point === "afterExpand" && request.ref.id === "lease-order")
|
|
151
|
+
return Deferred.await(claimed).pipe(Effect.timeout("2 seconds"), Effect.ignore, Effect.andThen(Effect.sync(() => order.push("expanded"))));
|
|
152
|
+
return Effect.void;
|
|
153
|
+
};
|
|
154
|
+
yield* (yield* SubOrder.get("lease-order")).Place({ customerId: "l", amount: 1 });
|
|
155
|
+
yield* drain;
|
|
156
|
+
expect(order).toEqual(["delivery", "expanded"]);
|
|
157
|
+
expect(yield* followerLog("lease-follower")).toEqual(["lease-order#1:OrderPlaced"]);
|
|
158
|
+
expect(yield* sourceRows("lease-order")).toMatchObject([
|
|
159
|
+
{ delivered: "1", due: false, attempts: 0 },
|
|
160
|
+
]);
|
|
161
|
+
})),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "loses no wake when a commit races a settle or an expansion",
|
|
165
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
166
|
+
const test = yield* ActorTest;
|
|
167
|
+
const order = yield* SubOrder.get("race-order");
|
|
168
|
+
yield* (yield* SubFollower.get("race-follower")).Follow({ source: "race-order" });
|
|
169
|
+
yield* drain;
|
|
170
|
+
const pause = yield* test.pauseNext("afterSettleSnapshot");
|
|
171
|
+
yield* order.Place({ customerId: "r", amount: 1 });
|
|
172
|
+
const draining = yield* drain.pipe(Effect.forkChild);
|
|
173
|
+
yield* pause.reached;
|
|
174
|
+
yield* order.Place({ customerId: "r", amount: 2 });
|
|
175
|
+
for (;;) {
|
|
176
|
+
if ((yield* outboxOf("SubOrder", "race-order", "feed")) === 0)
|
|
177
|
+
break;
|
|
178
|
+
yield* Effect.sleep("20 millis");
|
|
179
|
+
}
|
|
180
|
+
yield* pause.release;
|
|
181
|
+
yield* Fiber.join(draining);
|
|
182
|
+
yield* drain;
|
|
183
|
+
expect(yield* followerLog("race-follower")).toEqual([
|
|
184
|
+
"race-order#1:OrderPlaced",
|
|
185
|
+
"race-order#2:OrderPlaced",
|
|
186
|
+
]);
|
|
187
|
+
expect(yield* sourceRows("race-order")).toMatchObject([{ delivered: "2", due: false }]);
|
|
188
|
+
})),
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "keeps a backing-off row's due time when new commits expand the feed",
|
|
192
|
+
run: ({ expect, environment, fixture }) => run(environment, fixture, Effect.gen(function* () {
|
|
193
|
+
const test = yield* ActorTest;
|
|
194
|
+
const order = yield* SubOrder.get("backoff-order");
|
|
195
|
+
yield* (yield* SubFollower.get("backoff-follower")).Follow({ source: "backoff-order" });
|
|
196
|
+
yield* drain;
|
|
197
|
+
fixture.behave = (entry) => entry.startsWith("SubFollower/backoff-follower/") ? "defect" : "apply";
|
|
198
|
+
yield* order.Place({ customerId: "b", amount: 1 });
|
|
199
|
+
yield* drain;
|
|
200
|
+
const due = () => query((sql) => sql `SELECT due_at_ms::text AS due_at_ms
|
|
201
|
+
FROM actor_subscriptions WHERE tenant_id = ${test.tenant}
|
|
202
|
+
AND source_id = 'backoff-order' AND subscriber_id = 'backoff-follower'`).pipe(Effect.map((rows) => rows[0].due_at_ms));
|
|
203
|
+
const backingOff = yield* due();
|
|
204
|
+
yield* order.Place({ customerId: "b", amount: 2 });
|
|
205
|
+
yield* drain;
|
|
206
|
+
expect(yield* due()).toBe(backingOff);
|
|
207
|
+
const [backedOff] = yield* sourceRows("backoff-order");
|
|
208
|
+
expect(backedOff).toMatchObject({ delivered: "0", attempts: 1 });
|
|
209
|
+
expect(backedOff.last_error?.includes("Handler defect")).toBe(true);
|
|
210
|
+
fixture.behave = () => "apply";
|
|
211
|
+
yield* test.advance(CLAIM_LEASE);
|
|
212
|
+
expect(yield* followerLog("backoff-follower")).toEqual([
|
|
213
|
+
"backoff-order#1:OrderPlaced",
|
|
214
|
+
"backoff-order#2:OrderPlaced",
|
|
215
|
+
]);
|
|
216
|
+
})),
|
|
217
|
+
},
|
|
218
|
+
];
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { SqlClient, type SqlError } from "effect/sql";
|
|
3
|
+
import { InternalActors } from "../../../runtime/actors.ts";
|
|
4
|
+
import { Request } from "../../../runtime/request.ts";
|
|
5
|
+
import { type TurnPoint } from "../../../runtime/turn/hooks.ts";
|
|
6
|
+
import { ActorTest } from "../../actor-test.ts";
|
|
7
|
+
import type { ConformanceEnvironment, ConformanceServices } from "../../conformance.ts";
|
|
8
|
+
import { type SubscriptionsFixture } from "./actors.ts";
|
|
9
|
+
export declare const LogState: Schema.Struct<{
|
|
10
|
+
readonly log: Schema.optional<Schema.$Array<Schema.String>>;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const logOf: (actor: string, id: string) => Effect.Effect<readonly string[], never, ActorTest>;
|
|
13
|
+
export declare const query: <A>(statement: (sql: SqlClient.SqlClient) => Effect.Effect<A, SqlError.SqlError>) => Effect.Effect<A, never, SqlClient.SqlClient>;
|
|
14
|
+
/** The source-side rows of one order in the test tenant, of one subscriber type. */
|
|
15
|
+
export declare const sourceRows: (sourceId: string, subscriberType?: string) => Effect.Effect<readonly {
|
|
16
|
+
subscriber_type: string;
|
|
17
|
+
subscription: string;
|
|
18
|
+
subscriber_id: string;
|
|
19
|
+
epoch: string;
|
|
20
|
+
active: boolean;
|
|
21
|
+
delivered: string;
|
|
22
|
+
due: boolean;
|
|
23
|
+
attempts: number;
|
|
24
|
+
last_error: string | null;
|
|
25
|
+
}[], never, ActorTest | SqlClient.SqlClient>;
|
|
26
|
+
/** The subscriber-side cursor rows of one follower in the test tenant. */
|
|
27
|
+
export declare const cursorRows: (actor: string, id: string) => Effect.Effect<readonly {
|
|
28
|
+
subscription: string;
|
|
29
|
+
source_id: string;
|
|
30
|
+
epoch: string;
|
|
31
|
+
active: boolean;
|
|
32
|
+
applied: string;
|
|
33
|
+
}[], never, ActorTest | SqlClient.SqlClient>;
|
|
34
|
+
/** Outbox rows of one kind an actor of the test tenant holds. */
|
|
35
|
+
export declare const outboxOf: (actor: string, id: string, kind: "feed" | "control") => Effect.Effect<number, never, ActorTest | SqlClient.SqlClient>;
|
|
36
|
+
/**
|
|
37
|
+
* Tag summary rows that disagree with the active rows carrying each tag. A
|
|
38
|
+
* missed increment loses wakes, and a missed decrement costs feed writes forever.
|
|
39
|
+
*/
|
|
40
|
+
export declare const tagMismatches: Effect.Effect<readonly {
|
|
41
|
+
event: string;
|
|
42
|
+
counted: number | null;
|
|
43
|
+
summary: number | null;
|
|
44
|
+
}[], never, SqlClient.SqlClient>;
|
|
45
|
+
export declare const drain: Effect.Effect<void, never, ActorTest>;
|
|
46
|
+
/** Makes the first `point` that `match` accepts die, as a crash there would; later ones pass. */
|
|
47
|
+
export declare const crashOnce: (fixture: SubscriptionsFixture, point: TurnPoint, match: (request: Request) => boolean) => {
|
|
48
|
+
crashed: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** Holds the first `point` that `match` accepts until `release`. */
|
|
51
|
+
export declare const pauseOnce: (fixture: SubscriptionsFixture, point: TurnPoint, match: (request: Request) => boolean) => Effect.Effect<{
|
|
52
|
+
reached: Effect.Effect<void, never, never>;
|
|
53
|
+
release: Effect.Effect<void, never, never>;
|
|
54
|
+
}, never, never>;
|
|
55
|
+
/** A fault point of one subscription row's work: its tag and its subscriber, or the delivery command. */
|
|
56
|
+
export declare const subscriber: (id: string) => (request: Request) => boolean;
|
|
57
|
+
/** A follower's committed log, as entries of one source. */
|
|
58
|
+
export declare const followerLog: (id: string) => Effect.Effect<readonly string[], never, ActorTest>;
|
|
59
|
+
export declare const handlerRuns: (fixture: SubscriptionsFixture, prefix: string) => number;
|
|
60
|
+
/** Builds a relay delivery request, as a runner would, for cases that play a stale runner. */
|
|
61
|
+
export declare const deliveryRequest: (options: {
|
|
62
|
+
readonly subscriber: string;
|
|
63
|
+
readonly source: string;
|
|
64
|
+
readonly epoch: string;
|
|
65
|
+
readonly cursor: string;
|
|
66
|
+
/** Re-encodes the delivery with a field a newer schema added. */
|
|
67
|
+
readonly extra?: boolean;
|
|
68
|
+
/** The subscriber type, its subscription, its handler, and the source type; `SubFollower`'s `FollowedOrders` of `SubOrder` by default. */
|
|
69
|
+
readonly route?: {
|
|
70
|
+
readonly actor: string;
|
|
71
|
+
readonly subscription: string;
|
|
72
|
+
readonly command: string;
|
|
73
|
+
readonly source: string;
|
|
74
|
+
};
|
|
75
|
+
}) => Effect.Effect<{
|
|
76
|
+
readonly ref: {
|
|
77
|
+
readonly tenant: string;
|
|
78
|
+
readonly actor: string;
|
|
79
|
+
readonly id: string;
|
|
80
|
+
};
|
|
81
|
+
readonly caller: {
|
|
82
|
+
readonly _tag: "Anonymous";
|
|
83
|
+
} | {
|
|
84
|
+
readonly _tag: "System";
|
|
85
|
+
readonly source: "actor" | "cron" | "job" | "process" | "subscription" | "timer" | "workflow";
|
|
86
|
+
readonly ref?: {
|
|
87
|
+
readonly tenant: string;
|
|
88
|
+
readonly actor: string;
|
|
89
|
+
readonly id: string;
|
|
90
|
+
} | undefined;
|
|
91
|
+
readonly onBehalfOf?: {
|
|
92
|
+
readonly subject: string;
|
|
93
|
+
} | undefined;
|
|
94
|
+
readonly mint?: {
|
|
95
|
+
readonly commandId: string;
|
|
96
|
+
readonly ordinal: number;
|
|
97
|
+
} | undefined;
|
|
98
|
+
} | {
|
|
99
|
+
readonly _tag: "User";
|
|
100
|
+
readonly subject: string;
|
|
101
|
+
};
|
|
102
|
+
readonly command: string;
|
|
103
|
+
readonly commandId: string;
|
|
104
|
+
readonly payload: string;
|
|
105
|
+
readonly external?: boolean | undefined;
|
|
106
|
+
readonly clockOffset?: number | undefined;
|
|
107
|
+
readonly redelivered?: boolean | undefined;
|
|
108
|
+
readonly intent?: {
|
|
109
|
+
readonly tenant: string;
|
|
110
|
+
readonly actor: string;
|
|
111
|
+
readonly id: string;
|
|
112
|
+
} | undefined;
|
|
113
|
+
readonly delivery?: {
|
|
114
|
+
readonly subscription: string;
|
|
115
|
+
readonly sourceType: string;
|
|
116
|
+
readonly sourceId: string;
|
|
117
|
+
readonly epoch: string;
|
|
118
|
+
readonly kind: "event" | "gap" | "rejected";
|
|
119
|
+
readonly position: string;
|
|
120
|
+
} | undefined;
|
|
121
|
+
readonly queuedAtMs?: number | undefined;
|
|
122
|
+
readonly usageToken?: string | undefined;
|
|
123
|
+
}, Schema.SchemaError, ActorTest | InternalActors | SqlClient.SqlClient>;
|
|
124
|
+
export declare const run: <A, E>(environment: ConformanceEnvironment, fixture: SubscriptionsFixture, body: Effect.Effect<A, E, ConformanceServices>) => Promise<A>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { DateTime, Deferred, Effect, Schema } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { InternalActors } from "../../../runtime/actors.js";
|
|
4
|
+
import { Request } from "../../../runtime/request.js";
|
|
5
|
+
import { System } from "../../../identity/caller.js";
|
|
6
|
+
import { deliveryCommandId } from "../../../runtime/subscriptions/identity.js";
|
|
7
|
+
import { RetryTurn } from "../../../runtime/turn/hooks.js";
|
|
8
|
+
import { ActorTest } from "../../actor-test.js";
|
|
9
|
+
import { OrderDelivery, OrderPlaced, reset } from "./actors.js";
|
|
10
|
+
export const LogState = Schema.Struct({ log: Schema.optional(Schema.Array(Schema.String)) });
|
|
11
|
+
export const logOf = Effect.fnUntraced(function* (actor, id) {
|
|
12
|
+
const test = yield* ActorTest;
|
|
13
|
+
const { state } = yield* test.inspect({ tenant: test.tenant, actor, id });
|
|
14
|
+
return (yield* Schema.decodeUnknownEffect(LogState)(state).pipe(Effect.orDie)).log ?? [];
|
|
15
|
+
});
|
|
16
|
+
export const query = (statement) => Effect.gen(function* () {
|
|
17
|
+
return yield* statement(yield* SqlClient.SqlClient);
|
|
18
|
+
}).pipe(Effect.orDie);
|
|
19
|
+
/** The source-side rows of one order in the test tenant, of one subscriber type. */
|
|
20
|
+
export const sourceRows = (sourceId, subscriberType = "SubFollower") => Effect.gen(function* () {
|
|
21
|
+
const test = yield* ActorTest;
|
|
22
|
+
return yield* query((sql) => sql `SELECT subscriber_type, subscription, subscriber_id, epoch::text AS epoch, active,
|
|
23
|
+
delivered::text AS delivered, due_at_ms IS NOT NULL AS due, attempts, last_error
|
|
24
|
+
FROM actor_subscriptions WHERE tenant_id = ${test.tenant} AND source_type = 'SubOrder'
|
|
25
|
+
AND source_id = ${sourceId} AND subscriber_type = ${subscriberType}
|
|
26
|
+
ORDER BY subscription, subscriber_id`);
|
|
27
|
+
});
|
|
28
|
+
/** The subscriber-side cursor rows of one follower in the test tenant. */
|
|
29
|
+
export const cursorRows = (actor, id) => Effect.gen(function* () {
|
|
30
|
+
const test = yield* ActorTest;
|
|
31
|
+
return yield* query((sql) => sql `SELECT subscription, source_id, epoch::text AS epoch, active, applied::text AS applied
|
|
32
|
+
FROM actor_subscription_cursors WHERE tenant_id = ${test.tenant} AND actor_type = ${actor}
|
|
33
|
+
AND actor_id = ${id}
|
|
34
|
+
ORDER BY subscription, source_id`);
|
|
35
|
+
});
|
|
36
|
+
/** Outbox rows of one kind an actor of the test tenant holds. */
|
|
37
|
+
export const outboxOf = (actor, id, kind) => Effect.gen(function* () {
|
|
38
|
+
const test = yield* ActorTest;
|
|
39
|
+
return (yield* query((sql) => sql `SELECT count(*)::int AS count FROM actor_outbox
|
|
40
|
+
WHERE tenant_id = ${test.tenant} AND actor_type = ${actor} AND actor_id = ${id}
|
|
41
|
+
AND kind = ${kind}`))[0].count;
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Tag summary rows that disagree with the active rows carrying each tag. A
|
|
45
|
+
* missed increment loses wakes, and a missed decrement costs feed writes forever.
|
|
46
|
+
*/
|
|
47
|
+
export const tagMismatches = query((sql) => sql `
|
|
48
|
+
SELECT event, a.rows AS counted, t.rows AS summary FROM (
|
|
49
|
+
SELECT routing_key, tenant_id, source_type, source_id, x.tag AS event, count(*)::int AS rows
|
|
50
|
+
FROM actor_subscriptions, unnest(events) AS x(tag)
|
|
51
|
+
WHERE active GROUP BY routing_key, tenant_id, source_type, source_id, x.tag
|
|
52
|
+
) a FULL JOIN actor_subscription_tags t USING (routing_key, tenant_id, source_type, source_id, event)
|
|
53
|
+
WHERE a.rows IS DISTINCT FROM t.rows`);
|
|
54
|
+
export const drain = ActorTest.use((test) => test.advance(0));
|
|
55
|
+
/** Makes the first `point` that `match` accepts die, as a crash there would; later ones pass. */
|
|
56
|
+
export const crashOnce = (fixture, point, match) => {
|
|
57
|
+
const state = { crashed: false };
|
|
58
|
+
fixture.hook = (reached, request) => {
|
|
59
|
+
if (state.crashed || reached !== point || !match(request))
|
|
60
|
+
return Effect.void;
|
|
61
|
+
state.crashed = true;
|
|
62
|
+
return Effect.die(RetryTurn.make({ message: `Injected ${point} crash` }));
|
|
63
|
+
};
|
|
64
|
+
return state;
|
|
65
|
+
};
|
|
66
|
+
/** Holds the first `point` that `match` accepts until `release`. */
|
|
67
|
+
export const pauseOnce = Effect.fnUntraced(function* (fixture, point, match) {
|
|
68
|
+
const reached = yield* Deferred.make();
|
|
69
|
+
const release = yield* Deferred.make();
|
|
70
|
+
let paused = false;
|
|
71
|
+
fixture.hook = (at, request) => {
|
|
72
|
+
if (paused || at !== point || !match(request))
|
|
73
|
+
return Effect.void;
|
|
74
|
+
paused = true;
|
|
75
|
+
return Deferred.succeed(reached, undefined).pipe(Effect.andThen(Deferred.await(release)));
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
reached: Deferred.await(reached),
|
|
79
|
+
release: Deferred.succeed(release, undefined).pipe(Effect.asVoid),
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
/** A fault point of one subscription row's work: its tag and its subscriber, or the delivery command. */
|
|
83
|
+
export const subscriber = (id) => (request) => request.commandId === id || request.ref.id === id;
|
|
84
|
+
/** A follower's committed log, as entries of one source. */
|
|
85
|
+
export const followerLog = (id) => logOf("SubFollower", id);
|
|
86
|
+
export const handlerRuns = (fixture, prefix) => fixture.runs.filter((run) => run.startsWith(prefix)).length;
|
|
87
|
+
const DeliveredOrder = OrderDelivery.members[0];
|
|
88
|
+
const encodeDelivery = Schema.encodeEffect(Schema.fromJsonString(Schema.toCodecJson(Schema.Struct({ value: OrderDelivery }))));
|
|
89
|
+
const encodeWithExtra = Schema.encodeEffect(Schema.fromJsonString(Schema.toCodecJson(Schema.Struct({ value: OrderDelivery, extra: Schema.Boolean }))));
|
|
90
|
+
/** Builds a relay delivery request, as a runner would, for cases that play a stale runner. */
|
|
91
|
+
export const deliveryRequest = Effect.fnUntraced(function* (options) {
|
|
92
|
+
const test = yield* ActorTest;
|
|
93
|
+
const internal = yield* InternalActors;
|
|
94
|
+
const route = options.route ?? {
|
|
95
|
+
actor: "SubFollower",
|
|
96
|
+
subscription: "FollowedOrders",
|
|
97
|
+
command: "OnOrder",
|
|
98
|
+
source: "SubOrder",
|
|
99
|
+
};
|
|
100
|
+
const subscriber = { tenant: test.tenant, actor: route.actor, id: options.subscriber };
|
|
101
|
+
const source = { tenant: test.tenant, actor: route.source, id: options.source };
|
|
102
|
+
const envelope = {
|
|
103
|
+
subscription: route.subscription,
|
|
104
|
+
sourceType: route.source,
|
|
105
|
+
sourceId: options.source,
|
|
106
|
+
epoch: options.epoch,
|
|
107
|
+
kind: "event",
|
|
108
|
+
position: options.cursor,
|
|
109
|
+
};
|
|
110
|
+
const [event] = yield* query((sql) => sql `
|
|
111
|
+
SELECT emitted_at_ms::text AS emitted_at_ms, command_id FROM actor_events
|
|
112
|
+
WHERE tenant_id = ${test.tenant} AND actor_type = ${route.source} AND actor_id = ${options.source}
|
|
113
|
+
AND sequence = ${options.cursor}`);
|
|
114
|
+
const value = DeliveredOrder.make({
|
|
115
|
+
subscription: route.subscription,
|
|
116
|
+
source,
|
|
117
|
+
cursor: options.cursor,
|
|
118
|
+
event: OrderPlaced.make({ customerId: "c", amount: 1 }),
|
|
119
|
+
commandId: event.command_id,
|
|
120
|
+
timestamp: DateTime.makeUnsafe(Number(event.emitted_at_ms)),
|
|
121
|
+
});
|
|
122
|
+
return Request.make({
|
|
123
|
+
ref: subscriber,
|
|
124
|
+
caller: System.make({ source: "subscription", ref: source }),
|
|
125
|
+
command: route.command,
|
|
126
|
+
commandId: yield* deliveryCommandId({
|
|
127
|
+
subscriber,
|
|
128
|
+
envelope,
|
|
129
|
+
issuedAt: Number(event.emitted_at_ms),
|
|
130
|
+
retryWindowMs: internal.retryWindowMs,
|
|
131
|
+
}),
|
|
132
|
+
payload: options.extra === true
|
|
133
|
+
? yield* encodeWithExtra({ value, extra: true })
|
|
134
|
+
: yield* encodeDelivery({ value }),
|
|
135
|
+
delivery: envelope,
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
export const run = (environment, fixture, body) => environment.run(Effect.gen(function* () {
|
|
139
|
+
yield* reset(fixture);
|
|
140
|
+
const result = yield* body;
|
|
141
|
+
yield* reset(fixture);
|
|
142
|
+
return result;
|
|
143
|
+
}));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConformanceCase } from "../../conformance.ts";
|
|
2
|
+
import { type SubscriptionsFixture } from "./actors.ts";
|
|
3
|
+
/** Operator skip and listing of stuck subscription rows. */
|
|
4
|
+
export declare const subscriptionOperatorConformance: ReadonlyArray<ConformanceCase<SubscriptionsFixture>>;
|