@effect/cluster 0.52.4 → 0.52.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/cluster",
3
- "version": "0.52.4",
3
+ "version": "0.52.5",
4
4
  "description": "Unified interfaces for common cluster-specific services",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -12,10 +12,10 @@
12
12
  "homepage": "https://effect.website",
13
13
  "peerDependencies": {
14
14
  "@effect/platform": "^0.93.0",
15
- "@effect/rpc": "^0.72.1",
16
15
  "@effect/sql": "^0.48.0",
17
- "effect": "^3.19.1",
18
- "@effect/workflow": "^0.12.2"
16
+ "@effect/workflow": "^0.12.2",
17
+ "@effect/rpc": "^0.72.1",
18
+ "effect": "^3.19.2"
19
19
  },
20
20
  "publishConfig": {
21
21
  "provenance": true
package/src/Sharding.ts CHANGED
@@ -237,6 +237,14 @@ const make = Effect.gen(function*() {
237
237
  return MutableHashSet.has(acquiredShards, address.shardId)
238
238
  }
239
239
 
240
+ yield* Scope.addFinalizer(
241
+ shardingScope,
242
+ Effect.logDebug("Shutdown complete").pipe(Effect.annotateLogs({
243
+ package: "@effect/cluster",
244
+ module: "Sharding"
245
+ }))
246
+ )
247
+
240
248
  // --- Shard acquisition ---
241
249
  //
242
250
  // Responsible for acquiring and releasing shards from RunnerStorage.
@@ -252,6 +260,37 @@ const make = Effect.gen(function*() {
252
260
  return Effect.ignore(runnerStorage.releaseAll(selfAddress))
253
261
  })
254
262
 
263
+ const releaseShardsHandle = yield* FiberHandle.make()
264
+ const releaseShards = Effect.suspend(function loop(): Effect.Effect<void, PersistenceError> {
265
+ return Effect.flatMap(
266
+ Effect.forEach(
267
+ releasingShards,
268
+ (shardId) =>
269
+ Effect.forEach(
270
+ entityManagers.values(),
271
+ (state) => state.status === "closed" ? Effect.void : state.manager.interruptShard(shardId),
272
+ { concurrency: "unbounded", discard: true }
273
+ ).pipe(
274
+ Effect.andThen(runnerStorage.release(selfAddress, shardId)),
275
+ Effect.annotateLogs({ runner: selfAddress }),
276
+ Effect.flatMap(() => {
277
+ MutableHashSet.remove(releasingShards, shardId)
278
+ return storage.unregisterShardReplyHandlers(shardId)
279
+ })
280
+ ),
281
+ { concurrency: "unbounded", discard: true }
282
+ ),
283
+ () => {
284
+ if (MutableHashSet.size(releasingShards) === 0) {
285
+ return Effect.void
286
+ }
287
+ return loop()
288
+ }
289
+ )
290
+ }).pipe(
291
+ FiberHandle.run(releaseShardsHandle, { onlyIfMissing: true })
292
+ )
293
+
255
294
  yield* Effect.gen(function*() {
256
295
  activeShardsLatch.unsafeOpen()
257
296
 
@@ -320,7 +359,8 @@ const make = Effect.gen(function*() {
320
359
  fiber: "Shard acquisition loop",
321
360
  runner: selfAddress
322
361
  }),
323
- Effect.forkIn(shardingScope)
362
+ Effect.forkIn(shardingScope),
363
+ Effect.interruptible
324
364
  )
325
365
 
326
366
  // refresh the shard locks every `shardLockRefreshInterval`
@@ -359,38 +399,16 @@ const make = Effect.gen(function*() {
359
399
  ),
360
400
  Effect.repeat(Schedule.fixed(config.shardLockRefreshInterval)),
361
401
  Effect.forever,
362
- Effect.forkIn(shardingScope)
363
- )
364
-
365
- const releaseShardsHandle = yield* FiberHandle.make()
366
- const releaseShards = Effect.suspend(() =>
367
- Effect.forEach(
368
- releasingShards,
369
- (shardId) =>
370
- Effect.forEach(
371
- entityManagers.values(),
372
- (state) => state.manager.interruptShard(shardId),
373
- { concurrency: "unbounded", discard: true }
374
- ).pipe(
375
- Effect.andThen(runnerStorage.release(selfAddress, shardId)),
376
- Effect.annotateLogs({ runner: selfAddress }),
377
- Effect.flatMap(() => {
378
- MutableHashSet.remove(releasingShards, shardId)
379
- return storage.unregisterShardReplyHandlers(shardId)
380
- })
381
- ),
382
- { concurrency: "unbounded", discard: true }
383
- )
384
- ).pipe(
385
- Effect.repeat({ until: () => MutableHashSet.size(releasingShards) === 0 }),
386
- FiberHandle.run(releaseShardsHandle, { onlyIfMissing: true })
402
+ Effect.forkIn(shardingScope),
403
+ Effect.interruptible
387
404
  )
388
405
 
389
406
  // open the shard latch every poll interval
390
407
  yield* activeShardsLatch.open.pipe(
391
408
  Effect.delay(config.entityMessagePollInterval),
392
409
  Effect.forever,
393
- Effect.forkIn(shardingScope)
410
+ Effect.forkIn(shardingScope),
411
+ Effect.interruptible
394
412
  )
395
413
  }
396
414
 
@@ -555,14 +573,16 @@ const make = Effect.gen(function*() {
555
573
  runner: selfAddress
556
574
  }),
557
575
  Effect.withUnhandledErrorLogLevel(Option.none()),
558
- Effect.forkIn(shardingScope)
576
+ Effect.forkIn(shardingScope),
577
+ Effect.interruptible
559
578
  )
560
579
 
561
580
  // open the storage latch every poll interval
562
581
  yield* storageReadLatch.open.pipe(
563
582
  Effect.delay(config.entityMessagePollInterval),
564
583
  Effect.forever,
565
- Effect.forkIn(shardingScope)
584
+ Effect.forkIn(shardingScope),
585
+ Effect.interruptible
566
586
  )
567
587
 
568
588
  // Resume unprocessed messages for entities that reached a full mailbox.
@@ -682,7 +702,8 @@ const make = Effect.gen(function*() {
682
702
  Effect.sync(() => MutableHashMap.remove(entityResumptionState, address))
683
703
  ),
684
704
  Effect.withUnhandledErrorLogLevel(Option.none()),
685
- Effect.forkIn(shardingScope)
705
+ Effect.forkIn(shardingScope),
706
+ Effect.interruptible
686
707
  )
687
708
  }
