Skip to content
Effect Days 2026 Get your ticket

FiberSet

Manages many fibers together inside one scope.

A FiberSet<A, E> tracks running fibers, removes each fiber when it completes, and interrupts all still-running fibers when the owning scope closes. This module includes scoped runtime constructors plus helpers for adding, clearing, running, counting, joining, and waiting for managed fibers.

14 exports Added in v2.0.0 Source

Combinators

add

Added in v2.0.0 Source

Adds a fiber to the FiberSet. When the fiber completes, it will be removed.

Signature

declare const add: {
<A, E, XE, XA>(fiber: Fiber<XA, XE>, options?: {
readonly propagateInterruption?: boolean;
}): (self: FiberSet<A, E>) => Effect<void>;
<A, E, XE, XA>(self: FiberSet<A, E>, fiber: Fiber<XA, XE>, options?: {
readonly propagateInterruption?: boolean;
}): Effect<void>;
}

Example

(Adding a fiber)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
const fiber = yield* Effect.forkChild(Effect.never)
// Add the fiber to the set
yield* FiberSet.add(set, fiber)
// The fiber is now managed by the set
return yield* FiberSet.size(set)
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => 1

addUnsafe

Added in v4.0.0 Source

Adds an existing fiber to the FiberSet using a synchronous, unsafe mutation.

When to use

Use when an already forked fiber must be registered immediately and synchronous interruption on a closed set is acceptable.

Details

When the fiber completes, it is removed from the set. If the set is already closed, the supplied fiber is interrupted immediately. Non-interruption failures are recorded for FiberSet.join.

Signature

declare const addUnsafe: {
<A, E, XE, XA>(fiber: Fiber<XA, XE>, options?: {
readonly propagateInterruption?: boolean;
}): (self: FiberSet<A, E>) => void;
<A, E, XE, XA>(self: FiberSet<A, E>, fiber: Fiber<XA, XE>, options?: {
readonly propagateInterruption?: boolean;
}): void;
}

Example

(Adding a fiber unsafely)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
const fiber = yield* Effect.forkChild(Effect.never)
// Unsafe add - doesn't return an Effect
FiberSet.addUnsafe(set, fiber)
// The fiber is now managed by the set
return yield* FiberSet.size(set)
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => 1

awaitEmpty

Added in v3.13.0 Source

Waits until the fiber set is empty.

Signature

declare function awaitEmpty<A, E>(self: FiberSet<A, E>): Effect<void>

Example

(Waiting for an empty set)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
yield* FiberSet.run(set, Effect.yieldNow)
yield* FiberSet.run(set, Effect.yieldNow)
// Wait for all fibers to complete
yield* FiberSet.awaitEmpty(set)
return yield* FiberSet.size(set)
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => 0

clear

Added in v2.0.0 Source

Interrupts all fibers in the FiberSet and clears the set.

Signature

declare function clear<A, E>(self: FiberSet<A, E>): Effect<void>

Example

(Clearing all fibers)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
// Add some fibers
yield* FiberSet.run(set, Effect.never)
yield* FiberSet.run(set, Effect.never)
const sizeBefore = yield* FiberSet.size(set)
// Clear all fibers
yield* FiberSet.clear(set)
return [sizeBefore, yield* FiberSet.size(set)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => [2, 0]

join

Added in v2.0.0 Source

Joins all fibers in the FiberSet. If any fiber in the set terminates with a failure, the returned Effect will terminate with the first failure that occurred.

Signature

declare function join<A, E>(self: FiberSet<A, E>): Effect<void, E>

Example

(Joining failing fibers)

import { Effect, Exit, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
yield* FiberSet.add(set, Effect.runFork(Effect.fail("error")))
// parent fiber will fail with "error"
yield* FiberSet.join(set)
})
const actual = await Effect.runPromise(Effect.exit(Effect.scoped(program)))
actual // => Exit.fail("error")

run

Added in v2.0.0 Source

