@effect/cluster 0.50.6 → 0.52.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.
Files changed (232) hide show
  1. package/RunnerStorage/package.json +6 -0
  2. package/SqlRunnerStorage/package.json +6 -0
  3. package/dist/cjs/ClusterError.js +2 -24
  4. package/dist/cjs/ClusterError.js.map +1 -1
  5. package/dist/cjs/ClusterMetrics.js +13 -15
  6. package/dist/cjs/ClusterMetrics.js.map +1 -1
  7. package/dist/cjs/ClusterSchema.js +17 -2
  8. package/dist/cjs/ClusterSchema.js.map +1 -1
  9. package/dist/cjs/ClusterWorkflowEngine.js +50 -83
  10. package/dist/cjs/ClusterWorkflowEngine.js.map +1 -1
  11. package/dist/cjs/Entity.js +1 -13
  12. package/dist/cjs/Entity.js.map +1 -1
  13. package/dist/cjs/EntityAddress.js +9 -1
  14. package/dist/cjs/EntityAddress.js.map +1 -1
  15. package/dist/cjs/EntityId.js +7 -1
  16. package/dist/cjs/EntityId.js.map +1 -1
  17. package/dist/cjs/EntityProxy.js +1 -1
  18. package/dist/cjs/EntityProxy.js.map +1 -1
  19. package/dist/cjs/HttpRunner.js +69 -43
  20. package/dist/cjs/HttpRunner.js.map +1 -1
  21. package/dist/cjs/MessageStorage.js +64 -16
  22. package/dist/cjs/MessageStorage.js.map +1 -1
  23. package/dist/cjs/Runner.js +3 -3
  24. package/dist/cjs/Runner.js.map +1 -1
  25. package/dist/cjs/RunnerAddress.js +7 -0
  26. package/dist/cjs/RunnerAddress.js.map +1 -1
  27. package/dist/cjs/RunnerHealth.js +91 -32
  28. package/dist/cjs/RunnerHealth.js.map +1 -1
  29. package/dist/cjs/RunnerServer.js +38 -24
  30. package/dist/cjs/RunnerServer.js.map +1 -1
  31. package/dist/cjs/RunnerStorage.js +100 -0
  32. package/dist/cjs/RunnerStorage.js.map +1 -0
  33. package/dist/cjs/Runners.js +18 -22
  34. package/dist/cjs/Runners.js.map +1 -1
  35. package/dist/cjs/ShardId.js +17 -7
  36. package/dist/cjs/ShardId.js.map +1 -1
  37. package/dist/cjs/Sharding.js +444 -320
  38. package/dist/cjs/Sharding.js.map +1 -1
  39. package/dist/cjs/ShardingConfig.js +10 -14
  40. package/dist/cjs/ShardingConfig.js.map +1 -1
  41. package/dist/cjs/Snowflake.js +1 -1
  42. package/dist/cjs/SocketRunner.js +1 -1
  43. package/dist/cjs/SocketRunner.js.map +1 -1
  44. package/dist/cjs/SqlMessageStorage.js +22 -28
  45. package/dist/cjs/SqlMessageStorage.js.map +1 -1
  46. package/dist/cjs/SqlRunnerStorage.js +375 -0
  47. package/dist/cjs/SqlRunnerStorage.js.map +1 -0
  48. package/dist/cjs/index.js +5 -15
  49. package/dist/cjs/internal/entityManager.js +42 -23
  50. package/dist/cjs/internal/entityManager.js.map +1 -1
  51. package/dist/dts/ClusterError.d.ts +0 -22
  52. package/dist/dts/ClusterError.d.ts.map +1 -1
  53. package/dist/dts/ClusterMetrics.d.ts +4 -14
  54. package/dist/dts/ClusterMetrics.d.ts.map +1 -1
  55. package/dist/dts/ClusterSchema.d.ts +9 -1
  56. package/dist/dts/ClusterSchema.d.ts.map +1 -1
  57. package/dist/dts/ClusterWorkflowEngine.d.ts.map +1 -1
  58. package/dist/dts/Entity.d.ts +3 -14
  59. package/dist/dts/Entity.d.ts.map +1 -1
  60. package/dist/dts/EntityAddress.d.ts +11 -0
  61. package/dist/dts/EntityAddress.d.ts.map +1 -1
  62. package/dist/dts/EntityId.d.ts +5 -0
  63. package/dist/dts/EntityId.d.ts.map +1 -1
  64. package/dist/dts/EntityProxy.d.ts +5 -6
  65. package/dist/dts/EntityProxy.d.ts.map +1 -1
  66. package/dist/dts/HttpRunner.d.ts +48 -25
  67. package/dist/dts/HttpRunner.d.ts.map +1 -1
  68. package/dist/dts/MessageStorage.d.ts +13 -5
  69. package/dist/dts/MessageStorage.d.ts.map +1 -1
  70. package/dist/dts/Runner.d.ts +4 -4
  71. package/dist/dts/Runner.d.ts.map +1 -1
  72. package/dist/dts/RunnerAddress.d.ts +5 -0
  73. package/dist/dts/RunnerAddress.d.ts.map +1 -1
  74. package/dist/dts/RunnerHealth.d.ts +24 -16
  75. package/dist/dts/RunnerHealth.d.ts.map +1 -1
  76. package/dist/dts/RunnerServer.d.ts +5 -4
  77. package/dist/dts/RunnerServer.d.ts.map +1 -1
  78. package/dist/dts/{ShardStorage.d.ts → RunnerStorage.d.ts} +41 -54
  79. package/dist/dts/RunnerStorage.d.ts.map +1 -0
  80. package/dist/dts/Runners.d.ts +15 -11
  81. package/dist/dts/Runners.d.ts.map +1 -1
  82. package/dist/dts/ShardId.d.ts +1 -1
  83. package/dist/dts/ShardId.d.ts.map +1 -1
  84. package/dist/dts/Sharding.d.ts +20 -10
  85. package/dist/dts/Sharding.d.ts.map +1 -1
  86. package/dist/dts/ShardingConfig.d.ts +40 -14
  87. package/dist/dts/ShardingConfig.d.ts.map +1 -1
  88. package/dist/dts/SocketRunner.d.ts +4 -3
  89. package/dist/dts/SocketRunner.d.ts.map +1 -1
  90. package/dist/dts/SqlMessageStorage.d.ts +2 -3
  91. package/dist/dts/SqlMessageStorage.d.ts.map +1 -1
  92. package/dist/dts/SqlRunnerStorage.d.ts +40 -0
  93. package/dist/dts/SqlRunnerStorage.d.ts.map +1 -0
  94. package/dist/dts/index.d.ts +4 -24
  95. package/dist/dts/index.d.ts.map +1 -1
  96. package/dist/esm/ClusterError.js +0 -21
  97. package/dist/esm/ClusterError.js.map +1 -1
  98. package/dist/esm/ClusterMetrics.js +12 -14
  99. package/dist/esm/ClusterMetrics.js.map +1 -1
  100. package/dist/esm/ClusterSchema.js +17 -2
  101. package/dist/esm/ClusterSchema.js.map +1 -1
  102. package/dist/esm/ClusterWorkflowEngine.js +50 -83
  103. package/dist/esm/ClusterWorkflowEngine.js.map +1 -1
  104. package/dist/esm/Entity.js +0 -12
  105. package/dist/esm/Entity.js.map +1 -1
  106. package/dist/esm/EntityAddress.js +7 -0
  107. package/dist/esm/EntityAddress.js.map +1 -1
  108. package/dist/esm/EntityId.js +5 -0
  109. package/dist/esm/EntityId.js.map +1 -1
  110. package/dist/esm/EntityProxy.js +2 -2
  111. package/dist/esm/EntityProxy.js.map +1 -1
  112. package/dist/esm/HttpRunner.js +62 -39
  113. package/dist/esm/HttpRunner.js.map +1 -1
  114. package/dist/esm/MessageStorage.js +65 -17
  115. package/dist/esm/MessageStorage.js.map +1 -1
  116. package/dist/esm/Runner.js +3 -3
  117. package/dist/esm/Runner.js.map +1 -1
  118. package/dist/esm/RunnerAddress.js +7 -0
  119. package/dist/esm/RunnerAddress.js.map +1 -1
  120. package/dist/esm/RunnerHealth.js +88 -30
  121. package/dist/esm/RunnerHealth.js.map +1 -1
  122. package/dist/esm/RunnerServer.js +38 -24
  123. package/dist/esm/RunnerServer.js.map +1 -1
  124. package/dist/esm/RunnerStorage.js +90 -0
  125. package/dist/esm/RunnerStorage.js.map +1 -0
  126. package/dist/esm/Runners.js +19 -23
  127. package/dist/esm/Runners.js.map +1 -1
  128. package/dist/esm/ShardId.js +16 -6
  129. package/dist/esm/ShardId.js.map +1 -1
  130. package/dist/esm/Sharding.js +447 -323
  131. package/dist/esm/Sharding.js.map +1 -1
  132. package/dist/esm/ShardingConfig.js +10 -14
  133. package/dist/esm/ShardingConfig.js.map +1 -1
  134. package/dist/esm/Snowflake.js +1 -1
  135. package/dist/esm/SocketRunner.js +1 -1
  136. package/dist/esm/SocketRunner.js.map +1 -1
  137. package/dist/esm/SqlMessageStorage.js +22 -28
  138. package/dist/esm/SqlMessageStorage.js.map +1 -1
  139. package/dist/esm/SqlRunnerStorage.js +366 -0
  140. package/dist/esm/SqlRunnerStorage.js.map +1 -0
  141. package/dist/esm/index.js +4 -24
  142. package/dist/esm/index.js.map +1 -1
  143. package/dist/esm/internal/entityManager.js +41 -22
  144. package/dist/esm/internal/entityManager.js.map +1 -1
  145. package/package.json +20 -60
  146. package/src/ClusterError.ts +0 -24
  147. package/src/ClusterMetrics.ts +12 -16
  148. package/src/ClusterSchema.ts +17 -2
  149. package/src/ClusterWorkflowEngine.ts +48 -80
  150. package/src/Entity.ts +3 -21
  151. package/src/EntityAddress.ts +10 -0
  152. package/src/EntityId.ts +6 -0
  153. package/src/EntityProxy.ts +10 -10
  154. package/src/HttpRunner.ts +132 -67
  155. package/src/MessageStorage.ts +89 -24
  156. package/src/Runner.ts +4 -4
  157. package/src/RunnerAddress.ts +8 -0
  158. package/src/RunnerHealth.ts +119 -56
  159. package/src/RunnerServer.ts +64 -47
  160. package/src/RunnerStorage.ts +218 -0
  161. package/src/Runners.ts +32 -45
  162. package/src/ShardId.ts +14 -3
  163. package/src/Sharding.ts +561 -417
  164. package/src/ShardingConfig.ts +39 -31
  165. package/src/Snowflake.ts +1 -1
  166. package/src/SocketRunner.ts +6 -4
  167. package/src/SqlMessageStorage.ts +28 -30
  168. package/src/SqlRunnerStorage.ts +537 -0
  169. package/src/index.ts +4 -29
  170. package/src/internal/entityManager.ts +45 -29
  171. package/HttpCommon/package.json +0 -6
  172. package/HttpShardManager/package.json +0 -6
  173. package/ShardManager/package.json +0 -6
  174. package/ShardStorage/package.json +0 -6
  175. package/SocketShardManager/package.json +0 -6
  176. package/SqlShardStorage/package.json +0 -6
  177. package/SynchronizedClock/package.json +0 -6
  178. package/dist/cjs/HttpCommon.js +0 -48
  179. package/dist/cjs/HttpCommon.js.map +0 -1
  180. package/dist/cjs/HttpShardManager.js +0 -139
  181. package/dist/cjs/HttpShardManager.js.map +0 -1
  182. package/dist/cjs/ShardManager.js +0 -549
  183. package/dist/cjs/ShardManager.js.map +0 -1
  184. package/dist/cjs/ShardStorage.js +0 -151
  185. package/dist/cjs/ShardStorage.js.map +0 -1
  186. package/dist/cjs/SocketShardManager.js +0 -32
  187. package/dist/cjs/SocketShardManager.js.map +0 -1
  188. package/dist/cjs/SqlShardStorage.js +0 -253
  189. package/dist/cjs/SqlShardStorage.js.map +0 -1
  190. package/dist/cjs/SynchronizedClock.js +0 -65
  191. package/dist/cjs/SynchronizedClock.js.map +0 -1
  192. package/dist/cjs/internal/shardManager.js +0 -353
  193. package/dist/cjs/internal/shardManager.js.map +0 -1
  194. package/dist/dts/HttpCommon.d.ts +0 -25
  195. package/dist/dts/HttpCommon.d.ts.map +0 -1
  196. package/dist/dts/HttpShardManager.d.ts +0 -119
  197. package/dist/dts/HttpShardManager.d.ts.map +0 -1
  198. package/dist/dts/ShardManager.d.ts +0 -459
  199. package/dist/dts/ShardManager.d.ts.map +0 -1
  200. package/dist/dts/ShardStorage.d.ts.map +0 -1
  201. package/dist/dts/SocketShardManager.d.ts +0 -17
  202. package/dist/dts/SocketShardManager.d.ts.map +0 -1
  203. package/dist/dts/SqlShardStorage.d.ts +0 -38
  204. package/dist/dts/SqlShardStorage.d.ts.map +0 -1
  205. package/dist/dts/SynchronizedClock.d.ts +0 -19
  206. package/dist/dts/SynchronizedClock.d.ts.map +0 -1
  207. package/dist/dts/internal/shardManager.d.ts +0 -2
  208. package/dist/dts/internal/shardManager.d.ts.map +0 -1
  209. package/dist/esm/HttpCommon.js +0 -38
  210. package/dist/esm/HttpCommon.js.map +0 -1
  211. package/dist/esm/HttpShardManager.js +0 -128
  212. package/dist/esm/HttpShardManager.js.map +0 -1
  213. package/dist/esm/ShardManager.js +0 -535
  214. package/dist/esm/ShardManager.js.map +0 -1
  215. package/dist/esm/ShardStorage.js +0 -141
  216. package/dist/esm/ShardStorage.js.map +0 -1
  217. package/dist/esm/SocketShardManager.js +0 -24
  218. package/dist/esm/SocketShardManager.js.map +0 -1
  219. package/dist/esm/SqlShardStorage.js +0 -244
  220. package/dist/esm/SqlShardStorage.js.map +0 -1
  221. package/dist/esm/SynchronizedClock.js +0 -57
  222. package/dist/esm/SynchronizedClock.js.map +0 -1
  223. package/dist/esm/internal/shardManager.js +0 -342
  224. package/dist/esm/internal/shardManager.js.map +0 -1
  225. package/src/HttpCommon.ts +0 -73
  226. package/src/HttpShardManager.ts +0 -273
  227. package/src/ShardManager.ts +0 -823
  228. package/src/ShardStorage.ts +0 -297
  229. package/src/SocketShardManager.ts +0 -48
  230. package/src/SqlShardStorage.ts +0 -329
  231. package/src/SynchronizedClock.ts +0 -82
  232. package/src/internal/shardManager.ts +0 -412
