* Checks the memo map to see if a layer exists. If it is, immediately * returns it. Otherwise, obtains the layer, stores it in the memo map, * and adds a finalizer to the `Scope`.
(
layer: Layer.Layer<ROut, E, RIn>,
scope: Scope.Scope
)
| 210 | * and adds a finalizer to the `Scope`. |
| 211 | */ |
| 212 | getOrElseMemoize<RIn, E, ROut>( |
| 213 | layer: Layer.Layer<ROut, E, RIn>, |
| 214 | scope: Scope.Scope |
| 215 | ): Effect.Effect<Context.Context<ROut>, E, RIn> { |
| 216 | return pipe( |
| 217 | synchronized.modifyEffect(this.ref, (map) => { |
| 218 | const inMap = map.get(layer) |
| 219 | if (inMap !== undefined) { |
| 220 | const [acquire, release] = inMap |
| 221 | const cached: Effect.Effect<Context.Context<ROut>, E> = pipe( |
| 222 | acquire as Effect.Effect<readonly [FiberRefsPatch.FiberRefsPatch, Context.Context<ROut>], E>, |
| 223 | core.flatMap(([patch, b]) => pipe(effect.patchFiberRefs(patch), core.as(b))), |
| 224 | core.onExit(core.exitMatch({ |
| 225 | onFailure: () => core.void, |
| 226 | onSuccess: () => core.scopeAddFinalizerExit(scope, release) |
| 227 | })) |
| 228 | ) |
| 229 | return core.succeed([cached, map] as const) |
| 230 | } |
| 231 | return pipe( |
| 232 | ref.make(0), |
| 233 | core.flatMap((observers) => |
| 234 | pipe( |
| 235 | core.deferredMake<readonly [FiberRefsPatch.FiberRefsPatch, Context.Context<ROut>], E>(), |
| 236 | core.flatMap((deferred) => |
| 237 | pipe( |
| 238 | ref.make<Scope.Scope.Finalizer>(() => core.void), |
| 239 | core.map((finalizerRef) => { |
| 240 | const resource = core.uninterruptibleMask((restore) => |
| 241 | pipe( |
| 242 | fiberRuntime.scopeMake(), |
| 243 | core.flatMap((innerScope) => |
| 244 | pipe( |
| 245 | restore(core.flatMap( |
| 246 | makeBuilder(layer, innerScope, true), |
| 247 | (f) => effect.diffFiberRefs(f(this)) |
| 248 | )), |
| 249 | core.exit, |
| 250 | core.flatMap((exit) => { |
| 251 | switch (exit._tag) { |
| 252 | case EffectOpCodes.OP_FAILURE: { |
| 253 | return pipe( |
| 254 | core.deferredFailCause(deferred, exit.effect_instruction_i0), |
| 255 | core.zipRight(core.scopeClose(innerScope, exit)), |
| 256 | core.zipRight(core.failCause(exit.effect_instruction_i0)) |
| 257 | ) |
| 258 | } |
| 259 | case EffectOpCodes.OP_SUCCESS: { |
| 260 | return pipe( |
| 261 | ref.set(finalizerRef, (exit) => |
| 262 | pipe( |
| 263 | core.scopeClose(innerScope, exit), |
| 264 | core.whenEffect( |
| 265 | ref.modify(observers, (n) => [n === 1, n - 1] as const) |
| 266 | ), |
| 267 | core.asVoid |
| 268 | )), |
| 269 | core.zipRight(ref.update(observers, (n) => n + 1)), |
no test coverage detected