Forks an Effect and add the forked fiber to the FiberSet. When the fiber completes, it will be removed from the FiberSet.

Signature

declare const run: {
<A, E>(self: FiberSet<A, E>, options?: {
readonly propagateInterruption?: boolean;
readonly startImmediately?: boolean;
}): <R, XE, XA>(effect: Effect<XA, XE, R>) => Effect<Fiber<XA, XE>, never, R>;
<A, E, R, XE, XA>(self: FiberSet<A, E>, effect: Effect<XA, XE, R>, options?: {
readonly propagateInterruption?: boolean;
readonly startImmediately?: boolean;
}): Effect<Fiber<XA, XE>, never, R>;
}

Example

(Forking effects into a set)

import { Effect, Fiber, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
// Fork and add to set
const fiber1 = yield* FiberSet.run(set, Effect.succeed("hello"))
const fiber2 = yield* FiberSet.run(set, Effect.succeed("world"))
// Get results
return [yield* Fiber.join(fiber1), yield* Fiber.join(fiber2)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => ["hello", "world"]

runtime

Added in v2.0.0 Source

Captures a Runtime and uses it to fork effects into the FiberSet.

Signature

declare const runtime: <A, E>(self: FiberSet<A, E>) => <R = never>() => Effect.Effect<<XE extends E, XA extends A>(effect: Effect.Effect<XA, XE, R>, options?: Effect.RunOptions & {
readonly propagateInterruption?: boolean;
}) => Fiber.Fiber<XA, XE>, never, R>

Example

(Capturing a runtime)

import { Context, Effect, Fiber, FiberSet } from "effect"
class Users extends Context.Service<Users, {
readonly getAll: Effect.Effect<Array<unknown>>
}>()("Users") {}
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
const run = yield* FiberSet.runtime(set)<Users>()
// run some effects and add the fibers to the set
const fiber = run(Effect.andThen(Users, (_) => _.getAll))
return (yield* Fiber.join(fiber)).length
}).pipe(
Effect.scoped // The fibers will be interrupted when the scope is closed
)
const actual = await Effect.runPromise(Effect.provideService(program, Users, {
getAll: Effect.succeed([])
}))
actual // => 0

runtimePromise

Added in v3.13.0 Source

Captures a Runtime and returns a Promise-based runner that forks effects into the FiberSet.

When to use

Use when you need to bridge effects to Promise values while still tracking their fibers in a FiberSet.

Details

The returned run function returns a Promise for each effect result.

See

  • runtime for a runner that returns the forked Fiber

Signature

declare function runtimePromise<A, E>(self: FiberSet<A, E>): <R = never>() => Effect<<XE, XA>(effect: Effect<XA, XE, R>, options?: RunOptions & {
readonly propagateInterruption?: boolean;
}) => Promise<XA>, never, R>

Example

(Running effects as promises)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
const runPromise = yield* FiberSet.runtimePromise(set)()
// Run effects as promises
const promise1 = runPromise(Effect.succeed("hello"))
const promise2 = runPromise(Effect.succeed("world"))
return [yield* Effect.promise(() => promise1), yield* Effect.promise(() => promise2)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => ["hello", "world"]

size

Added in v2.0.0 Source

Gets the number of fibers currently in the FiberSet.

Signature

declare function size<A, E>(self: FiberSet<A, E>): Effect<number>

Example

(Checking the set size)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
const sizeBefore = yield* FiberSet.size(set)
// Add some fibers
yield* FiberSet.run(set, Effect.never)
yield* FiberSet.run(set, Effect.never)
return [sizeBefore, yield* FiberSet.size(set)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => [0, 2]

Constructors

make

Added in v2.0.0 Source

Creates a scoped FiberSet for storing fibers.

Details

When the associated Scope is closed, all fibers in the set will be interrupted. You can add fibers to the set using FiberSet.add or FiberSet.run, and the fibers will be automatically removed from the FiberSet when they complete.

Signature

declare function make<A = unknown, E = unknown>(): Effect<FiberSet<A, E>, never, Scope>

Example

(Creating a scoped FiberSet)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
// run some effects and add the fibers to the set
yield* FiberSet.run(set, Effect.never)
yield* FiberSet.run(set, Effect.never)
yield* Effect.yieldNow
return yield* FiberSet.size(set)
}).pipe(
Effect.scoped // The fibers will be interrupted when the scope is closed
)
const actual = await Effect.runPromise(program)
actual // => 2

