@effect/cluster 0.29.12 → 0.29.16

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 (54) hide show
  1. package/dist/cjs/MessageStorage.js +8 -5
  2. package/dist/cjs/MessageStorage.js.map +1 -1
  3. package/dist/cjs/RunnerServer.js +18 -11
  4. package/dist/cjs/RunnerServer.js.map +1 -1
  5. package/dist/cjs/Runners.js +21 -9
  6. package/dist/cjs/Runners.js.map +1 -1
  7. package/dist/cjs/ShardManager.js +2 -2
  8. package/dist/cjs/ShardManager.js.map +1 -1
  9. package/dist/cjs/Sharding.js +24 -3
  10. package/dist/cjs/Sharding.js.map +1 -1
  11. package/dist/cjs/SqlMessageStorage.js +7 -1
  12. package/dist/cjs/SqlMessageStorage.js.map +1 -1
  13. package/dist/cjs/SqlShardStorage.js +6 -6
  14. package/dist/cjs/SqlShardStorage.js.map +1 -1
  15. package/dist/cjs/internal/entityManager.js +13 -2
  16. package/dist/cjs/internal/entityManager.js.map +1 -1
  17. package/dist/dts/MessageStorage.d.ts +14 -2
  18. package/dist/dts/MessageStorage.d.ts.map +1 -1
  19. package/dist/dts/RunnerServer.d.ts +2 -2
  20. package/dist/dts/RunnerServer.d.ts.map +1 -1
  21. package/dist/dts/Runners.d.ts +4 -1
  22. package/dist/dts/Runners.d.ts.map +1 -1
  23. package/dist/dts/ShardManager.d.ts.map +1 -1
  24. package/dist/dts/ShardStorage.d.ts +3 -3
  25. package/dist/dts/Sharding.d.ts +3 -3
  26. package/dist/dts/Sharding.d.ts.map +1 -1
  27. package/dist/dts/SqlMessageStorage.d.ts +2 -1
  28. package/dist/dts/SqlMessageStorage.d.ts.map +1 -1
  29. package/dist/esm/MessageStorage.js +8 -5
  30. package/dist/esm/MessageStorage.js.map +1 -1
  31. package/dist/esm/RunnerServer.js +18 -11
  32. package/dist/esm/RunnerServer.js.map +1 -1
  33. package/dist/esm/Runners.js +21 -9
  34. package/dist/esm/Runners.js.map +1 -1
  35. package/dist/esm/ShardManager.js +2 -2
  36. package/dist/esm/ShardManager.js.map +1 -1
  37. package/dist/esm/Sharding.js +25 -4
  38. package/dist/esm/Sharding.js.map +1 -1
  39. package/dist/esm/SqlMessageStorage.js +7 -1
  40. package/dist/esm/SqlMessageStorage.js.map +1 -1
  41. package/dist/esm/SqlShardStorage.js +6 -6
  42. package/dist/esm/SqlShardStorage.js.map +1 -1
  43. package/dist/esm/internal/entityManager.js +13 -2
  44. package/dist/esm/internal/entityManager.js.map +1 -1
  45. package/package.json +5 -5
  46. package/src/MessageStorage.ts +29 -7
  47. package/src/RunnerServer.ts +28 -17
  48. package/src/Runners.ts +38 -9
  49. package/src/ShardManager.ts +1 -4
  50. package/src/ShardStorage.ts +1 -1
  51. package/src/Sharding.ts +30 -10
  52. package/src/SqlMessageStorage.ts +12 -1
  53. package/src/SqlShardStorage.ts +6 -6
  54. package/src/internal/entityManager.ts +18 -3