688
709
 
@@ -958,7 +979,8 @@ const make = Effect.gen(function*() {
958
979
  fiber: "RunnerStorage sync",
959
980
  runner: config.runnerAddress
960
981
  }),
961
- Effect.forkIn(shardingScope)
982
+ Effect.forkIn(shardingScope),
983
+ Effect.interruptible
962
984
  )
963
985
 
964
986
  // --- Clients ---
@@ -447,9 +447,7 @@ export const make = Effect.fnUntraced(function*(options: {
447
447
  function*(_address, shardId) {
448
448
  const lockNum = lockNumbers.get(shardId)!
449
449
  const conn = yield* Resource.get(lockConnRef!)
450
- const release = conn.executeRaw(`SELECT pg_advisory_unlock(${lockNum})`, []).pipe(
451
- Effect.timeoutOption(Duration.seconds(5))
452
- )
450
+ const release = conn.executeRaw(`SELECT pg_advisory_unlock(${lockNum})`, [])
453
451
  const check = conn.executeValues(
454
452
  `SELECT 1 FROM pg_locks WHERE locktype = 'advisory' AND granted = true AND pid = pg_backend_pid() AND objid = ${lockNum}`,
455
453
  []
@@ -460,7 +458,6 @@ export const make = Effect.fnUntraced(function*(options: {
460
458
  if (takenLocks.length === 0) return
461
459
  }
462
460
  },
463
- Effect.timeout(config.shardLockExpiration),
464
461
  Effect.onError(() => Resource.refresh(lockConnRef!)),
465
462
  Effect.asVoid,
466
463
  PersistenceError.refail,
@@ -482,7 +479,6 @@ export const make = Effect.fnUntraced(function*(options: {
482
479
  if (takenLocks.length === 0 || takenLocks[0][0] !== 1) return
483
480
  }
484
481
  },
485
- Effect.timeout(config.shardLockExpiration),
486
482
  Effect.onError(() => Resource.refresh(lockConnRef!)),
487
483
  Effect.asVoid,
488
484
  PersistenceError.refail,
@@ -127,7 +127,7 @@ export const make = Effect.fnUntraced(function*<
127
127
  () => {
128
128
  serverCloseLatches.get(address)?.unsafeOpen()
129
129
  serverCloseLatches.delete(address)
130
- return Effect.ignore(options.storage.resetAddress(address))
130
+ return Effect.void
131
131
  }
132
132
  )
133
133