effect 4.0.0-beta.92 → 4.0.0-beta.94
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/dist/Cause.d.ts +3 -1
- package/dist/Cause.d.ts.map +1 -1
- package/dist/Cause.js.map +1 -1
- package/dist/Config.d.ts +1 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Effect.d.ts +130 -0
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +43 -0
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +7 -0
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +3 -0
- package/dist/FileSystem.js.map +1 -1
- package/dist/Layer.d.ts +1 -1
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +6 -3
- package/dist/Layer.js.map +1 -1
- package/dist/LayerMap.js +1 -1
- package/dist/LayerMap.js.map +1 -1
- package/dist/LayerRef.d.ts +252 -0
- package/dist/LayerRef.d.ts.map +1 -0
- package/dist/LayerRef.js +171 -0
- package/dist/LayerRef.js.map +1 -0
- package/dist/Schema.d.ts +74 -30
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +3 -0
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaParser.d.ts +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js.map +1 -1
- package/dist/internal/core.js +1 -1
- package/dist/internal/effect.js +10 -6
- package/dist/internal/effect.js.map +1 -1
- package/dist/testing/TestSchema.d.ts +2 -2
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js.map +1 -1
- package/dist/unstable/ai/Chat.d.ts +1 -1
- package/dist/unstable/ai/Chat.d.ts.map +1 -1
- package/dist/unstable/ai/LanguageModel.d.ts +2 -2
- package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
- package/dist/unstable/cli/Argument.d.ts +2 -2
- package/dist/unstable/cli/Argument.d.ts.map +1 -1
- package/dist/unstable/cli/Argument.js.map +1 -1
- package/dist/unstable/cli/Flag.d.ts +2 -2
- package/dist/unstable/cli/Flag.d.ts.map +1 -1
- package/dist/unstable/cli/Flag.js.map +1 -1
- package/dist/unstable/cli/Param.d.ts +2 -2
- package/dist/unstable/cli/Param.d.ts.map +1 -1
- package/dist/unstable/cli/Param.js.map +1 -1
- package/dist/unstable/cli/Primitive.js.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.js +1 -0
- package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/unstable/cluster/Entity.d.ts.map +1 -1
- package/dist/unstable/cluster/Entity.js +5 -3
- package/dist/unstable/cluster/Entity.js.map +1 -1
- package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
- package/dist/unstable/cluster/Sharding.js +3 -1
- package/dist/unstable/cluster/Sharding.js.map +1 -1
- package/dist/unstable/cluster/internal/entityManager.js +3 -2
- package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
- package/dist/unstable/cluster/internal/resourceMap.js +39 -14
- package/dist/unstable/cluster/internal/resourceMap.js.map +1 -1
- package/dist/unstable/encoding/Sse.d.ts +2 -2
- package/dist/unstable/encoding/Sse.d.ts.map +1 -1
- package/dist/unstable/http/HttpBody.d.ts +1 -1
- package/dist/unstable/http/HttpBody.d.ts.map +1 -1
- package/dist/unstable/http/HttpBody.js +1 -1
- package/dist/unstable/http/HttpBody.js.map +1 -1
- package/dist/unstable/http/HttpClient.js +2 -2
- package/dist/unstable/http/HttpClient.js.map +1 -1
- package/dist/unstable/http/HttpClientRequest.d.ts +5 -4
- package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientRequest.js +5 -4
- package/dist/unstable/http/HttpClientRequest.js.map +1 -1
- package/dist/unstable/http/HttpClientResponse.d.ts +1 -1
- package/dist/unstable/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientResponse.js.map +1 -1
- package/dist/unstable/http/HttpIncomingMessage.d.ts +2 -2
- package/dist/unstable/http/HttpIncomingMessage.d.ts.map +1 -1
- package/dist/unstable/http/HttpIncomingMessage.js.map +1 -1
- package/dist/unstable/http/HttpRouter.d.ts +4 -4
- package/dist/unstable/http/HttpRouter.d.ts.map +1 -1
- package/dist/unstable/http/HttpRouter.js.map +1 -1
- package/dist/unstable/http/HttpServerRequest.d.ts +8 -8
- package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerRequest.js.map +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerResponse.js.map +1 -1
- package/dist/unstable/http/Multipart.d.ts +2 -2
- package/dist/unstable/http/Multipart.d.ts.map +1 -1
- package/dist/unstable/http/Multipart.js.map +1 -1
- package/dist/unstable/http/Url.d.ts +29 -4
- package/dist/unstable/http/Url.d.ts.map +1 -1
- package/dist/unstable/http/Url.js +44 -2
- package/dist/unstable/http/Url.js.map +1 -1
- package/dist/unstable/http/UrlParams.d.ts +2 -28
- package/dist/unstable/http/UrlParams.d.ts.map +1 -1
- package/dist/unstable/http/UrlParams.js +4 -46
- package/dist/unstable/http/UrlParams.js.map +1 -1
- package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApi.js +2 -4
- package/dist/unstable/httpapi/HttpApi.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js +30 -15
- package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +7 -7
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiSchema.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpTracer.js +4 -3
- package/dist/unstable/observability/OtlpTracer.js.map +1 -1
- package/dist/unstable/reactivity/Atom.d.ts +4 -4
- package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
- package/dist/unstable/reactivity/Atom.js.map +1 -1
- package/package.json +1 -1
- package/src/Cause.ts +3 -1
- package/src/Config.ts +1 -1
- package/src/Effect.ts +131 -0
- package/src/FileSystem.ts +13 -0
- package/src/Layer.ts +6 -6
- package/src/LayerMap.ts +1 -1
- package/src/LayerRef.ts +379 -0
- package/src/Schema.ts +83 -33
- package/src/SchemaParser.ts +2 -2
- package/src/internal/core.ts +1 -1
- package/src/internal/effect.ts +33 -6
- package/src/testing/TestSchema.ts +2 -2
- package/src/unstable/ai/Chat.ts +1 -1
- package/src/unstable/ai/LanguageModel.ts +3 -3
- package/src/unstable/cli/Argument.ts +14 -7
- package/src/unstable/cli/Flag.ts +6 -3
- package/src/unstable/cli/Param.ts +6 -3
- package/src/unstable/cli/Primitive.ts +2 -2
- package/src/unstable/cluster/ClusterWorkflowEngine.ts +1 -0
- package/src/unstable/cluster/Entity.ts +13 -14
- package/src/unstable/cluster/Sharding.ts +134 -131
- package/src/unstable/cluster/internal/entityManager.ts +11 -9
- package/src/unstable/cluster/internal/resourceMap.ts +59 -25
- package/src/unstable/encoding/Sse.ts +3 -3
- package/src/unstable/http/HttpBody.ts +2 -2
- package/src/unstable/http/HttpClient.ts +2 -2
- package/src/unstable/http/HttpClientRequest.ts +8 -7
- package/src/unstable/http/HttpClientResponse.ts +2 -3
- package/src/unstable/http/HttpIncomingMessage.ts +4 -5
- package/src/unstable/http/HttpRouter.ts +8 -10
- package/src/unstable/http/HttpServerRequest.ts +20 -19
- package/src/unstable/http/HttpServerResponse.ts +2 -2
- package/src/unstable/http/Multipart.ts +3 -3
- package/src/unstable/http/Url.ts +62 -7
- package/src/unstable/http/UrlParams.ts +5 -58
- package/src/unstable/httpapi/HttpApi.ts +2 -4
- package/src/unstable/httpapi/HttpApiBuilder.ts +33 -21
- package/src/unstable/httpapi/HttpApiClient.ts +2 -2
- package/src/unstable/httpapi/HttpApiEndpoint.ts +7 -7
- package/src/unstable/httpapi/HttpApiSchema.ts +1 -1
- package/src/unstable/observability/OtlpTracer.ts +4 -3
- package/src/unstable/reactivity/Atom.ts +10 -7
|
@@ -124,7 +124,7 @@ export interface Service {
|
|
|
124
124
|
*/
|
|
125
125
|
readonly generateObject: <
|
|
126
126
|
ObjectEncoded extends Record<string, any>,
|
|
127
|
-
StructuredOutputSchema extends Schema.
|
|
127
|
+
StructuredOutputSchema extends Schema.Encoder<ObjectEncoded, unknown>,
|
|
128
128
|
Options extends NoExcessProperties<
|
|
129
129
|
GenerateObjectOptions<any, StructuredOutputSchema>,
|
|
130
130
|
Options
|
|
@@ -835,7 +835,7 @@ export const make: (params: {
|
|
|
835
835
|
|
|
836
836
|
const generateObject = <
|
|
837
837
|
ObjectEncoded extends Record<string, any>,
|
|
838
|
-
StructuredOutputSchema extends Schema.
|
|
838
|
+
StructuredOutputSchema extends Schema.Encoder<ObjectEncoded, unknown>,
|
|
839
839
|
Options extends NoExcessProperties<
|
|
840
840
|
GenerateObjectOptions<any, StructuredOutputSchema>,
|
|
841
841
|
Options
|
|
@@ -1691,7 +1691,7 @@ export const generateText: {
|
|
|
1691
1691
|
*/
|
|
1692
1692
|
export const generateObject = <
|
|
1693
1693
|
ObjectEncoded extends Record<string, any>,
|
|
1694
|
-
StructuredOutputSchema extends Schema.
|
|
1694
|
+
StructuredOutputSchema extends Schema.Encoder<ObjectEncoded, unknown>,
|
|
1695
1695
|
Options extends NoExcessProperties<
|
|
1696
1696
|
GenerateObjectOptions<any, StructuredOutputSchema>,
|
|
1697
1697
|
Options
|
|
@@ -401,8 +401,8 @@ export const withDefault: {
|
|
|
401
401
|
* @since 4.0.0
|
|
402
402
|
*/
|
|
403
403
|
<A, const B>(
|
|
404
|
-
|
|
405
|
-
|
|
404
|
+
self: Argument<A>,
|
|
405
|
+
defaultValue: B | Effect.Effect<B, CliError.CliError, Environment>
|
|
406
406
|
): Argument<A | B>
|
|
407
407
|
} = Param.withDefault
|
|
408
408
|
|
|
@@ -729,8 +729,8 @@ export const mapEffect: {
|
|
|
729
729
|
* @since 4.0.0
|
|
730
730
|
*/
|
|
731
731
|
<A, B>(
|
|
732
|
-
|
|
733
|
-
|
|
732
|
+
self: Argument<A>,
|
|
733
|
+
f: (a: A) => Effect.Effect<B, CliError.CliError, Environment>
|
|
734
734
|
): Argument<B>
|
|
735
735
|
} = dual(2, <A, B>(
|
|
736
736
|
self: Argument<A>,
|
|
@@ -982,7 +982,7 @@ export const withSchema: {
|
|
|
982
982
|
* @category combinators
|
|
983
983
|
* @since 4.0.0
|
|
984
984
|
*/
|
|
985
|
-
<A, B>(schema: Schema.
|
|
985
|
+
<A, B>(schema: Schema.ConstraintCodec<B, A, Environment, unknown>): (self: Argument<A>) => Argument<B>
|
|
986
986
|
/**
|
|
987
987
|
* Validates parsed values against a Schema.
|
|
988
988
|
*
|
|
@@ -1000,8 +1000,15 @@ export const withSchema: {
|
|
|
1000
1000
|
* @category combinators
|
|
1001
1001
|
* @since 4.0.0
|
|
1002
1002
|
*/
|
|
1003
|
-
<A, B>(
|
|
1004
|
-
|
|
1003
|
+
<A, B>(
|
|
1004
|
+
self: Argument<A>,
|
|
1005
|
+
schema: Schema.ConstraintCodec<B, A, Environment, unknown>
|
|
1006
|
+
): Argument<B>
|
|
1007
|
+
} = dual(
|
|
1008
|
+
2,
|
|
1009
|
+
<A, B>(self: Argument<A>, schema: Schema.ConstraintCodec<B, A, Environment, unknown>): Argument<B> =>
|
|
1010
|
+
Param.withSchema(self, schema)
|
|
1011
|
+
)
|
|
1005
1012
|
|
|
1006
1013
|
/**
|
|
1007
1014
|
* Creates a positional choice argument with custom value mapping.
|
package/src/unstable/cli/Flag.ts
CHANGED
|
@@ -1782,7 +1782,7 @@ export const withSchema: {
|
|
|
1782
1782
|
* @category schemas
|
|
1783
1783
|
* @since 4.0.0
|
|
1784
1784
|
*/
|
|
1785
|
-
<A, B>(schema: Schema.
|
|
1785
|
+
<A, B>(schema: Schema.ConstraintCodec<B, A, Environment, unknown>): (self: Flag<A>) => Flag<B>
|
|
1786
1786
|
/**
|
|
1787
1787
|
* Validates and transforms a flag value using a Schema codec.
|
|
1788
1788
|
*
|
|
@@ -1820,5 +1820,8 @@ export const withSchema: {
|
|
|
1820
1820
|
* @category schemas
|
|
1821
1821
|
* @since 4.0.0
|
|
1822
1822
|
*/
|
|
1823
|
-
<A, B>(self: Flag<A>, schema: Schema.
|
|
1824
|
-
} = dual(
|
|
1823
|
+
<A, B>(self: Flag<A>, schema: Schema.ConstraintCodec<B, A, Environment, unknown>): Flag<B>
|
|
1824
|
+
} = dual(
|
|
1825
|
+
2,
|
|
1826
|
+
<A, B>(self: Flag<A>, schema: Schema.ConstraintCodec<B, A, Environment, unknown>) => Param.withSchema(self, schema)
|
|
1827
|
+
)
|
|
@@ -2430,7 +2430,7 @@ export const withSchema: {
|
|
|
2430
2430
|
* @category combinators
|
|
2431
2431
|
* @since 4.0.0
|
|
2432
2432
|
*/
|
|
2433
|
-
<A, B>(schema: Schema.
|
|
2433
|
+
<A, B>(schema: Schema.ConstraintCodec<B, A, Environment, unknown>): <Kind extends ParamKind>(
|
|
2434
2434
|
self: Param<Kind, A>
|
|
2435
2435
|
) => Param<Kind, B>
|
|
2436
2436
|
/**
|
|
@@ -2455,10 +2455,13 @@ export const withSchema: {
|
|
|
2455
2455
|
* @category combinators
|
|
2456
2456
|
* @since 4.0.0
|
|
2457
2457
|
*/
|
|
2458
|
-
<Kind extends ParamKind, A, B>(
|
|
2458
|
+
<Kind extends ParamKind, A, B>(
|
|
2459
|
+
self: Param<Kind, A>,
|
|
2460
|
+
schema: Schema.ConstraintCodec<B, A, Environment, unknown>
|
|
2461
|
+
): Param<Kind, B>
|
|
2459
2462
|
} = dual(2, <Kind extends ParamKind, A, B>(
|
|
2460
2463
|
self: Param<Kind, A>,
|
|
2461
|
-
schema: Schema.
|
|
2464
|
+
schema: Schema.ConstraintCodec<B, A, Environment, unknown>
|
|
2462
2465
|
) => {
|
|
2463
2466
|
const decodeParam = Schema.decodeUnknownEffect(schema)
|
|
2464
2467
|
return mapEffect(self, (value) =>
|
|
@@ -105,9 +105,9 @@ const makePrimitive = <A>(
|
|
|
105
105
|
parse
|
|
106
106
|
})
|
|
107
107
|
|
|
108
|
-
const makeSchemaPrimitive = <T
|
|
108
|
+
const makeSchemaPrimitive = <T>(
|
|
109
109
|
tag: string,
|
|
110
|
-
schema: Schema.
|
|
110
|
+
schema: Schema.ConstraintDecoder<T, Environment>
|
|
111
111
|
): Primitive<T> => {
|
|
112
112
|
const toCodecStringTree = Schema.toCodecStringTree(schema)
|
|
113
113
|
const decode = Schema.decodeUnknownEffect(toCodecStringTree)
|
|
@@ -133,6 +133,7 @@ export const make = Effect.gen(function*() {
|
|
|
133
133
|
if (!entity) {
|
|
134
134
|
return yield* Effect.die(`Workflow ${workflowName} not registered`)
|
|
135
135
|
}
|
|
136
|
+
yield* RcMap.invalidate(clientsPartial, workflowName)
|
|
136
137
|
return yield* entity.client
|
|
137
138
|
}),
|
|
138
139
|
idleTimeToLive: "5 minutes"
|
|
@@ -618,11 +618,7 @@ export const makeTestClient: <Type extends string, Rpcs extends Rpc.Any, LA, LE,
|
|
|
618
618
|
Rpc.ServicesClient<Rpcs> | Rpc.ServicesServer<Rpcs> | Rpc.Middleware<Rpcs> | LR
|
|
619
619
|
>
|
|
620
620
|
readonly concurrency: number | "unbounded"
|
|
621
|
-
readonly build: Effect.Effect<
|
|
622
|
-
Context.Context<Rpc.ToHandler<Rpcs>>,
|
|
623
|
-
never,
|
|
624
|
-
Scope | CurrentAddress
|
|
625
|
-
>
|
|
621
|
+
readonly build: Effect.Effect<Context.Context<Rpc.ToHandler<Rpcs>>>
|
|
626
622
|
}>()
|
|
627
623
|
const sharding = shardingTag.of({
|
|
628
624
|
...({} as Sharding["Service"]),
|
|
@@ -631,13 +627,7 @@ export const makeTestClient: <Type extends string, Rpcs extends Rpc.Any, LA, LE,
|
|
|
631
627
|
entityMap.set(entity.type, {
|
|
632
628
|
context: context as any,
|
|
633
629
|
concurrency: options?.concurrency ?? 1,
|
|
634
|
-
build: entity.protocol.toHandlers(handlers as any)
|
|
635
|
-
Effect.provideContext(Context.mutate(context, (context) =>
|
|
636
|
-
context.pipe(
|
|
637
|
-
Context.add(CurrentRunnerAddress, runnerAddress),
|
|
638
|
-
Context.omit(Scope)
|
|
639
|
-
)))
|
|
640
|
-
) as any
|
|
630
|
+
build: entity.protocol.toHandlers(handlers as any) as any
|
|
641
631
|
})
|
|
642
632
|
return Effect.void
|
|
643
633
|
})
|
|
@@ -654,8 +644,15 @@ export const makeTestClient: <Type extends string, Rpcs extends Rpc.Any, LA, LE,
|
|
|
654
644
|
entityId: entityId as EntityId,
|
|
655
645
|
shardId: makeShardId(entityId)
|
|
656
646
|
})
|
|
647
|
+
const scope = yield* Effect.scope
|
|
648
|
+
const handlerContext = Context.mutate(entityEntry.context, (context) =>
|
|
649
|
+
context.pipe(
|
|
650
|
+
Context.add(CurrentRunnerAddress, runnerAddress),
|
|
651
|
+
Context.add(CurrentAddress, address),
|
|
652
|
+
Context.add(Scope, scope)
|
|
653
|
+
))
|
|
657
654
|
const handlers = yield* entityEntry.build.pipe(
|
|
658
|
-
Effect.
|
|
655
|
+
Effect.setContext(handlerContext as Context.Context<any>)
|
|
659
656
|
)
|
|
660
657
|
|
|
661
658
|
// oxlint-disable-next-line prefer-const
|
|
@@ -665,7 +662,9 @@ export const makeTestClient: <Type extends string, Rpcs extends Rpc.Any, LA, LE,
|
|
|
665
662
|
onFromServer(response) {
|
|
666
663
|
return client.write(response)
|
|
667
664
|
}
|
|
668
|
-
}).pipe(
|
|
665
|
+
}).pipe(
|
|
666
|
+
Effect.setContext(Context.merge(handlerContext, handlers))
|
|
667
|
+
)
|
|
669
668
|
|
|
670
669
|
client = yield* RpcClient.makeNoSerialization(entity.protocol, {
|
|
671
670
|
supportsAck: true,
|
|
@@ -1034,148 +1034,151 @@ const make = Effect.gen(function*() {
|
|
|
1034
1034
|
MailboxFull | AlreadyProcessingMessage
|
|
1035
1035
|
>,
|
|
1036
1036
|
never
|
|
1037
|
-
> = yield* ResourceMap.make(
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
rpc.annotations,
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1037
|
+
> = yield* ResourceMap.make(
|
|
1038
|
+
Effect.fnUntraced(function*(entity: Entity<string, any>) {
|
|
1039
|
+
const client = yield* RpcClient.makeNoSerialization(entity.protocol, {
|
|
1040
|
+
spanPrefix: `${entity.type}.client`,
|
|
1041
|
+
disableTracing: !Context.get(entity.protocol.annotations, ClusterSchema.ClientTracingEnabled),
|
|
1042
|
+
supportsAck: true,
|
|
1043
|
+
generateRequestId: () => RequestId(snowflakeGen.nextUnsafe()),
|
|
1044
|
+
flatten: true,
|
|
1045
|
+
onFromClient(options): Effect.Effect<
|
|
1046
|
+
void,
|
|
1047
|
+
MailboxFull | AlreadyProcessingMessage | PersistenceError
|
|
1048
|
+
> {
|
|
1049
|
+
const address = Context.getUnsafe(options.context, ClientAddressTag)
|
|
1050
|
+
switch (options.message._tag) {
|
|
1051
|
+
case "Request": {
|
|
1052
|
+
const fiber = Fiber.getCurrent()!
|
|
1053
|
+
const id = Snowflake.Snowflake(options.message.id)
|
|
1054
|
+
const rpc = entity.protocol.requests.get(options.message.tag)!
|
|
1055
|
+
let respond: (reply: Reply.Reply<any>) => Effect.Effect<void>
|
|
1056
|
+
const envelope = Envelope.makeRequest<any>({
|
|
1057
|
+
requestId: id,
|
|
1058
|
+
address,
|
|
1059
|
+
tag: options.message.tag,
|
|
1060
|
+
payload: options.message.payload,
|
|
1061
|
+
headers: options.message.headers,
|
|
1062
|
+
traceId: options.message.traceId,
|
|
1063
|
+
spanId: options.message.spanId,
|
|
1064
|
+
sampled: options.message.sampled
|
|
1065
|
+
})
|
|
1066
|
+
const message = new Message.OutgoingRequest({
|
|
1067
|
+
envelope,
|
|
1068
|
+
lastReceivedReply: Option.none(),
|
|
1069
|
+
rpc,
|
|
1070
|
+
context: fiber.context as Context.Context<any>,
|
|
1071
|
+
respond: (reply) => respond(reply),
|
|
1072
|
+
annotations: Context.get(rpc.annotations, ClusterSchema.Dynamic)(
|
|
1073
|
+
rpc.annotations,
|
|
1074
|
+
envelope as any
|
|
1075
|
+
)
|
|
1076
|
+
})
|
|
1077
|
+
if (!options.discard) {
|
|
1078
|
+
const entry: ClientRequestEntry = {
|
|
1079
|
+
rpc: rpc as any,
|
|
1080
|
+
context: fiber.currentContext,
|
|
1081
|
+
message
|
|
1082
|
+
}
|
|
1083
|
+
clientRequests.set(id, entry)
|
|
1084
|
+
respond = makeClientRespond(entry, client.write)
|
|
1085
|
+
} else {
|
|
1086
|
+
respond = clientRespondDiscard
|
|
1081
1087
|
}
|
|
1082
|
-
|
|
1083
|
-
respond = makeClientRespond(entry, client.write)
|
|
1084
|
-
} else {
|
|
1085
|
-
respond = clientRespondDiscard
|
|
1088
|
+
return sendOutgoing(message, options.discard)
|
|
1086
1089
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1090
|
+
case "Ack": {
|
|
1091
|
+
const requestId = Snowflake.Snowflake(options.message.requestId)
|
|
1092
|
+
const entry = clientRequests.get(requestId)
|
|
1093
|
+
if (!entry) return Effect.void
|
|
1094
|
+
return sendOutgoing(
|
|
1095
|
+
new Message.OutgoingEnvelope({
|
|
1096
|
+
envelope: new Envelope.AckChunk({
|
|
1097
|
+
id: snowflakeGen.nextUnsafe(),
|
|
1098
|
+
address,
|
|
1099
|
+
requestId,
|
|
1100
|
+
replyId: entry.lastChunkId!
|
|
1101
|
+
}),
|
|
1102
|
+
rpc: entry.rpc
|
|
1100
1103
|
}),
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
false
|
|
1104
|
-
)
|
|
1105
|
-
}
|
|
1106
|
-
case "Interrupt": {
|
|
1107
|
-
const requestId = Snowflake.Snowflake(options.message.requestId)
|
|
1108
|
-
const entry = clientRequests.get(requestId)!
|
|
1109
|
-
if (!entry) return Effect.void
|
|
1110
|
-
clientRequests.delete(requestId)
|
|
1111
|
-
if (ClusterSchema.isUninterruptibleForClient(entry.message.annotations)) {
|
|
1112
|
-
return Effect.void
|
|
1113
|
-
}
|
|
1114
|
-
// for durable messages, we ignore interrupts on shutdown or as a
|
|
1115
|
-
// result of a shard being resassigned
|
|
1116
|
-
const isTransientInterrupt = MutableRef.get(isShutdown) ||
|
|
1117
|
-
options.message.interruptors.some((id) => internalInterruptors.has(id))
|
|
1118
|
-
if (isTransientInterrupt && Context.get(entry.message.annotations, Persisted)) {
|
|
1119
|
-
return Effect.void
|
|
1104
|
+
false
|
|
1105
|
+
)
|
|
1120
1106
|
}
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1107
|
+
case "Interrupt": {
|
|
1108
|
+
const requestId = Snowflake.Snowflake(options.message.requestId)
|
|
1109
|
+
const entry = clientRequests.get(requestId)!
|
|
1110
|
+
if (!entry) return Effect.void
|
|
1111
|
+
clientRequests.delete(requestId)
|
|
1112
|
+
if (ClusterSchema.isUninterruptibleForClient(entry.message.annotations)) {
|
|
1113
|
+
return Effect.void
|
|
1114
|
+
}
|
|
1115
|
+
// for durable messages, we ignore interrupts on shutdown or as a
|
|
1116
|
+
// result of a shard being resassigned
|
|
1117
|
+
const isTransientInterrupt = MutableRef.get(isShutdown) ||
|
|
1118
|
+
options.message.interruptors.some((id) => internalInterruptors.has(id))
|
|
1119
|
+
if (isTransientInterrupt && Context.get(entry.message.annotations, Persisted)) {
|
|
1120
|
+
return Effect.void
|
|
1121
|
+
}
|
|
1122
|
+
return Effect.ignore(sendOutgoing(
|
|
1123
|
+
new Message.OutgoingEnvelope({
|
|
1124
|
+
envelope: new Envelope.Interrupt({
|
|
1125
|
+
id: snowflakeGen.nextUnsafe(),
|
|
1126
|
+
address,
|
|
1127
|
+
requestId
|
|
1128
|
+
}),
|
|
1129
|
+
rpc: entry.rpc
|
|
1127
1130
|
}),
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
))
|
|
1131
|
+
false,
|
|
1132
|
+
3
|
|
1133
|
+
))
|
|
1134
|
+
}
|
|
1133
1135
|
}
|
|
1136
|
+
return Effect.void
|
|
1134
1137
|
}
|
|
1135
|
-
return Effect.void
|
|
1136
|
-
}
|
|
1137
|
-
})
|
|
1138
|
-
|
|
1139
|
-
yield* Scope.addFinalizer(
|
|
1140
|
-
yield* Effect.scope,
|
|
1141
|
-
Effect.withFiber((fiber) => {
|
|
1142
|
-
internalInterruptors.add(fiber.id)
|
|
1143
|
-
return Effect.void
|
|
1144
1138
|
})
|
|
1145
|
-
)
|
|
1146
1139
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
entityType: entity.type
|
|
1153
|
-
}))
|
|
1154
|
-
const clientFn = function(tag: string, payload: any, options?: {
|
|
1155
|
-
readonly context?: Context.Context<never>
|
|
1156
|
-
}) {
|
|
1157
|
-
const context = options?.context ? Context.merge(options.context, address) : address
|
|
1158
|
-
return client.client(tag, payload, {
|
|
1159
|
-
...options,
|
|
1160
|
-
context
|
|
1140
|
+
yield* Scope.addFinalizer(
|
|
1141
|
+
yield* Effect.scope,
|
|
1142
|
+
Effect.withFiber((fiber) => {
|
|
1143
|
+
internalInterruptors.add(fiber.id)
|
|
1144
|
+
return Effect.void
|
|
1161
1145
|
})
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
return
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1146
|
+
)
|
|
1147
|
+
|
|
1148
|
+
return (entityId: string) => {
|
|
1149
|
+
const id = makeEntityId(entityId)
|
|
1150
|
+
const address = ClientAddressTag.context(makeEntityAddress({
|
|
1151
|
+
shardId: getShardId(id, entity.getShardGroup(entityId as EntityId)),
|
|
1152
|
+
entityId: id,
|
|
1153
|
+
entityType: entity.type
|
|
1154
|
+
}))
|
|
1155
|
+
const clientFn = function(tag: string, payload: any, options?: {
|
|
1156
|
+
readonly context?: Context.Context<never>
|
|
1157
|
+
}) {
|
|
1158
|
+
const context = options?.context ? Context.merge(options.context, address) : address
|
|
1159
|
+
return client.client(tag, payload, {
|
|
1160
|
+
...options,
|
|
1161
|
+
context
|
|
1162
|
+
})
|
|
1175
1163
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1164
|
+
const proxyClient: any = {}
|
|
1165
|
+
return new Proxy(proxyClient, {
|
|
1166
|
+
has(_, p) {
|
|
1167
|
+
return entity.protocol.requests.has(p as string)
|
|
1168
|
+
},
|
|
1169
|
+
get(target, p) {
|
|
1170
|
+
if (p in target) {
|
|
1171
|
+
return target[p]
|
|
1172
|
+
} else if (!entity.protocol.requests.has(p as string)) {
|
|
1173
|
+
return undefined
|
|
1174
|
+
}
|
|
1175
|
+
return target[p] = (payload: any, options?: {}) => clientFn(p as string, payload, options)
|
|
1176
|
+
}
|
|
1177
|
+
})
|
|
1178
|
+
}
|
|
1179
|
+
}),
|
|
1180
|
+
{ referential: true }
|
|
1181
|
+
)
|
|
1179
1182
|
|
|
1180
1183
|
const makeClient = <Type extends string, Rpcs extends Rpc.Any>(entity: Entity<Type, Rpcs>): Effect.Effect<
|
|
1181
1184
|
(
|
|
@@ -155,16 +155,18 @@ export const make = Effect.fnUntraced(function*<
|
|
|
155
155
|
Effect.fnUntraced(function*(scope) {
|
|
156
156
|
let isShuttingDown = false
|
|
157
157
|
|
|
158
|
+
const handlerContext = Context.mutate(context, (context) =>
|
|
159
|
+
context.pipe(
|
|
160
|
+
Context.add(CurrentAddress, address),
|
|
161
|
+
Context.add(CurrentRunnerAddress, options.runnerAddress),
|
|
162
|
+
Context.add(KeepAliveLatch, keepAliveLatch),
|
|
163
|
+
Context.add(Scope.Scope, scope),
|
|
164
|
+
Context.add(CurrentLogAnnotations, {})
|
|
165
|
+
))
|
|
166
|
+
|
|
158
167
|
// Initiate the behavior for the entity
|
|
159
168
|
const handlers = yield* (entity.protocol.toHandlers(buildHandlers as any).pipe(
|
|
160
|
-
Effect.
|
|
161
|
-
Effect.provideContext(Context.mutate(context, (context) =>
|
|
162
|
-
context.pipe(
|
|
163
|
-
Context.add(CurrentAddress, address),
|
|
164
|
-
Context.add(CurrentRunnerAddress, options.runnerAddress),
|
|
165
|
-
Context.add(KeepAliveLatch, keepAliveLatch),
|
|
166
|
-
Context.add(Scope.Scope, scope)
|
|
167
|
-
))),
|
|
169
|
+
Effect.setContext(handlerContext as Context.Context<any>),
|
|
168
170
|
Effect.sandbox,
|
|
169
171
|
Effect.tapError((cause) => Effect.logError("Defect building entity handlers", cause)),
|
|
170
172
|
Effect.retry(defectRetryPolicy)
|
|
@@ -280,7 +282,7 @@ export const make = Effect.fnUntraced(function*<
|
|
|
280
282
|
}
|
|
281
283
|
}).pipe(
|
|
282
284
|
Scope.provide(scope),
|
|
283
|
-
Effect.
|
|
285
|
+
Effect.setContext(Context.merge(handlerContext, handlers))
|
|
284
286
|
)
|
|
285
287
|
|
|
286
288
|
yield* Scope.addFinalizer(
|
|
@@ -4,23 +4,16 @@ import * as Effect from "../../../Effect.ts"
|
|
|
4
4
|
import * as Exit from "../../../Exit.ts"
|
|
5
5
|
import * as MutableHashMap from "../../../MutableHashMap.ts"
|
|
6
6
|
import * as MutableRef from "../../../MutableRef.ts"
|
|
7
|
-
import * as Option from "../../../Option.ts"
|
|
8
7
|
import * as Scope from "../../../Scope.ts"
|
|
9
8
|
|
|
10
9
|
/** @internal */
|
|
11
10
|
export class ResourceMap<K, A, E> {
|
|
12
11
|
readonly lookup: (key: K, scope: Scope.Scope) => Effect.Effect<A, E>
|
|
13
|
-
readonly entries:
|
|
14
|
-
readonly scope: Scope.Closeable
|
|
15
|
-
readonly deferred: Deferred.Deferred<A, E>
|
|
16
|
-
}>
|
|
12
|
+
readonly entries: BackingMap<K, A, E>
|
|
17
13
|
readonly isClosed: MutableRef.MutableRef<boolean>
|
|
18
14
|
constructor(
|
|
19
15
|
lookup: (key: K, scope: Scope.Scope) => Effect.Effect<A, E>,
|
|
20
|
-
entries:
|
|
21
|
-
readonly scope: Scope.Closeable
|
|
22
|
-
readonly deferred: Deferred.Deferred<A, E>
|
|
23
|
-
}>,
|
|
16
|
+
entries: BackingMap<K, A, E>,
|
|
24
17
|
isClosed: MutableRef.MutableRef<boolean>
|
|
25
18
|
) {
|
|
26
19
|
this.lookup = lookup
|
|
@@ -28,22 +21,29 @@ export class ResourceMap<K, A, E> {
|
|
|
28
21
|
this.isClosed = isClosed
|
|
29
22
|
}
|
|
30
23
|
|
|
31
|
-
static make = Effect.fnUntraced(function*<K, A, E, R>(lookup: (key: K) => Effect.Effect<A, E, R
|
|
24
|
+
static make = Effect.fnUntraced(function*<K, A, E, R>(lookup: (key: K) => Effect.Effect<A, E, R>, options?: {
|
|
25
|
+
readonly referential?: boolean | undefined
|
|
26
|
+
}) {
|
|
32
27
|
const scope = yield* Effect.scope
|
|
33
28
|
const services = yield* Effect.context<R>()
|
|
34
29
|
const isClosed = MutableRef.make(false)
|
|
35
30
|
|
|
36
|
-
const entries
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
const entries: BackingMap<K, A, E> = options?.referential ?
|
|
32
|
+
{
|
|
33
|
+
_tag: "Referential",
|
|
34
|
+
map: new Map()
|
|
35
|
+
} :
|
|
36
|
+
{
|
|
37
|
+
_tag: "Equal",
|
|
38
|
+
map: MutableHashMap.empty()
|
|
39
|
+
}
|
|
40
40
|
|
|
41
41
|
yield* Scope.addFinalizerExit(
|
|
42
42
|
scope,
|
|
43
43
|
(exit) => {
|
|
44
44
|
MutableRef.set(isClosed, true)
|
|
45
|
-
return Effect.forEach(entries, ([key, { scope }]) => {
|
|
46
|
-
|
|
45
|
+
return Effect.forEach(entries.map, ([key, { scope }]) => {
|
|
46
|
+
backingDelete(entries, key)
|
|
47
47
|
return Effect.exit(Scope.close(scope, exit))
|
|
48
48
|
}, { concurrency: "unbounded", discard: true })
|
|
49
49
|
}
|
|
@@ -61,18 +61,18 @@ export class ResourceMap<K, A, E> {
|
|
|
61
61
|
if (MutableRef.get(this.isClosed)) {
|
|
62
62
|
return Effect.interrupt
|
|
63
63
|
}
|
|
64
|
-
const existing =
|
|
65
|
-
if (
|
|
66
|
-
return Deferred.await(existing.
|
|
64
|
+
const existing = backingGet(this.entries, key)
|
|
65
|
+
if (existing) {
|
|
66
|
+
return Deferred.await(existing.deferred)
|
|
67
67
|
}
|
|
68
68
|
const scope = Effect.runSync(Scope.make())
|
|
69
69
|
const deferred = Deferred.makeUnsafe<A, E>()
|
|
70
|
-
|
|
70
|
+
backingSet(this.entries, key, { scope, deferred })
|
|
71
71
|
return Effect.onExit(this.lookup(key, scope), (exit) => {
|
|
72
72
|
if (exit._tag === "Success") {
|
|
73
73
|
return Deferred.done(deferred, exit)
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
backingDelete(this.entries, key)
|
|
76
76
|
return Deferred.done(deferred, exit)
|
|
77
77
|
})
|
|
78
78
|
})
|
|
@@ -80,12 +80,12 @@ export class ResourceMap<K, A, E> {
|
|
|
80
80
|
|
|
81
81
|
remove(key: K): Effect.Effect<void> {
|
|
82
82
|
return Effect.suspend(() => {
|
|
83
|
-
const entry =
|
|
84
|
-
if (
|
|
83
|
+
const entry = backingGet(this.entries, key)
|
|
84
|
+
if (!entry) {
|
|
85
85
|
return Effect.void
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
return Scope.close(entry.
|
|
87
|
+
backingDelete(this.entries, key)
|
|
88
|
+
return Scope.close(entry.scope, Exit.void)
|
|
89
89
|
})
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -98,3 +98,37 @@ export class ResourceMap<K, A, E> {
|
|
|
98
98
|
}))
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
+
|
|
102
|
+
type BackingMap<K, A, E> = {
|
|
103
|
+
readonly _tag: "Equal"
|
|
104
|
+
readonly map: MutableHashMap.MutableHashMap<K, Entry<A, E>>
|
|
105
|
+
} | {
|
|
106
|
+
readonly _tag: "Referential"
|
|
107
|
+
readonly map: Map<K, Entry<A, E>>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type Entry<A, E> = {
|
|
111
|
+
readonly scope: Scope.Closeable
|
|
112
|
+
readonly deferred: Deferred.Deferred<A, E>
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const backingGet = <K, A, E>(map: BackingMap<K, A, E>, key: K): Entry<A, E> | undefined => {
|
|
116
|
+
if (map._tag === "Equal") {
|
|
117
|
+
return MutableHashMap.get(map.map, key).valueOrUndefined
|
|
118
|
+
}
|
|
119
|
+
return map.map.get(key)
|
|
120
|
+
}
|
|
121
|
+
const backingSet = <K, A, E>(map: BackingMap<K, A, E>, key: K, entry: Entry<A, E>): void => {
|
|
122
|
+
if (map._tag === "Equal") {
|
|
123
|
+
MutableHashMap.set(map.map, key, entry)
|
|
124
|
+
} else {
|
|
125
|
+
map.map.set(key, entry)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const backingDelete = <K, A, E>(map: BackingMap<K, A, E>, key: K): void => {
|
|
129
|
+
if (map._tag === "Equal") {
|
|
130
|
+
MutableHashMap.remove(map.map, key)
|
|
131
|
+
} else {
|
|
132
|
+
map.map.delete(key)
|
|
133
|
+
}
|
|
134
|
+
}
|