@@ -750,7 +750,18 @@ export const make = Effect.fnUntraced(function*(options?: {
750
750
  AND shard_id = ${address.shardId}
751
751
  AND entity_type = ${address.entityType}
752
752
  AND entity_id = ${address.entityId}
753
- `.pipe(
753
+ `.pipe(
754
+ Effect.asVoid,
755
+ PersistenceError.refail
756
+ ),
757
+
758
+ resetShards: (shardIds) =>
759
+ sql`
760
+ UPDATE ${messagesTableSql}
761
+ SET last_read = NULL
762
+ WHERE processed = ${sqlFalse}
763
+ AND shard_id IN (${sql.literal(shardIds.join(","))})
764
+ `.pipe(
754
765
  Effect.asVoid,
755
766
  PersistenceError.refail
756
767
  )
@@ -141,10 +141,10 @@ export const make = Effect.fnUntraced(function*(options?: {
141
141
  const sqlNow = sql.literal(sqlNowString)
142
142
 
143
143
  const lockExpiresAt = sql.onDialectOrElse({
144
- pg: () => sql`${sqlNow} - INTERVAL '120 seconds'`,
145
- mysql: () => sql`DATE_SUB(${sqlNow}, INTERVAL 120 SECOND)`,
146
- mssql: () => sql`DATEADD(SECOND, -120, ${sqlNow})`,
147
- orElse: () => sql`datetime(${sqlNow}, '-120 seconds')`
144
+ pg: () => sql`${sqlNow} - INTERVAL '15 seconds'`,
145
+ mysql: () => sql`DATE_SUB(${sqlNow}, INTERVAL 15 SECOND)`,
146
+ mssql: () => sql`DATEADD(SECOND, -15, ${sqlNow})`,
147
+ orElse: () => sql`datetime(${sqlNow}, '-15 seconds')`
148
148
  })
149
149
 
150
150
  const acquireLock = sql.onDialectOrElse({
@@ -168,7 +168,7 @@ export const make = Effect.fnUntraced(function*(options?: {
168
168
  MERGE ${locksTableSql} WITH (HOLDLOCK) AS target
169
169
  USING (SELECT * FROM (VALUES ${sql.csv(values)})) AS source (shard_id, address, acquired_at)
170
170
  ON target.shard_id = source.shard_id
171
- WHEN MATCHED AND (target.address = source.address OR DATEDIFF(SECOND, target.acquired_at, ${sqlNow}) > 120) THEN
171
+ WHEN MATCHED AND (target.address = source.address OR DATEDIFF(SECOND, target.acquired_at, ${sqlNow}) > 15) THEN
172
172
  UPDATE SET address = source.address, acquired_at = source.acquired_at
173
173
  WHEN NOT MATCHED THEN
174
174
  INSERT (shard_id, address, acquired_at)
@@ -185,7 +185,7 @@ export const make = Effect.fnUntraced(function*(options?: {
185
185
  SELECT 1 FROM ${locksTableSql}
186
186
  WHERE shard_id = source.shard_id
187
187
  AND address != ${address}
188
- AND (strftime('%s', ${sqlNow}) - strftime('%s', acquired_at)) <= 120
188
+ AND (strftime('%s', ${sqlNow}) - strftime('%s', acquired_at)) <= 15
189
189
  )
190
190
  ON CONFLICT(shard_id) DO UPDATE
191
191
  SET address = ${address}, acquired_at = ${sqlNow}
@@ -47,7 +47,9 @@ export interface EntityManager {
47
47
  message: Message.Incoming<any>
48
48
  ) => Effect.Effect<void, EntityNotManagedByRunner | MailboxFull | AlreadyProcessingMessage>
49
49
 
50
- readonly isProcessingFor: (message: Message.Incoming<any>) => boolean
50
+ readonly isProcessingFor: (message: Message.Incoming<any>, options?: {
51
+ readonly excludeReplies?: boolean
52
+ }) => boolean
51
53
 
52
54
  readonly interruptShard: (shardId: ShardId) => Effect.Effect<void>
53
55
 
@@ -62,6 +64,7 @@ export type EntityState = {
62
64
  readonly activeRequests: Map<bigint, {
63
65
  readonly rpc: Rpc.AnyWithProps
64
66
  readonly message: Message.IncomingRequestLocal<any>
67
+ sentReply: boolean
65
68
  lastSentChunk: Option.Option<Reply.Chunk<Rpc.Any>>
66
69
  sequence: number
67
70
  }>
@@ -143,6 +146,8 @@ export const make = Effect.fnUntraced(function*<
143
146
  const request = activeRequests.get(response.requestId)
144
147
  if (!request) return Effect.void
145
148
 
149
+ request.sentReply = true
150
+
146
151
  // For durable messages, ignore interrupts during shutdown.
147
152
  // They will be retried when the entity is restarted.
148
153
  if (
@@ -184,6 +189,9 @@ export const make = Effect.fnUntraced(function*<
184
189
  if (!request) return Effect.void
185
190
  const sequence = request.sequence
186
191
  request.sequence++
192
+ if (!request.sentReply) {
193
+ request.sentReply = true
194
+ }
187
195
  return Effect.orDie(retryRespond(
188
196
  4,
189
197
  Effect.suspend(() => {
@@ -336,6 +344,7 @@ export const make = Effect.fnUntraced(function*<
336
344
  entry = {
337
345
  rpc: entity.protocol.requests.get(message.envelope.tag)! as any as Rpc.AnyWithProps,
338
346
  message,
347
+ sentReply: false,
339
348
  lastSentChunk: message.lastSentReply as any,
340
349
  sequence: Option.match(message.lastSentReply, {
341
350
  onNone: () => 0,
@@ -402,10 +411,16 @@ export const make = Effect.fnUntraced(function*<
402
411
 
403
412
  return identity<EntityManager>({
404
413
  interruptShard,
405
- isProcessingFor(message) {
414
+ isProcessingFor(message, options) {
406
415
  const state = activeServers.get(message.envelope.address.entityId)
407
416
  if (!state) return false
408
- return state.activeRequests.has(message.envelope.requestId)
417
+ const request = state.activeRequests.get(message.envelope.requestId)
418
+ if (request === undefined) {
419
+ return false
420
+ } else if (options?.excludeReplies && request.sentReply) {
421
+ return false
422
+ }
423
+ return true
409
424
  },
410
425
  sendLocal,
411
426
  send: (message) =>