Skip to content

Commit df69cb5

Browse files
authored
provide seperate close scope to EntityResource via context (#5781)
1 parent 0a1c842 commit df69cb5

File tree

2 files changed

+28
-32
lines changed

2 files changed

+28
-32
lines changed

.changeset/lemon-planets-drum.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@effect/cluster": patch
3+
---
4+
5+
provide seperate close scope to EntityResource via context

packages/cluster/src/EntityResource.ts

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @since 1.0.0
33
*/
4+
import * as Context from "effect/Context"
45
import * as Duration from "effect/Duration"
56
import * as Effect from "effect/Effect"
67
import { identity } from "effect/Function"
@@ -31,6 +32,19 @@ export interface EntityResource<out A, out E = never> {
3132
readonly close: Effect.Effect<void>
3233
}
3334

35+
/**
36+
* A `Scope` that is only closed when the resource is explicitly closed.
37+
*
38+
* It is not closed during restarts, due to shard movement or node shutdowns.
39+
*
40+
* @since 1.0.0
41+
* @category Scope
42+
*/
43+
export class CloseScope extends Context.Tag("@effect/cluster/EntityResource/CloseScope")<
44+
CloseScope,
45+
Scope.Scope
46+
>() {}
47+
3448
/**
3549
* A `EntityResource` is a resource that can be acquired inside a cluster
3650
* entity, which will keep the entity alive even across restarts.
@@ -47,55 +61,32 @@ export interface EntityResource<out A, out E = never> {
4761
export const make: <A, E, R>(options: {
4862
readonly acquire: Effect.Effect<A, E, R>
4963
readonly idleTimeToLive?: Duration.DurationInput | undefined
50-
/**
51-
* When to close the resource Scope.
52-
*
53-
* If set to "explicit", the resource will only be cleaned up when either the
54-
* `idleTimeToLive` is reached, or the .close effect is called.
55-
*
56-
* Defaults to "always", which means the resource will be cleaned up when the
57-
* the parent Scope is closed.
58-
*/
59-
readonly shutdownMode?: "explicit" | "always" | undefined
6064
}) => Effect.Effect<
6165
EntityResource<A, E>,
6266
E,
63-
Scope.Scope | R | Sharding | Entity.CurrentAddress
67+
Scope.Scope | Exclude<R, CloseScope> | Sharding | Entity.CurrentAddress
6468
> = Effect.fnUntraced(function*<A, E, R>(options: {
6569
readonly acquire: Effect.Effect<A, E, R>
6670
readonly idleTimeToLive?: Duration.DurationInput | undefined
67-
readonly shutdownMode?: "explicit" | "always" | undefined
6871
}) {
69-
const shutdownMode = options.shutdownMode ?? "always"
7072
let shuttingDown = false
7173

7274
const ref = yield* RcRef.make({
7375
acquire: Effect.gen(function*() {
74-
let scope = yield* Effect.scope
76+
const closeable = yield* Scope.make()
7577

76-
if (shutdownMode === "explicit") {
77-
const closeable = yield* Scope.make()
78-
const context = yield* Effect.context<Sharding | Entity.CurrentAddress>()
79-
yield* Scope.addFinalizerExit(
80-
scope,
81-
Effect.fnUntraced(function*(exit) {
82-
if (shuttingDown) return
83-
yield* Scope.close(closeable, exit)
84-
yield* Entity.keepAlive(false)
85-
}, Effect.provide(context))
86-
)
87-
scope = closeable
88-
} else {
89-
yield* Effect.addFinalizer(() => {
90-
if (shuttingDown) return Effect.void
91-
return Entity.keepAlive(false)
78+
yield* Effect.addFinalizer(
79+
Effect.fnUntraced(function*(exit) {
80+
if (shuttingDown) return
81+
yield* Scope.close(closeable, exit)
82+
yield* Entity.keepAlive(false)
9283
})
93-
}
84+
)
9485

9586
yield* Entity.keepAlive(true)
9687

9788
return yield* options.acquire.pipe(
98-
Scope.extend(scope)
89+
Effect.provideService(CloseScope, closeable)
9990
)
10091
}),
10192
idleTimeToLive: options.idleTimeToLive ?? Duration.infinity

0 commit comments

Comments
 (0)