Skip to content

RcRef.ts

Reference-counted handles for sharing one scoped resource across many scoped users. An RcRef<A, E> acquires the resource lazily the first time get needs it, reuses that value while it is borrowed or kept idle, and finalizes it when the final borrowing scope closes unless an idle timeout keeps it available. The module also provides invalidate for forcing the next get to acquire a fresh resource.

Since v3.5.0



Gets the value from an RcRef, acquiring it first if needed.

When to use

Use to borrow the current resource within a Scope, acquiring it first if necessary.

Details

The reference count is incremented for the current Scope, and a release finalizer is added to that scope. When the current scope closes, the reference is released; the resource is closed when the final reference is released, subject to any configured idle time-to-live.

Example (Sharing one acquired value)

import { Effect, RcRef } from "effect"
const program = Effect.gen(function* () {
// Create an RcRef with a resource
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(Effect.succeed("shared resource"), (resource) => Effect.log(`Releasing ${resource}`))
})
// Get the value from the RcRef
const value1 = yield* RcRef.get(ref)
const value2 = yield* RcRef.get(ref)
// Both values are the same instance
console.log(value1 === value2) // true
return value1
})

Signature

declare const get: <A, E>(self: RcRef<A, E>) => Effect.Effect<A, E, Scope>

Source

Since v3.5.0

Invalidates the currently cached resource, if one has been acquired.

When to use

Use to force future RcRef.get calls to acquire a fresh resource when the currently cached resource should no longer be reused.

Details

After invalidation, the next get acquires a fresh resource.

Gotchas

Invalidation does not revoke resources already borrowed by active scopes; those remain usable until their scopes close.

See

  • get for acquiring the current cached resource or the fresh resource after invalidation

Signature

declare const invalidate: <A, E>(self: RcRef<A, E>) => Effect.Effect<void>

Source

Since v3.19.6

Creates an RcRef from an acquire effect.

When to use

Use to create a lazily acquired, reference-counted resource from an acquire effect.

Details

The resource is acquired lazily on the first get and shared by subsequent gets while it remains cached. Each get adds a reference to the current Scope. When the last reference is released, the resource is closed immediately by default, or after idleTimeToLive when that option is provided.

Example (Creating a reference-counted resource)

import { Effect, RcRef } from "effect"
Effect.gen(function* () {
const ref = yield* RcRef.make({
acquire: Effect.acquireRelease(Effect.succeed("foo"), () => Effect.log("release foo"))
})
// will only acquire the resource once, and release it
// when the scope is closed
yield* RcRef.get(ref).pipe(Effect.andThen(RcRef.get(ref)), Effect.scoped)
})

Signature

declare const make: <A, E, R>(options: {
readonly acquire: Effect.Effect<A, E, R>
readonly idleTimeToLive?: Duration.Input | undefined
}) => Effect.Effect<RcRef<A, E>, never, R | Scope>

Source

Since v3.5.0

A reference counted reference that manages resource lifecycle.

When to use

Use to share a scoped resource across active users with reference-counted acquisition and release.

Details

An RcRef wraps a resource that can be acquired and released multiple times. The resource is lazily acquired on the first call to get and automatically released when the last reference is released.

Example (Sharing a lazily acquired resource)

import { Effect, RcRef } from "effect"
// Create an RcRef for a database connection
const createConnectionRef = (connectionString: string) =>
RcRef.make({
acquire: Effect.acquireRelease(Effect.succeed(`Connected to ${connectionString}`), (connection) =>
Effect.log(`Closing connection: ${connection}`)
)
})
// Use the RcRef in multiple operations
const program = Effect.gen(function* () {
const connectionRef = yield* createConnectionRef("postgres://localhost")
// Multiple gets will share the same connection
const connection1 = yield* RcRef.get(connectionRef)
const connection2 = yield* RcRef.get(connectionRef)
return [connection1, connection2]
})

Signature

export interface RcRef<out A, out E = never> extends Pipeable {
readonly [TypeId]: RcRef.Variance<A, E>
}

Source

Since v3.5.0

Namespace containing type-level members associated with RcRef.

Example (Referencing namespace types)

import type { RcRef } from "effect"
// Use RcRef namespace types
type MyRcRef = RcRef.RcRef<string, Error>
type MyVariance = RcRef.RcRef.Variance<string, Error>

Source

Since v3.5.0

Type-level variance marker for RcRef.

When to use

Use to carry the value and error type parameters for RcRef in Effect’s type machinery.

Details

This interface records the covariant value and error types carried by an RcRef. It is used by Effect’s type machinery and is not normally referenced directly by users.

Signature

export interface Variance<A, E> {
readonly _A: Types.Covariant<A>
readonly _E: Types.Covariant<E>
}

Source

Since v3.5.0