package/src/Entity.ts CHANGED
@@ -7,14 +7,13 @@ import * as RpcGroup from "@effect/rpc/RpcGroup"
7
7
  import * as RpcServer from "@effect/rpc/RpcServer"
8
8
  import * as Arr from "effect/Array"
9
9
  import type { Brand } from "effect/Brand"
10
- import * as Cause from "effect/Cause"
10
+ import type * as Cause from "effect/Cause"
11
11
  import * as Context from "effect/Context"
12
12
  import * as Data from "effect/Data"
13
13
  import type { DurationInput } from "effect/Duration"
14
14
  import * as Effect from "effect/Effect"
15
15
  import * as Equal from "effect/Equal"
16
16
  import * as Exit from "effect/Exit"
17
- import * as FiberId from "effect/FiberId"
18
17
  import { identity } from "effect/Function"
19
18
  import * as Hash from "effect/Hash"
20
19
  import * as Layer from "effect/Layer"
@@ -24,12 +23,7 @@ import * as Predicate from "effect/Predicate"
24
23
  import type * as Schedule from "effect/Schedule"
25
24
  import { Scope } from "effect/Scope"
26
25
  import type * as Stream from "effect/Stream"
27
- import type {
28
- AlreadyProcessingMessage,
29
- EntityNotManagedByRunner,
30
- MailboxFull,
31
- PersistenceError
32
- } from "./ClusterError.js"
26
+ import type { AlreadyProcessingMessage, MailboxFull, PersistenceError } from "./ClusterError.js"
33
27
  import { ShardGroup } from "./ClusterSchema.js"
