effect 4.0.2 → 4.0.4
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/AGENTS.md +24 -0
- package/CLAUDE.md +24 -0
- package/ai-docs/package.json +2 -2
- package/ai-docs/src/52_graphql/10_basics.ts +111 -0
- package/ai-docs/src/52_graphql/20_testing.ts +45 -0
- package/ai-docs/src/52_graphql/30_batching.ts +116 -0
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +122 -0
- package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
- package/ai-docs/src/52_graphql/index.md +6 -0
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +12 -3
- package/dist/Context.js.map +1 -1
- package/dist/Crypto.d.ts +33 -5
- package/dist/Crypto.d.ts.map +1 -1
- package/dist/Crypto.js +8 -2
- package/dist/Crypto.js.map +1 -1
- package/dist/DateTime.d.ts +9 -6
- package/dist/DateTime.d.ts.map +1 -1
- package/dist/DateTime.js +9 -6
- package/dist/DateTime.js.map +1 -1
- package/dist/Duration.d.ts +6 -6
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +27 -8
- package/dist/Duration.js.map +1 -1
- package/dist/FileSystem.d.ts +44 -2
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/RequestResolver.js +4 -10
- package/dist/RequestResolver.js.map +1 -1
- package/dist/Scheduler.d.ts +9 -0
- package/dist/Scheduler.d.ts.map +1 -1
- package/dist/Scheduler.js +9 -0
- package/dist/Scheduler.js.map +1 -1
- package/dist/Schema.d.ts +481 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +362 -4
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaGetter.d.ts +4 -0
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +52 -33
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +38 -17
- package/dist/Sink.js.map +1 -1
- package/dist/Stdio.d.ts +7 -1
- package/dist/Stdio.d.ts.map +1 -1
- package/dist/Stdio.js +1 -0
- package/dist/Stdio.js.map +1 -1
- package/dist/Stream.d.ts +22 -11
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +21 -6
- package/dist/Stream.js.map +1 -1
- package/dist/Utils.js +8 -3
- package/dist/Utils.js.map +1 -1
- package/dist/ai/AnthropicStructuredOutput.js +0 -2
- package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
- package/dist/ai/Chat.d.ts +2 -2
- package/dist/ai/Chat.d.ts.map +1 -1
- package/dist/ai/LanguageModel.d.ts +38 -7
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +25 -7
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +61 -0
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +196 -44
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +28 -5
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +4 -3
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +5 -0
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +1 -0
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +27 -0
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +33 -10
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +6 -3
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +3 -3
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +8 -5
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts +5 -4
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +3 -3
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Prompt.d.ts +17 -1
- package/dist/cli/Prompt.d.ts.map +1 -1
- package/dist/cli/Prompt.js +119 -114
- package/dist/cli/Prompt.js.map +1 -1
- package/dist/cli/internal/ansi.d.ts +0 -1
- package/dist/cli/internal/ansi.d.ts.map +1 -1
- package/dist/cli/internal/ansi.js +20 -3
- package/dist/cli/internal/ansi.js.map +1 -1
- package/dist/cli/internal/completions/powershell.d.ts +2 -0
- package/dist/cli/internal/completions/powershell.d.ts.map +1 -0
- package/dist/cli/internal/completions/powershell.js +273 -0
- package/dist/cli/internal/completions/powershell.js.map +1 -0
- package/dist/cli/internal/completions/zsh.js +3 -2
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts +3 -3
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +21 -18
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterSchema.d.ts +28 -0
- package/dist/cluster/ClusterSchema.d.ts.map +1 -1
- package/dist/cluster/ClusterSchema.js +30 -0
- package/dist/cluster/ClusterSchema.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +56 -26
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +18 -3
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +31 -11
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +8 -2
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +187 -66
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts +59 -19
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +84 -55
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts +68 -19
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +191 -113
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +104 -37
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/encoding/Sse.d.ts +6 -0
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +62 -70
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/graphql/GraphQL.d.ts +349 -0
- package/dist/graphql/GraphQL.d.ts.map +1 -0
- package/dist/graphql/GraphQL.js +207 -0
- package/dist/graphql/GraphQL.js.map +1 -0
- package/dist/graphql/GraphQLClient.d.ts +562 -0
- package/dist/graphql/GraphQLClient.d.ts.map +1 -0
- package/dist/graphql/GraphQLClient.js +498 -0
- package/dist/graphql/GraphQLClient.js.map +1 -0
- package/dist/graphql/GraphQLClientError.d.ts +445 -0
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
- package/dist/graphql/GraphQLClientError.js +479 -0
- package/dist/graphql/GraphQLClientError.js.map +1 -0
- package/dist/graphql/GraphQLGroup.d.ts +118 -0
- package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
- package/dist/graphql/GraphQLGroup.js +109 -0
- package/dist/graphql/GraphQLGroup.js.map +1 -0
- package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
- package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
- package/dist/graphql/GraphQLMiddleware.js +130 -0
- package/dist/graphql/GraphQLMiddleware.js.map +1 -0
- package/dist/graphql/GraphQLProtocol.d.ts +731 -0
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
- package/dist/graphql/GraphQLProtocol.js +719 -0
- package/dist/graphql/GraphQLProtocol.js.map +1 -0
- package/dist/graphql/GraphQLResolver.d.ts +453 -0
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
- package/dist/graphql/GraphQLResolver.js +552 -0
- package/dist/graphql/GraphQLResolver.js.map +1 -0
- package/dist/graphql/index.d.ts +40 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +41 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/http/FindMyWay/internal/router.js +3 -6
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/HttpClient.d.ts +21 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +63 -12
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +14 -7
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +31 -32
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts +35 -0
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +35 -0
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts +8 -6
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +27 -16
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +4 -2
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/Multipart.d.ts.map +1 -1
- package/dist/http/Multipart.js +15 -1
- package/dist/http/Multipart.js.map +1 -1
- package/dist/http-api/HttpApiScalar.d.ts +5 -0
- package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
- package/dist/http-api/HttpApiScalar.js.map +1 -1
- package/dist/internal/dateTime.js +40 -35
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +19 -9
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.d.ts +2 -0
- package/dist/internal/graphql.d.ts.map +1 -0
- package/dist/internal/graphql.js +195 -0
- package/dist/internal/graphql.js.map +1 -0
- package/dist/internal/graphqlHeaders.d.ts +4 -0
- package/dist/internal/graphqlHeaders.d.ts.map +1 -0
- package/dist/internal/graphqlHeaders.js +11 -0
- package/dist/internal/graphqlHeaders.js.map +1 -0
- package/dist/internal/request.js +20 -1
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +4 -1
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/AddressResolver.d.ts +145 -0
- package/dist/net/AddressResolver.d.ts.map +1 -0
- package/dist/net/AddressResolver.js +114 -0
- package/dist/net/AddressResolver.js.map +1 -0
- package/dist/net/Dns.d.ts +596 -0
- package/dist/net/Dns.d.ts.map +1 -0
- package/dist/net/Dns.js +549 -0
- package/dist/net/Dns.js.map +1 -0
- package/dist/net/Host.d.ts +369 -0
- package/dist/net/Host.d.ts.map +1 -0
- package/dist/net/Host.js +397 -0
- package/dist/net/Host.js.map +1 -0
- package/dist/net/IpInterface.d.ts +76 -3
- package/dist/net/IpInterface.d.ts.map +1 -1
- package/dist/net/IpInterface.js +53 -4
- package/dist/net/IpInterface.js.map +1 -1
- package/dist/net/IpNetwork.d.ts +82 -8
- package/dist/net/IpNetwork.d.ts.map +1 -1
- package/dist/net/IpNetwork.js +60 -4
- package/dist/net/IpNetwork.js.map +1 -1
- package/dist/net/NetAddress.d.ts +396 -35
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +358 -34
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/net/index.d.ts +15 -0
- package/dist/net/index.d.ts.map +1 -1
- package/dist/net/index.js +15 -0
- package/dist/net/index.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +15 -21
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/PrometheusMetrics.js +1 -0
- package/dist/observability/PrometheusMetrics.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +32 -3
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +75 -16
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +22 -6
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +12 -5
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts +6 -0
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +78 -29
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/socket/DatagramSocket.d.ts +456 -0
- package/dist/socket/DatagramSocket.d.ts.map +1 -0
- package/dist/socket/DatagramSocket.js +535 -0
- package/dist/socket/DatagramSocket.js.map +1 -0
- package/dist/socket/Socket.d.ts +20 -1
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js +9 -1
- package/dist/socket/Socket.js.map +1 -1
- package/dist/socket/index.d.ts +5 -0
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +5 -0
- package/dist/socket/index.js.map +1 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +7 -2
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +7 -1
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +31 -6
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestCrypto.d.ts +73 -0
- package/dist/testing/TestCrypto.d.ts.map +1 -0
- package/dist/testing/TestCrypto.js +87 -0
- package/dist/testing/TestCrypto.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts +54 -0
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +108 -50
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +24 -2
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +13 -3
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +6 -3
- package/src/Context.ts +12 -3
- package/src/Crypto.ts +43 -9
- package/src/DateTime.ts +9 -6
- package/src/Duration.ts +36 -16
- package/src/FileSystem.ts +48 -2
- package/src/RequestResolver.ts +4 -10
- package/src/Scheduler.ts +9 -0
- package/src/Schema.ts +677 -5
- package/src/SchemaGetter.ts +47 -35
- package/src/Sink.ts +45 -18
- package/src/Stdio.ts +9 -2
- package/src/Stream.ts +44 -15
- package/src/Utils.ts +8 -5
- package/src/ai/AnthropicStructuredOutput.ts +2 -2
- package/src/ai/Chat.ts +2 -2
- package/src/ai/LanguageModel.ts +96 -24
- package/src/ai/McpServer.ts +288 -94
- package/src/ai/Prompt.ts +24 -10
- package/src/ai/Response.ts +6 -3
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +5 -0
- package/src/ai/internal/mcpProtocol.ts +3 -0
- package/src/ai/internal/mcpRuntime.ts +2 -0
- package/src/cli/CliOutput.ts +33 -16
- package/src/cli/Command.ts +4 -3
- package/src/cli/Completions.ts +9 -6
- package/src/cli/GlobalFlag.ts +19 -11
- package/src/cli/Prompt.ts +159 -149
- package/src/cli/internal/ansi.ts +26 -3
- package/src/cli/internal/completions/powershell.ts +322 -0
- package/src/cli/internal/completions/zsh.ts +4 -2
- package/src/cli/internal/wizard.ts +34 -26
- package/src/cluster/ClusterSchema.ts +32 -0
- package/src/cluster/ClusterWorkflowEngine.ts +64 -36
- package/src/cluster/MessageStorage.ts +45 -14
- package/src/cluster/Runners.ts +8 -2
- package/src/cluster/Sharding.ts +219 -58
- package/src/cluster/SqlMessageStorage.ts +118 -84
- package/src/cluster/SqlRunnerStorage.ts +224 -128
- package/src/cluster/internal/entityManager.ts +151 -55
- package/src/encoding/Sse.ts +69 -79
- package/src/graphql/GraphQL.ts +494 -0
- package/src/graphql/GraphQLClient.ts +912 -0
- package/src/graphql/GraphQLClientError.ts +542 -0
- package/src/graphql/GraphQLGroup.ts +167 -0
- package/src/graphql/GraphQLMiddleware.ts +253 -0
- package/src/graphql/GraphQLProtocol.ts +1286 -0
- package/src/graphql/GraphQLResolver.ts +1010 -0
- package/src/graphql/index.ts +48 -0
- package/src/http/FindMyWay/internal/router.ts +4 -7
- package/src/http/HttpClient.ts +110 -12
- package/src/http/HttpEffect.ts +11 -5
- package/src/http/HttpMiddleware.ts +33 -34
- package/src/http/HttpRouter.ts +35 -0
- package/src/http/HttpServerResponse.ts +28 -16
- package/src/http/HttpTraceContext.ts +8 -2
- package/src/http/Multipart.ts +17 -1
- package/src/http-api/HttpApiScalar.ts +5 -0
- package/src/internal/dateTime.ts +13 -10
- package/src/internal/effect.ts +22 -15
- package/src/internal/graphql.ts +263 -0
- package/src/internal/graphqlHeaders.ts +11 -0
- package/src/internal/request.ts +31 -3
- package/src/internal/schema/toCodeDocument.ts +7 -1
- package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
- package/src/internal/version.ts +1 -1
- package/src/net/AddressResolver.ts +222 -0
- package/src/net/Dns.ts +1035 -0
- package/src/net/Host.ts +544 -0
- package/src/net/IpInterface.ts +117 -7
- package/src/net/IpNetwork.ts +116 -17
- package/src/net/NetAddress.ts +620 -76
- package/src/net/index.ts +18 -0
- package/src/observability/OtlpMetrics.ts +12 -23
- package/src/observability/PrometheusMetrics.ts +1 -0
- package/src/persistence/PersistedQueue.ts +146 -53
- package/src/rpc/RpcClient.ts +41 -19
- package/src/rpc/RpcServer.ts +115 -40
- package/src/socket/DatagramSocket.ts +919 -0
- package/src/socket/Socket.ts +28 -2
- package/src/socket/index.ts +6 -0
- package/src/sql/Migrator.ts +21 -5
- package/src/sql/SqlClient.ts +39 -15
- package/src/testing/TestCrypto.ts +94 -0
- package/src/testing/index.ts +6 -0
- package/src/workflow/DurableDeferred.ts +160 -47
- package/src/workflow/WorkflowEngine.ts +50 -5
|
@@ -15,7 +15,6 @@ import * as Effect from "../Effect.ts"
|
|
|
15
15
|
import * as Exit from "../Exit.ts"
|
|
16
16
|
import * as Fiber from "../Fiber.ts"
|
|
17
17
|
import * as Headers from "../http/Headers.ts"
|
|
18
|
-
import * as Latch from "../Latch.ts"
|
|
19
18
|
import * as Layer from "../Layer.ts"
|
|
20
19
|
import * as Option from "../Option.ts"
|
|
21
20
|
import * as PrimaryKey from "../PrimaryKey.ts"
|
|
@@ -132,7 +131,6 @@ export const make = Effect.gen(function*() {
|
|
|
132
131
|
readonly context: Context.Context<any>
|
|
133
132
|
}>()
|
|
134
133
|
const interruptedActivities = new Set<string>()
|
|
135
|
-
const activityLatches = new Map<string, Latch.Latch>()
|
|
136
134
|
const deferredState = WorkflowEngine.makeDeferredState()
|
|
137
135
|
// Rebuilds share an activation; overlapping activations have separate results.
|
|
138
136
|
// Weak keys do not retain scopes, but contexts captured by clients, activities,
|
|
@@ -293,10 +291,7 @@ export const make = Effect.gen(function*() {
|
|
|
293
291
|
id: ""
|
|
294
292
|
})
|
|
295
293
|
|
|
296
|
-
const maybeSuspended = Option.filter(
|
|
297
|
-
maybeReply,
|
|
298
|
-
(reply) => reply.exit._tag === "Success" && reply.exit.value._tag === "Suspended"
|
|
299
|
-
)
|
|
294
|
+
const maybeSuspended = Option.filter(maybeReply, isSuspendedReply)
|
|
300
295
|
|
|
301
296
|
if (Option.isNone(maybeSuspended)) return
|
|
302
297
|
if (
|
|
@@ -330,10 +325,14 @@ export const make = Effect.gen(function*() {
|
|
|
330
325
|
yield* sharding.reset(requestId.value)
|
|
331
326
|
}, Effect.scoped)
|
|
332
327
|
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
// the
|
|
336
|
-
const
|
|
328
|
+
// Subscribe to the run's next reply before reading storage, so a reply
|
|
329
|
+
// cannot fall between the read and the subscription. Returns `true` when the
|
|
330
|
+
// stored reply already settles the wait, `false` when a new reply arrived.
|
|
331
|
+
const awaitRunReply = Effect.fnUntraced(function*(
|
|
332
|
+
workflow: Workflow.Any,
|
|
333
|
+
request: Envelope.Request<any>,
|
|
334
|
+
isSettled: (reply: WithExitEncoded<Workflow.ResultEncoded<any, any>>) => boolean
|
|
335
|
+
) {
|
|
337
336
|
const waiter = yield* storage.registerReplyHandler(
|
|
338
337
|
new Message.OutgoingRequest<any>({
|
|
339
338
|
envelope: request,
|
|
@@ -345,12 +344,45 @@ export const make = Effect.gen(function*() {
|
|
|
345
344
|
})
|
|
346
345
|
).pipe(Effect.forkScoped({ startImmediately: true }))
|
|
347
346
|
const reply = yield* replyForRequestId(request.requestId)
|
|
348
|
-
if (Option.isSome(reply)) return
|
|
349
|
-
yield* Fiber.join(waiter)
|
|
347
|
+
if (Option.isSome(reply) && isSettled(reply.value)) return true
|
|
348
|
+
yield* Fiber.join(waiter)
|
|
349
|
+
return false
|
|
350
|
+
}, Effect.scoped)
|
|
351
|
+
|
|
352
|
+
// A child or deferred may complete while a run is still unwinding. Wait for
|
|
353
|
+
// the run's reply so the wake cannot fall between the run's last read and
|
|
354
|
+
// its suspended reply.
|
|
355
|
+
const waitForRunReply = (workflow: Workflow.Any, request: Entity.Request<any>) =>
|
|
356
|
+
awaitRunReply(workflow, request, () => true).pipe(
|
|
357
|
+
Effect.asVoid,
|
|
350
358
|
Effect.catchTag("EntityNotAssignedToRunner", () => ClusterAbandon.interrupt),
|
|
351
359
|
Effect.catchCause((cause) => ClusterAbandon.isCause(cause) ? ClusterAbandon.interrupt : Effect.failCause(cause))
|
|
352
360
|
)
|
|
353
|
-
|
|
361
|
+
|
|
362
|
+
// Wake an external caller once its run publishes a reply other than
|
|
363
|
+
// `Suspended`. Replies are only observed on the runner that saves them, so
|
|
364
|
+
// callers on other runners, and any failure here, leave delivery to the
|
|
365
|
+
// caller's retry schedule.
|
|
366
|
+
const awaitComplete = (workflow: Workflow.Any, executionId: string) =>
|
|
367
|
+
Effect.gen(function*() {
|
|
368
|
+
const address = entityAddressFor({ workflow, entityType: `Workflow/${workflow._tag}`, executionId })
|
|
369
|
+
if (!sharding.hasShardId(address.shardId)) return yield* Effect.never
|
|
370
|
+
const requestId = yield* storage.requestIdForPrimaryKey({ address, tag: "run", id: "" })
|
|
371
|
+
if (Option.isNone(requestId)) return yield* Effect.never
|
|
372
|
+
const request = Envelope.makeRequest<any>({
|
|
373
|
+
requestId: requestId.value,
|
|
374
|
+
address,
|
|
375
|
+
tag: "run",
|
|
376
|
+
payload: {},
|
|
377
|
+
headers: Headers.empty
|
|
378
|
+
})
|
|
379
|
+
// A replay that suspends again re-arms the wait, so it does not spend a
|
|
380
|
+
// step of the caller's retry schedule.
|
|
381
|
+
let settled = false
|
|
382
|
+
while (!settled) {
|
|
383
|
+
settled = yield* awaitRunReply(workflow, request, (reply) => !isSuspendedReply(reply))
|
|
384
|
+
}
|
|
385
|
+
}).pipe(Effect.catchCause(() => Effect.never))
|
|
354
386
|
|
|
355
387
|
const interrupt = Effect.fnUntraced(
|
|
356
388
|
function*(workflow: Workflow.Any, executionId: string) {
|
|
@@ -369,7 +401,7 @@ export const make = Effect.gen(function*() {
|
|
|
369
401
|
|
|
370
402
|
const nonSuspendedReply = Option.filter(
|
|
371
403
|
reply,
|
|
372
|
-
(reply) => reply
|
|
404
|
+
(reply) => !isSuspendedReply(reply)
|
|
373
405
|
)
|
|
374
406
|
if (Option.isSome(nonSuspendedReply)) {
|
|
375
407
|
return Option.none()
|
|
@@ -476,23 +508,19 @@ export const make = Effect.gen(function*() {
|
|
|
476
508
|
const activityId = `${executionId}/${payload.name}`
|
|
477
509
|
const instance = WorkflowEngine.WorkflowInstance.initial(workflow, executionId)
|
|
478
510
|
interruptedActivities.delete(activityId)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
)
|
|
492
|
-
return yield* entry.activity.executeEncoded.pipe(
|
|
493
|
-
Effect.provideContext(context)
|
|
494
|
-
)
|
|
495
|
-
}).pipe(
|
|
511
|
+
const entry = activities.get(activityId)
|
|
512
|
+
if (!entry) {
|
|
513
|
+
// Replay may never register a losing race activity. Answer it
|
|
514
|
+
// without waiting; a later registration can reset this reply.
|
|
515
|
+
return Effect.succeed(new Workflow.Suspended({})).pipe(Rpc.wrap({ fork: true }))
|
|
516
|
+
}
|
|
517
|
+
const context = entry.context.pipe(
|
|
518
|
+
Context.add(WorkflowEngine.WorkflowInstance, instance),
|
|
519
|
+
Context.add(CurrentActivationScope, activation),
|
|
520
|
+
Context.add(Activity.CurrentAttempt, payload.attempt)
|
|
521
|
+
)
|
|
522
|
+
return entry.activity.executeEncoded.pipe(
|
|
523
|
+
Effect.provideContext(context),
|
|
496
524
|
Workflow.intoResult,
|
|
497
525
|
Effect.catchCause((cause) => {
|
|
498
526
|
// we only want to store interrupts as suspends when the
|
|
@@ -623,6 +651,8 @@ export const make = Effect.gen(function*() {
|
|
|
623
651
|
|
|
624
652
|
resume: (workflow, executionId) => ensureSuccess(resume(workflow, executionId)),
|
|
625
653
|
|
|
654
|
+
awaitComplete,
|
|
655
|
+
|
|
626
656
|
activityExecute: Effect.fnUntraced(
|
|
627
657
|
function*(activity, attempt) {
|
|
628
658
|
const services = yield* Effect.context<WorkflowEngine.WorkflowInstance>()
|
|
@@ -633,11 +663,6 @@ export const make = Effect.gen(function*() {
|
|
|
633
663
|
while (true) {
|
|
634
664
|
if (!activities.has(activityId)) {
|
|
635
665
|
activities.set(activityId, { activity, context: services })
|
|
636
|
-
const latch = activityLatches.get(activityId)
|
|
637
|
-
if (latch) {
|
|
638
|
-
yield* latch.open
|
|
639
|
-
activityLatches.delete(activityId)
|
|
640
|
-
}
|
|
641
666
|
}
|
|
642
667
|
const result = yield* Effect.orDie(
|
|
643
668
|
client.activity({
|
|
@@ -820,6 +845,9 @@ const DeferredRpc = Rpc.make("deferred", {
|
|
|
820
845
|
.annotate(ClusterSchema.Persisted, true)
|
|
821
846
|
.annotate(ClusterSchema.Uninterruptible, true)
|
|
822
847
|
|
|
848
|
+
const isSuspendedReply = (reply: WithExitEncoded<Workflow.ResultEncoded<any, any>>) =>
|
|
849
|
+
reply.exit._tag === "Success" && reply.exit.value._tag === "Suspended"
|
|
850
|
+
|
|
823
851
|
const decodeDeferredWithExit = Schema.decodeSync(Schema.toCodecJson(Reply.WithExit.schema(DeferredRpc)))
|
|
824
852
|
|
|
825
853
|
const ResumeRpc = Rpc.make("resume", {
|
|
@@ -207,7 +207,12 @@ export class MessageStorage extends Context.Service<MessageStorage, {
|
|
|
207
207
|
) => Effect.Effect<void, PersistenceError>
|
|
208
208
|
|
|
209
209
|
/**
|
|
210
|
-
*
|
|
210
|
+
* Wraps requests in storage transactions.
|
|
211
|
+
*
|
|
212
|
+
* `WithExit` replies saved in a transaction notify callers after the outermost
|
|
213
|
+
* commit; stream chunks notify immediately. Replies saved in a failed
|
|
214
|
+
* transaction must be discarded. The wrapper may fail only with the wrapped
|
|
215
|
+
* effect's own failure or a defect.
|
|
211
216
|
*/
|
|
212
217
|
readonly withTransaction: <A, E, R>(
|
|
213
218
|
effect: Effect.Effect<A, E, R>
|
|
@@ -513,6 +518,10 @@ export type EncodedRepliesOptions<A> = {
|
|
|
513
518
|
readonly cursor: Option.Option<A>
|
|
514
519
|
}
|
|
515
520
|
|
|
521
|
+
const TransactionNotifications = Context.Reference<
|
|
522
|
+
Array<Effect.Effect<void, PersistenceError | MalformedMessage>> | undefined
|
|
523
|
+
>("effect/cluster/MessageStorage/TransactionNotifications", { defaultValue: () => undefined })
|
|
524
|
+
|
|
516
525
|
/**
|
|
517
526
|
* Wraps a concrete message storage implementation with reply-handler management.
|
|
518
527
|
*
|
|
@@ -555,6 +564,20 @@ export const make = (
|
|
|
555
564
|
const replyHandlersShard = new Map<string, Set<ReplyHandler>>()
|
|
556
565
|
return MessageStorage.of({
|
|
557
566
|
...storage,
|
|
567
|
+
// Nested transactions defer notifications to the outermost commit.
|
|
568
|
+
withTransaction: (effect) =>
|
|
569
|
+
TransactionNotifications.use((outer) => {
|
|
570
|
+
const notifications: Array<Effect.Effect<void, PersistenceError | MalformedMessage>> = []
|
|
571
|
+
return storage.withTransaction(Effect.provideService(effect, TransactionNotifications, notifications)).pipe(
|
|
572
|
+
Effect.tap(() =>
|
|
573
|
+
outer
|
|
574
|
+
? Effect.sync(() => {
|
|
575
|
+
outer.push(...notifications)
|
|
576
|
+
})
|
|
577
|
+
: Effect.orDie(Effect.forEach(notifications, identity, { discard: true }))
|
|
578
|
+
)
|
|
579
|
+
)
|
|
580
|
+
}),
|
|
558
581
|
registerReplyHandler: (message) => {
|
|
559
582
|
const requestId = message.envelope.requestId
|
|
560
583
|
return Effect.callback<void, EntityNotAssignedToRunner>((resume) => {
|
|
@@ -619,20 +642,28 @@ export const make = (
|
|
|
619
642
|
saveReply(reply) {
|
|
620
643
|
const requestId = reply.reply.requestId
|
|
621
644
|
return Effect.flatMap(storage.saveReply(reply), (persisted) => {
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
645
|
+
const notify = Effect.suspend(() => {
|
|
646
|
+
const handlers = replyHandlers.get(requestId)
|
|
647
|
+
if (!handlers) {
|
|
648
|
+
return Effect.void
|
|
649
|
+
} else if (persisted.reply._tag === "WithExit") {
|
|
650
|
+
replyHandlers.delete(requestId)
|
|
651
|
+
for (let i = 0; i < handlers.length; i++) {
|
|
652
|
+
const handler = handlers[i]
|
|
653
|
+
handler.shardSet.delete(handler)
|
|
654
|
+
handler.resume(Effect.void)
|
|
655
|
+
}
|
|
631
656
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
657
|
+
return handlers.length === 1
|
|
658
|
+
? handlers[0].respond(persisted)
|
|
659
|
+
: Effect.forEach(handlers, (handler) => handler.respond(persisted), { discard: true })
|
|
660
|
+
})
|
|
661
|
+
if (persisted.reply._tag !== "WithExit") return notify
|
|
662
|
+
return TransactionNotifications.use((notifications) =>
|
|
663
|
+
notifications === undefined ? notify : Effect.sync(() => {
|
|
664
|
+
notifications.push(notify)
|
|
665
|
+
})
|
|
666
|
+
)
|
|
636
667
|
})
|
|
637
668
|
}
|
|
638
669
|
})
|
package/src/cluster/Runners.ts
CHANGED
|
@@ -282,6 +282,10 @@ export const make: (
|
|
|
282
282
|
const reply = entry.replies[i]
|
|
283
283
|
// we have reached the end
|
|
284
284
|
if (reply._tag === "WithExit") {
|
|
285
|
+
// A reply can immediately reset and resend the same request. Do not
|
|
286
|
+
// let that sender attach to this completed reply loop.
|
|
287
|
+
storageRequests.delete(message.envelope.requestId)
|
|
288
|
+
waitingStorageRequests.delete(message.envelope.requestId)
|
|
285
289
|
for (const message of entry.messages) {
|
|
286
290
|
yield* message.respond(reply)
|
|
287
291
|
}
|
|
@@ -304,8 +308,10 @@ export const make: (
|
|
|
304
308
|
effect,
|
|
305
309
|
Effect.sync(() => {
|
|
306
310
|
const entry = storageRequests.get(message.envelope.requestId)
|
|
307
|
-
|
|
308
|
-
|
|
311
|
+
// An old waiter must not clean up a reset request's new reply loop.
|
|
312
|
+
if (!entry?.messages.has(message)) return
|
|
313
|
+
if (entry.messages.size > 1) {
|
|
314
|
+
entry.messages.delete(message)
|
|
309
315
|
return
|
|
310
316
|
}
|
|
311
317
|
storageRequests.delete(message.envelope.requestId)
|