makeRuntime

Added in v2.0.0 Source

Creates a scoped run function that forks effects into a new FiberSet.

Details

Each call returns the forked fiber and adds it to the set. Managed fibers are removed when they complete and are interrupted when the set's scope closes.

Signature

declare function makeRuntime<R = never, A = unknown, E = unknown>(): Effect<<XE, XA>(effect: Effect<XA, XE, R>, options?: RunOptions & {
readonly propagateInterruption?: boolean;
}) => Fiber<XA, XE>, never, Scope | R>

Example

(Creating a scoped runtime)

import { Effect, Fiber, FiberSet } from "effect"
const program = Effect.gen(function*() {
const runFork = yield* FiberSet.makeRuntime()
// Fork effects using the runtime
const fiber1 = runFork(Effect.succeed("hello"))
const fiber2 = runFork(Effect.succeed("world"))
return [yield* Fiber.join(fiber1), yield* Fiber.join(fiber2)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => ["hello", "world"]

Creates a scoped run function that forks effects into a new FiberSet and returns a Promise for each effect result.

When to use

Use when many scoped fibers should be tracked as a set while exposing each result through Promise-based APIs.

Details

Managed fibers are removed when they complete and are interrupted when the set's scope closes. Each Promise resolves with the effect's success value or rejects with the squashed failure cause.

Signature

declare function makeRuntimePromise<R = never, A = unknown, E = unknown>(): Effect<<XE, XA>(effect: Effect<XA, XE, R>, options?: RunOptions & {
readonly propagateInterruption?: boolean;
}) => Promise<XA>, never, Scope | R>

Example

(Creating a promise runtime)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const runPromise = yield* FiberSet.makeRuntimePromise()
// Run effects as promises
const promise1 = runPromise(Effect.succeed("hello"))
const promise2 = runPromise(Effect.succeed("world"))
return [yield* Effect.promise(() => promise1), yield* Effect.promise(() => promise2)]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => ["hello", "world"]

Guards

isFiberSet

Added in v2.0.0 Source

Checks whether a value is a FiberSet.

Signature

declare function isFiberSet(u: unknown): u is FiberSet<unknown, unknown>

Example

(Checking if a value is a FiberSet)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make()
return [FiberSet.isFiberSet(set), FiberSet.isFiberSet({})]
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => [true, false]

Models

FiberSet interface

Added in v2.0.0 Source

A FiberSet is a collection of fibers that can be managed together. When the associated Scope is closed, all fibers in the set will be interrupted.

Signature

interface FiberSet<out A = unknown, out E = unknown> extends Pipeable, Inspectable, "/home/runner/work/website/website/.effect-source-v4/packages/effect/src/Iterable"<Fiber.Fiber<A, E>> {
readonly "~effect/FiberSet": "~effect/FiberSet";
readonly deferred: Deferred<void, unknown>;
state: {
readonly _tag: "Open";
readonly backing: Set<Fiber<A, E>>;
} | {
readonly _tag: "Closed";
};
}

Example

(Managing fibers in a set)

import { Effect, FiberSet } from "effect"
const program = Effect.gen(function*() {
const set = yield* FiberSet.make<string, string>()
// Add fibers to the set
yield* FiberSet.run(set, Effect.succeed("hello"))
yield* FiberSet.run(set, Effect.succeed("world"))
// Wait for all fibers to complete
yield* FiberSet.awaitEmpty(set)
return yield* FiberSet.size(set)
})
const actual = await Effect.runPromise(Effect.scoped(program))
actual // => 0