34
28
  import { EntityAddress } from "./EntityAddress.js"
35
29
  import type { EntityId } from "./EntityId.js"
@@ -114,7 +108,7 @@ export interface Entity<
114
108
  entityId: string
115
109
  ) => RpcClient.RpcClient.From<
116
110
  Rpcs,
117
- MailboxFull | AlreadyProcessingMessage | PersistenceError | EntityNotManagedByRunner
111
+ MailboxFull | AlreadyProcessingMessage | PersistenceError
118
112
  >,
119
113
  never,
120
114
  Sharding
@@ -493,18 +487,6 @@ export class Request<Rpc extends Rpc.Any> extends Data.Class<
493
487
 
494
488
  const shardingTag = Context.GenericTag<Sharding, Sharding["Type"]>("@effect/cluster/Sharding")
495
489
 
496
- /**
497
- * @since 1.0.0
498
- * @category Interruption
499
- */
500
- export const fiberIdIgnored = FiberId.make(-1, 0)
501
-
502
- /**
503
- * @since 1.0.0
504
- * @category Interruption
505
- */
506
- export const interruptIgnored = Effect.failCause(Cause.interrupt(fiberIdIgnored))
507
-
508
490
  /**
509
491
  * @since 1.0.0
510
492
  * @category Testing
@@ -63,3 +63,13 @@ export class EntityAddress extends Schema.Class<EntityAddress>(SymbolKey)({
63
63
  export const EntityAddressFromSelf: Schema.Schema<EntityAddress> = Schema.typeSchema(
64
64
  EntityAddress
65
65
  )
66
+
67
+ /**
68
+ * @since 4.0.0
69
+ * @category constructors
70
+ */
71
+ export const make = (options: {
72
+ readonly shardId: ShardId
73
+ readonly entityType: EntityType
74
+ readonly entityId: EntityId
75
+ }): EntityAddress => new EntityAddress(options, { disableValidation: true })
package/src/EntityId.ts CHANGED
@@ -14,3 +14,9 @@ export const EntityId = Schema.NonEmptyTrimmedString.pipe(Schema.brand("EntityId
14
14
  * @category models
15
15
  */
16
16
  export type EntityId = typeof EntityId.Type
17
+
18
+ /**
19
+ * @since 1.0.0
20
+ * @category constructors
21
+ */
22
+ export const make = (id: string): EntityId => id as EntityId
@@ -6,14 +6,13 @@ import * as HttpApiGroup from "@effect/platform/HttpApiGroup"
6
6
  import * as Rpc from "@effect/rpc/Rpc"
7
7
  import * as RpcGroup from "@effect/rpc/RpcGroup"
8
8
  import * as Schema from "effect/Schema"
9
- import { AlreadyProcessingMessage, EntityNotManagedByRunner, MailboxFull, PersistenceError } from "./ClusterError.js"
9
+ import { AlreadyProcessingMessage, MailboxFull, PersistenceError } from "./ClusterError.js"
10
10
  import type * as Entity from "./Entity.js"
11
11
 
12
12
  const clientErrors = [
13
13
  MailboxFull,
14
14
  AlreadyProcessingMessage,
15
- PersistenceError,
16
- EntityNotManagedByRunner
15
+ PersistenceError
17
16
  ] as const
18
17
 
19
18
  /**
@@ -94,12 +93,14 @@ export type ConvertRpcs<Rpcs extends Rpc.Any, Prefix extends string> = Rpcs exte
94
93
  }>,
95
94
  _Success,
96
95
  Schema.Schema<
97
- _Error["Type"] | MailboxFull | AlreadyProcessingMessage | PersistenceError | EntityNotManagedByRunner,
96
+ | _Error["Type"]
97
+ | MailboxFull
98
+ | AlreadyProcessingMessage
99
+ | PersistenceError
98
100
  | _Error["Encoded"]
99
101
  | typeof MailboxFull["Encoded"]
100
102
  | typeof AlreadyProcessingMessage["Encoded"]
101
- | typeof PersistenceError["Encoded"]
102
- | typeof EntityNotManagedByRunner["Encoded"],
103
+ | typeof PersistenceError["Encoded"],
103
104
  _Error["Context"]
104
105
  >
105
106
  >
@@ -113,8 +114,7 @@ export type ConvertRpcs<Rpcs extends Rpc.Any, Prefix extends string> = Rpcs exte
113
114
  Schema.Union<[
114
115
  typeof MailboxFull,
115
116
  typeof AlreadyProcessingMessage,
116
- typeof PersistenceError,
117
- typeof EntityNotManagedByRunner
117
+ typeof PersistenceError
118
118
  ]>
119
119
  >
120
120
  : never
@@ -210,7 +210,7 @@ export type ConvertHttpApi<Rpcs extends Rpc.Any> = Rpcs extends Rpc.Rpc<
210
210
  _Payload["Type"],
211
211
  never,
212
212
  _Success["Type"],
213
- _Error["Type"] | MailboxFull | AlreadyProcessingMessage | PersistenceError | EntityNotManagedByRunner,
213
+ _Error["Type"] | MailboxFull | AlreadyProcessingMessage | PersistenceError,
214
214
  _Payload["Context"] | _Success["Context"],
215
215
  _Error["Context"]
216
216
  >
@@ -222,6 +222,6 @@ export type ConvertHttpApi<Rpcs extends Rpc.Any> = Rpcs extends Rpc.Rpc<
222
222
  _Payload["Type"],
223
223
  never,
224
224
  void,
225
- MailboxFull | AlreadyProcessingMessage | PersistenceError | EntityNotManagedByRunner
225
+ MailboxFull | AlreadyProcessingMessage | PersistenceError
226
226
  >
227
227
  : never
package/src/HttpRunner.ts CHANGED
@@ -1,34 +1,116 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
- import type * as HttpApp from "@effect/platform/HttpApp"
5
- import type * as HttpClient from "@effect/platform/HttpClient"
6
- import * as HttpRouter from "@effect/platform/HttpRouter"
7
- import * as HttpServer from "@effect/platform/HttpServer"
8
- import type * as Socket from "@effect/platform/Socket"
9
- import type * as RpcSerialization from "@effect/rpc/RpcSerialization"
4
+ import * as HttpClient from "@effect/platform/HttpClient"
5
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest"
6
+ import * as HttpRouter from "@effect/platform/HttpLayerRouter"
7
+ import type * as HttpServer from "@effect/platform/HttpServer"
8
+ import type { HttpServerRequest } from "@effect/platform/HttpServerRequest"
9
+ import type { HttpServerResponse } from "@effect/platform/HttpServerResponse"
10
+ import * as Socket from "@effect/platform/Socket"
11
+ import * as RpcClient from "@effect/rpc/RpcClient"
12
+ import * as RpcSerialization from "@effect/rpc/RpcSerialization"
10
13
  import * as RpcServer from "@effect/rpc/RpcServer"
11
14
  import * as Effect from "effect/Effect"
12
15
  import * as Layer from "effect/Layer"
13
16
  import type { Scope } from "effect/Scope"
14
- import { layerClientProtocolHttp, layerClientProtocolWebsocket } from "./HttpCommon.js"
15
17
  import type { MessageStorage } from "./MessageStorage.js"
18
+ import type { RunnerHealth } from "./RunnerHealth.js"
16
19
  import * as Runners from "./Runners.js"
20
+ import { RpcClientProtocol } from "./Runners.js"
17
21
  import * as RunnerServer from "./RunnerServer.js"
22
+ import type { RunnerStorage } from "./RunnerStorage.js"
18
23
  import * as Sharding from "./Sharding.js"
19
24
  import type * as ShardingConfig from "./ShardingConfig.js"
20
- import * as ShardManager from "./ShardManager.js"
21
- import type { ShardStorage } from "./ShardStorage.js"
22
- import * as SynchronizedClock from "./SynchronizedClock.js"
25
+
26
+ /**
27
+ * @since 1.0.0
28
+ * @category Layers
29
+ */
30
+ export const layerClientProtocolHttp = (options: {
31
+ readonly path: string
32
+ readonly https?: boolean | undefined
33
+ }): Layer.Layer<
34
+ RpcClientProtocol,
35
+ never,
36
+ RpcSerialization.RpcSerialization | HttpClient.HttpClient
37
+ > =>
38
+ Layer.effect(RpcClientProtocol)(
39
+ Effect.gen(function*() {
40
+ const serialization = yield* RpcSerialization.RpcSerialization
41
+ const client = yield* HttpClient.HttpClient
42
+ const https = options.https ?? false
43
+ return (address) => {
44
+ const clientWithUrl = HttpClient.mapRequest(
45
+ client,
46
+ HttpClientRequest.prependUrl(`http${https ? "s" : ""}://${address.host}:${address.port}/${options.path}`)
47
+ )
48
+ return RpcClient.makeProtocolHttp(clientWithUrl).pipe(
49
+ Effect.provideService(RpcSerialization.RpcSerialization, serialization)
50
+ )
51
+ }
52
+ })
53
+ )
54
+
55
+ /**
56
+ * @since 1.0.0
57
+ * @category Layers
58
+ */
59
+ export const layerClientProtocolHttpDefault: Layer.Layer<
60
+ Runners.RpcClientProtocol,
61
+ never,
62
+ RpcSerialization.RpcSerialization | HttpClient.HttpClient
63
+ > = layerClientProtocolHttp({ path: "/" })
64
+
65
+ /**
66
+ * @since 1.0.0
67
+ * @category Layers
68
+ */
69
+ export const layerClientProtocolWebsocket = (options: {
70
+ readonly path: string
71
+ readonly https?: boolean | undefined
72
+ }): Layer.Layer<
73
+ RpcClientProtocol,
74
+ never,
75
+ RpcSerialization.RpcSerialization | Socket.WebSocketConstructor
76
+ > =>
77
+ Layer.effect(RpcClientProtocol)(
78
+ Effect.gen(function*() {
79
+ const serialization = yield* RpcSerialization.RpcSerialization
80
+ const https = options.https ?? false
81
+ const constructor = yield* Socket.WebSocketConstructor
82
+ return Effect.fnUntraced(function*(address) {
83
+ const socket = yield* Socket.makeWebSocket(
84
+ `ws${https ? "s" : ""}://${address.host}:${address.port}/${options.path}`
85
+ ).pipe(
86
+ Effect.provideService(Socket.WebSocketConstructor, constructor)
87
+ )
88
+ return yield* RpcClient.makeProtocolSocket().pipe(
89
+ Effect.provideService(Socket.Socket, socket),
90
+ Effect.provideService(RpcSerialization.RpcSerialization, serialization)
91
+ )
92
+ })
93
+ })
94
+ )
95
+
96
+ /**
97
+ * @since 1.0.0
98
+ * @category Layers
99
+ */
100
+ export const layerClientProtocolWebsocketDefault: Layer.Layer<
101
+ Runners.RpcClientProtocol,
102
+ never,
103
+ RpcSerialization.RpcSerialization | Socket.WebSocketConstructor
104
+ > = layerClientProtocolWebsocket({ path: "/" })
23
105
 
24
106
  /**
25
107
  * @since 1.0.0
26
108
  * @category Http App
27
109
  */
28
- export const toHttpApp: Effect.Effect<
29
- HttpApp.Default<never, Scope>,
110
+ export const toHttpEffect: Effect.Effect<
111
+ Effect.Effect<HttpServerResponse, never, Scope | HttpServerRequest>,
30
112
  never,
31
- Scope | Sharding.Sharding | RpcSerialization.RpcSerialization | MessageStorage
113
+ Scope | RpcSerialization.RpcSerialization | Sharding.Sharding | MessageStorage
32
114
  > = Effect.gen(function*() {
33
115
  const handlers = yield* Layer.build(RunnerServer.layerHandlers)
34
116
  return yield* RpcServer.toHttpApp(Runners.Rpcs, {
@@ -41,18 +123,16 @@ export const toHttpApp: Effect.Effect<
41
123
  * @since 1.0.0
42
124
  * @category Http App
43
125
  */
44
- export const toHttpAppWebsocket: Effect.Effect<
45
- HttpApp.Default<never, Scope>,
126
+ export const toHttpEffectWebsocket: Effect.Effect<
127
+ Effect.Effect<HttpServerResponse, never, Scope | HttpServerRequest>,
46
128
  never,
47
- Scope | Sharding.Sharding | RpcSerialization.RpcSerialization | MessageStorage
129
+ Scope | RpcSerialization.RpcSerialization | Sharding.Sharding | MessageStorage
48
130
  > = Effect.gen(function*() {
49
131
  const handlers = yield* Layer.build(RunnerServer.layerHandlers)
50
132
  return yield* RpcServer.toHttpAppWebsocket(Runners.Rpcs, {
51
133
  spanPrefix: "RunnerServer",
52
134
  disableTracing: true
53
- }).pipe(
54
- Effect.provide(handlers)
55
- )
135
+ }).pipe(Effect.provide(handlers))
56
136
  })
57
137
 
58
138
  /**
@@ -62,75 +142,55 @@ export const toHttpAppWebsocket: Effect.Effect<
62
142
  export const layerClient: Layer.Layer<
63
143
  Sharding.Sharding | Runners.Runners,
64
144
  never,
65
- ShardingConfig.ShardingConfig | Runners.RpcClientProtocol | MessageStorage | ShardStorage
145
+ ShardingConfig.ShardingConfig | Runners.RpcClientProtocol | MessageStorage | RunnerStorage | RunnerHealth
66
146
  > = Sharding.layer.pipe(
67
- Layer.provideMerge(Runners.layerRpc),
68
- Layer.provideMerge(SynchronizedClock.layer),
69
- Layer.provide(ShardManager.layerClientRpc)
147
+ Layer.provideMerge(Runners.layerRpc)
70
148
  )
71
149
 
72
150
  /**
73
151
  * A HTTP layer for the `Runners` services, that adds a route to the provided
74
- * `HttpRouter.Tag`.
75
- *
76
- * By default, it uses the `HttpRouter.Default` tag.
152
+ * `HttpRouter`.
77
153
  *
78
154
  * @since 1.0.0
79
155
  * @category Layers
80
156
  */
81
- export const layer = <I = HttpRouter.Default>(options: {
157
+ export const layerHttpOptions = (options: {
82
158
  readonly path: HttpRouter.PathInput
83
- readonly routerTag?: HttpRouter.HttpRouter.TagClass<I, string, any, any>
84
- readonly logAddress?: boolean | undefined
85
159
  }): Layer.Layer<
86
160
  Sharding.Sharding | Runners.Runners,
87
161
  never,
162
+ | RunnerStorage
163
+ | RunnerHealth
88
164
  | RpcSerialization.RpcSerialization
165
+ | MessageStorage
89
166
  | ShardingConfig.ShardingConfig
90
167
  | Runners.RpcClientProtocol
91
- | HttpServer.HttpServer
92
- | MessageStorage
93
- | ShardStorage
94
- > => {
95
- const layer = RunnerServer.layerWithClients.pipe(
168
+ | HttpRouter.HttpRouter
169
+ > =>
170
+ RunnerServer.layerWithClients.pipe(
96
171
  Layer.provide(RpcServer.layerProtocolHttp(options))
97
172
  )
98
- return options.logAddress ? withLogAddress(layer) : layer
99
- }
100
173
 
101
174
  /**
102
175
  * @since 1.0.0
103
176
  * @category Layers
104
177
  */
105
- export const layerWebsocketOptions = <I = HttpRouter.Default>(options: {
178
+ export const layerWebsocketOptions = (options: {
106
179
  readonly path: HttpRouter.PathInput
107
- readonly routerTag?: HttpRouter.HttpRouter.TagClass<I, string, any, any>
108
- readonly logAddress?: boolean | undefined
109
180
  }): Layer.Layer<
110
181
  Sharding.Sharding | Runners.Runners,
111
182
  never,
112
- | RpcSerialization.RpcSerialization
113
183
  | ShardingConfig.ShardingConfig
114
184
  | Runners.RpcClientProtocol
115
- | HttpServer.HttpServer
116
185
  | MessageStorage
117
- | ShardStorage
118
- > => {
119
- const layer = RunnerServer.layerWithClients.pipe(
186
+ | RunnerStorage
187
+ | RunnerHealth
188
+ | RpcSerialization.RpcSerialization
189
+ | HttpRouter.HttpRouter
190
+ > =>
191
+ RunnerServer.layerWithClients.pipe(
120
192
  Layer.provide(RpcServer.layerProtocolWebsocket(options))
121
193
  )
122
- return options.logAddress ? withLogAddress(layer) : layer
123
- }
124
-
125
- const withLogAddress = <A, E, R>(layer: Layer.Layer<A, E, R>): Layer.Layer<A, E, R | HttpServer.HttpServer> =>
126
- Layer.effectDiscard(
127
- HttpServer.addressFormattedWith((address) =>
128
- Effect.annotateLogs(Effect.logInfo(`Listening on: ${address}`), {
129
- package: "@effect/cluster",
130
- service: "Runner"
131
- })
132
- )
133
- ).pipe(Layer.provideMerge(layer))
134
194
 
135
195
  /**
136
196
  * @since 1.0.0
@@ -144,10 +204,10 @@ export const layerHttp: Layer.Layer<
144
204
  | HttpClient.HttpClient
145
205
  | HttpServer.HttpServer
146
206
  | MessageStorage
147
- | ShardStorage
148
- > = HttpRouter.Default.serve().pipe(
149
- Layer.provideMerge(layer({ path: "/", logAddress: true })),
150
- Layer.provide(layerClientProtocolHttp({ path: "/" }))
207
+ | RunnerStorage
208
+ | RunnerHealth
209
+ > = HttpRouter.serve(layerHttpOptions({ path: "/" })).pipe(
210
+ Layer.provide(layerClientProtocolHttpDefault)
151
211
  )
152
212
 
153
213
  /**
@@ -161,8 +221,9 @@ export const layerHttpClientOnly: Layer.Layer<
161
221
  | ShardingConfig.ShardingConfig
162
222
  | HttpClient.HttpClient
163
223
  | MessageStorage
224
+ | RunnerStorage
164
225
  > = RunnerServer.layerClientOnly.pipe(
165
- Layer.provide(layerClientProtocolHttp({ path: "/" }))
226
+ Layer.provide(layerClientProtocolHttpDefault)
166
227
  )
167
228
 
168
229
  /**
@@ -177,10 +238,10 @@ export const layerWebsocket: Layer.Layer<
177
238
  | Socket.WebSocketConstructor
178
239
  | HttpServer.HttpServer
179
240
  | MessageStorage
180
- | ShardStorage
181
- > = HttpRouter.Default.serve().pipe(
182
- Layer.provideMerge(layerWebsocketOptions({ path: "/", logAddress: true })),
183
- Layer.provide(layerClientProtocolWebsocket({ path: "/" }))
241
+ | RunnerStorage
242
+ | RunnerHealth
243
+ > = HttpRouter.serve(layerWebsocketOptions({ path: "/" })).pipe(
244
+ Layer.provide(layerClientProtocolWebsocketDefault)
184
245
  )
185
246
 
186
247
  /**
@@ -190,7 +251,11 @@ export const layerWebsocket: Layer.Layer<
190
251
  export const layerWebsocketClientOnly: Layer.Layer<
191
252
  Sharding.Sharding | Runners.Runners,
192
253
  never,
193
- ShardingConfig.ShardingConfig | MessageStorage | RpcSerialization.RpcSerialization | Socket.WebSocketConstructor
254
+ | ShardingConfig.ShardingConfig
255
+ | MessageStorage
256
+ | RunnerStorage
257
+ | RpcSerialization.RpcSerialization
258
+ | Socket.WebSocketConstructor
194
259
  > = RunnerServer.layerClientOnly.pipe(
195
- Layer.provide(layerClientProtocolWebsocket({ path: "/" }))
260
+ Layer.provide(layerClientProtocolWebsocketDefault)
196
261
  )
@@ -15,13 +15,13 @@ import type { ParseError } from "effect/ParseResult"
15
15
  import type { Predicate } from "effect/Predicate"
16
16
  import * as Schema from "effect/Schema"
17
17
  import type { PersistenceError } from "./ClusterError.js"
18
- import { MalformedMessage } from "./ClusterError.js"
18
+ import { EntityNotAssignedToRunner, MalformedMessage } from "./ClusterError.js"
19
19
  import * as DeliverAt from "./DeliverAt.js"
20
20
  import type { EntityAddress } from "./EntityAddress.js"
21
21
  import * as Envelope from "./Envelope.js"
22
22
  import * as Message from "./Message.js"
23
23
  import * as Reply from "./Reply.js"
24
- import { ShardId } from "./ShardId.js"
24
+ import type { ShardId } from "./ShardId.js"
25
25
  import type { ShardingConfig } from "./ShardingConfig.js"
26
26
  import * as Snowflake from "./Snowflake.js"
27
27
 
@@ -88,15 +88,19 @@ export class MessageStorage extends Context.Tag("@effect/cluster/MessageStorage"
88
88
  * For locally sent messages, register a handler to process the replies.
89
89
  */
90
90
  readonly registerReplyHandler: <R extends Rpc.Any>(
91
- message: Message.OutgoingRequest<R> | Message.IncomingRequest<R>,
92
- onUnregister: Effect.Effect<void>
93
- ) => Effect.Effect<void>
91
+ message: Message.OutgoingRequest<R> | Message.IncomingRequest<R>
92
+ ) => Effect.Effect<void, EntityNotAssignedToRunner>
94
93
 
95
94
  /**
96
95
  * Unregister the reply handler for the specified message.
97
96
  */
98
97
  readonly unregisterReplyHandler: (requestId: Snowflake.Snowflake) => Effect.Effect<void>
99
98
 
99
+ /**
100
+ * Unregister the reply handlers for the specified ShardId.
101
+ */
102
+ readonly unregisterShardReplyHandlers: (shardId: ShardId) => Effect.Effect<void>
103
+
100
104
  /**
101
105
  * Retrieves the unprocessed messages for the specified shards.
102
106
  *
@@ -342,38 +346,98 @@ export type EncodedRepliesOptions<A> = {
342
346
  * @category constructors
343
347
  */
344
348
  export const make = (
345
- storage: Omit<MessageStorage["Type"], "registerReplyHandler" | "unregisterReplyHandler">
349
+ storage: Omit<
350
+ MessageStorage["Type"],
351
+ "registerReplyHandler" | "unregisterReplyHandler" | "unregisterShardReplyHandlers"
352
+ >
346
353
  ): Effect.Effect<MessageStorage["Type"]> =>
347
354
  Effect.sync(() => {
348
- const replyHandlers = new Map<Snowflake.Snowflake, {
355
+ type ReplyHandler = {
356
+ readonly message: Message.OutgoingRequest<any> | Message.IncomingRequest<any>
357
+ readonly shardSet: Set<ReplyHandler>
349
358
  readonly respond: (reply: Reply.ReplyWithContext<any>) => Effect.Effect<void, PersistenceError | MalformedMessage>
350
- readonly onUnregister: Effect.Effect<void>
351
- }>()
359
+ readonly resume: (effect: Effect.Effect<void, EntityNotAssignedToRunner>) => void
360
+ }
361
+ const replyHandlers = new Map<Snowflake.Snowflake, Array<ReplyHandler>>()
362
+ const replyHandlersShard = new Map<string, Set<ReplyHandler>>()
352
363
  return MessageStorage.of({
353
364
  ...storage,
354
- registerReplyHandler: (message, onUnregister) =>
355
- Effect.sync(() => {
356
- replyHandlers.set(message.envelope.requestId, {
365
+ registerReplyHandler: (message) => {
366
+ const requestId = message.envelope.requestId
367
+ return Effect.async<void, EntityNotAssignedToRunner>((resume) => {
368
+ const shardId = message.envelope.address.shardId.toString()
369
+ let handlers = replyHandlers.get(requestId)
370
+ if (handlers === undefined) {
371
+ handlers = []
372
+ replyHandlers.set(requestId, handlers)
373
+ }
374
+ let shardSet = replyHandlersShard.get(shardId)
375
+ if (!shardSet) {
376
+ shardSet = new Set()
377
+ replyHandlersShard.set(shardId, shardSet)
378
+ }
379
+ const entry: ReplyHandler = {
380
+ message,
381
+ shardSet,
357
382
  respond: message._tag === "IncomingRequest" ? message.respond : (reply) => message.respond(reply.reply),
358
- onUnregister
383
+ resume
384
+ }
385
+ handlers.push(entry)
386
+ shardSet.add(entry)
387
+ return Effect.sync(() => {
388
+ const index = handlers.indexOf(entry)
389
+ handlers.splice(index, 1)
390
+ shardSet.delete(entry)
359
391
  })
360
- }),
392
+ })
393
+ },
361
394
  unregisterReplyHandler: (requestId) =>
362
- Effect.suspend(() => {
363
- const handler = replyHandlers.get(requestId)
364
- if (!handler) return Effect.void
395
+ Effect.sync(() => {
396
+ const handlers = replyHandlers.get(requestId)
397
+ if (!handlers) return Effect.void
365
398
  replyHandlers.delete(requestId)
366
- return handler.onUnregister
399
+ for (let i = 0; i < handlers.length; i++) {
400
+ const handler = handlers[i]
401
+ handler.shardSet.delete(handler)
402
+ handler.resume(Effect.fail(
403
+ new EntityNotAssignedToRunner({
404
+ address: handler.message.envelope.address
405
+ })
406
+ ))
407
+ }
408
+ }),
409
+ unregisterShardReplyHandlers: (shardId) =>
410
+ Effect.sync(() => {
411
+ const id = shardId.toString()
412
+ const shardSet = replyHandlersShard.get(id)
413
+ if (!shardSet) return
414
+ replyHandlersShard.delete(id)
415
+ shardSet.forEach((handler) => {
416
+ replyHandlers.delete(handler.message.envelope.requestId)
417
+ handler.resume(Effect.fail(
418
+ new EntityNotAssignedToRunner({
419
+ address: handler.message.envelope.address
420
+ })
421
+ ))
422
+ })
367
423
  }),
368
424
  saveReply(reply) {
425
+ const requestId = reply.reply.requestId
369
426
  return Effect.flatMap(storage.saveReply(reply), () => {
370
- const handler = replyHandlers.get(reply.reply.requestId)
371
- if (!handler) {
427
+ const handlers = replyHandlers.get(requestId)
428
+ if (!handlers) {
372
429
  return Effect.void
373
430
  } else if (reply.reply._tag === "WithExit") {
374
- replyHandlers.delete(reply.reply.requestId)
431
+ replyHandlers.delete(requestId)
432
+ for (let i = 0; i < handlers.length; i++) {
433
+ const handler = handlers[i]
434
+ handler.shardSet.delete(handler)
435
+ handler.resume(Effect.void)
436
+ }
375
437
  }
376
- return handler.respond(reply)
438
+ return handlers.length === 1
439
+ ? handlers[0].respond(reply)
440
+ : Effect.forEach(handlers, (handler) => handler.respond(reply))
377
441
  })
378
442
  }
379
443
  })
@@ -748,8 +812,9 @@ export class MemoryDriver extends Effect.Service<MemoryDriver>()("@effect/cluste
748
812
  }>()
749
813
  for (let index = 0; index < journal.length; index++) {
750
814
  const envelope = journal[index]
751
- const shardId = ShardId.make(envelope.address.shardId)
752
- if (!unprocessed.has(envelope as any) || !shardIds.includes(shardId.toString())) {
815
+ const shardId = envelope.address.shardId
816
+ const shardIdStr = `${shardId.group}:${shardId.id}`
817
+ if (!unprocessed.has(envelope as any) || !shardIds.includes(shardIdStr)) {
753
818
  continue
754
819
  }
755
820
  if (envelope._tag === "Request") {
package/src/Runner.ts CHANGED
@@ -38,7 +38,7 @@ export type TypeId = typeof TypeId
38
38
  export class Runner extends Schema.Class<Runner>(SymbolKey)({
39
39
  address: RunnerAddress,
40
40
  groups: Schema.Array(Schema.String),
41
- version: Schema.Int
41
+ weight: Schema.Number
42
42
  }) {
43
43
  /**
44
44
  * @since 1.0.0
@@ -71,14 +71,14 @@ export class Runner extends Schema.Class<Runner>(SymbolKey)({
71
71
  * @since 1.0.0
72
72
  */
73
73
  [Equal.symbol](that: Runner): boolean {
74
- return this.address[Equal.symbol](that.address) && this.version === that.version
74
+ return this.address[Equal.symbol](that.address) && this.weight === that.weight
75
75
  }
76
76
 
77
77
  /**
78
78
  * @since 1.0.0
79
79
  */
80
80
  [Hash.symbol](): number {
81
- return Hash.cached(this, Hash.string(`${this.address.toString()}:${this.version}`))
81
+ return Hash.cached(this, Hash.string(`${this.address.toString()}:${this.weight}`))
82
82
  }
83
83
  }
84
84
 
@@ -98,5 +98,5 @@ export class Runner extends Schema.Class<Runner>(SymbolKey)({
98
98
  export const make = (props: {
99
99
  readonly address: RunnerAddress
100
100
  readonly groups: ReadonlyArray<string>
101
- readonly version: number
101
+ readonly weight: number
102
102
  }): Runner => new Runner(props)
@@ -4,6 +4,7 @@
4
4
  import * as Equal from "effect/Equal"
5
5
  import * as Hash from "effect/Hash"
6
6
  import { NodeInspectSymbol } from "effect/Inspectable"
7
+ import * as PrimaryKey from "effect/PrimaryKey"
7
8
  import * as Schema from "effect/Schema"
8
9
 
9
10
  const SymbolKey = "@effect/cluster/RunnerAddress"
@@ -33,6 +34,13 @@ export class RunnerAddress extends Schema.Class<RunnerAddress>(SymbolKey)({
33
34
  */
34
35
  readonly [TypeId] = TypeId;
35
36
 
37
+ /**
38
+ * @since 1.0.0
39
+ */
40
+ [PrimaryKey.symbol](): string {
41
+ return `${this.host}:${this.port}`
42
+ }
43
+
36
44
  /**
37
45
  * @since 1.0.0
38
46
  */