On This Page

Sharding and Supervision

25 symbols from @neontechspace/fluxerly

Functions#

fileSessionStore#

Create a SessionStore that keeps each shard's snapshot in its own file, shard-ID.json, inside one directory

Pass it as sharding.sessions so a restart within Fluxer's 60-second window resumes instead of starting new sessions. Use a directory that only the bot's account can read, outside version control, because each file holds a session ID that lets the bot's token resume that session. The store never logs snapshot contents

fileSessionStore(directory: string | URL): SessionStorefileSessionStore(
  directory: string | URL
): SessionStore

Parameters

directory
string | URL

A relative path resolves against the current working directory when the store is created, and a URL must use the file: scheme. An empty path or another URL scheme throws ConfigurationError. The store creates nothing until the first save. Each save creates the directory when missing, with mode 0700, writes the snapshot to a new temporary file with mode 0600 in that directory, flushes it to disk and renames it over the shard's file, so a crash never leaves a partly written snapshot and the previous file stays until the rename. A failed save removes its temporary file. Windows ignores these modes, so there the directory's access control list decides who can read the files. Load returns undefined when the shard has no file. It returns the parsed file without checking its fields, so the SDK ignores a malformed or outdated snapshot with a lifecycle.sessionSnapshotIgnored Warn. A file that is not valid JSON rejects with an Error that names the file but not its contents, and other file system failures reject with their Node.js error. The SDK logs those rejections as lifecycle.sessionLoadFailed or lifecycle.sessionSaveFailed and continues, as SessionStore describes. Separate processes must use separate directories unless their shard IDs never overlap

import { createClient, fileSessionStore } from "@neontechspace/fluxerly"

export function resumableClient(token) {
    return createClient({ token, sharding: { totalShards: "auto", sessions: fileSessionStore("sessions") } })
}
import { createClient, fileSessionStore } from "@neontechspace/fluxerly"

export function resumableClient(token: string) {
    return createClient({ token, sharding: { totalShards: "auto", sessions: fileSessionStore("sessions") } })
}

Variables#

supervisor#

Run a fixed group of local Node.js child processes, each with its own client and assigned shards

Use create to validate the assignments, then start to launch the children. Each child entry module must call supervisor.child.run to create and run its client

const supervisor: SupervisorTools

The start method waits for assignment and configuration acknowledgements, not gateway READY. Use waitForReady for all-child READY, and waitForClose to wait until this supervisor's children have exited. The status method returns a frozen local report with the latest gateway state received from each current child. Those states are separate observations, not an atomic health check across processes

Fresh gateway Identify sends require a parent permit and are spaced by at least one second, unless identify.coordinator paces them. Identify authenticates a new session, while Resume reuses an earlier gateway session. Session Resume sends do not need a permit. A permit stays outstanding until the child confirms the send or cancels before sending. A stalled child is stopped and must exit before another permit is issued, after a full spacing interval. The child helper receives a stop signal. A parent stop does not wait for an uncooperative configure promise or start its client afterward

The parent can forcibly terminate only children it started after the graceful deadline, and still waits for their exit. No process signal handlers are installed. Child output follows childOutput: Lines are forwarded with a child label by default, and inherit or ignore can be chosen instead. A crashed child restarts by default, up to three times in a row with exponentially increasing delays. Set restart to false to turn this off. The childEnvironment, args and execArgv options affect child launch but are omitted from status and failures. With totalShards "auto" and processes or shardsPerProcess, the plan is sized at start. Each child sends its client diagnostics, which status includes. Children keep resumable sessions through clientOptions.sharding.sessions. The children share Fluxer's limits per bot account through the parent. When one child is rate-limited globally, the parent holds the other children's REST requests until the same time. Member requests from all children share one count of 12 in any 11 seconds, and a members.iterateChunks request past it fails at once with reason rateLimit and retryAfterMs. A child that gets no answer from the parent within one second counts only its own member requests and logs supervisor.memberRequestsLocal once. Per-route REST rate limits stay per child, and other processes using the same token are not counted

import { supervisor } from "@neontechspace/fluxerly"

export const workers = supervisor.create({
    entry: "/srv/bot-worker.js",
    totalShards: 2,
    assignments: [
        { id: "one", shardIds: [0] },
        { id: "two", shardIds: [1] },
    ],
})
import { supervisor } from "@neontechspace/fluxerly"

export const workers = supervisor.create({
    entry: "/srv/bot-worker.js",
    totalShards: 2,
    assignments: [
        { id: "one", shardIds: [0] },
        { id: "two", shardIds: [1] },
    ],
})

Interfaces#

IdentifyCoordinator#

Coordinates Identify commands for shards that start new sessions, so several processes serving one bot can respect Fluxer's shared Identify budget

Creation copies the permit function, bound to its object, and later changes to the object have no effect. Clients that a local supervisor starts cannot set one, because the supervisor paces their Identify commands. Pass the coordinator to the supervisor option identify.coordinator instead, and the supervisor consults it for every child

interface IdentifyCoordinator

permit#

Resolve when the shard may send Identify now

The SDK calls this once per new-session attempt and sends Identify as soon as the promise resolves, without spacing of its own, so pace permits within Fluxer's budget of 300 Identify commands per source IP address in each 60-second window. Only one permit per client is outstanding at a time, so a slow permit delays this client's other shards. The wait counts against the startup deadline during startup and against the recovery attempt timeout during recovery. The signal aborts when the attempt ends first, for example on timeout or shutdown, so resolve or reject promptly then. A rejection or thrown error fails that connection attempt: The SDK logs the error in full at Error with code lifecycle.identifyPermitFailed and retries like a transient connection failure, so repeated rejection can end startup with a ConnectionError whose cause is the rejection

permit(
    shardId: number,
    totalShards: number,
    signal: AbortSignal
): Promise<void>permit(
  shardId: number,
  totalShards: number,
  signal: AbortSignal
): Promise<void>

Parameters

shardId

The local shard about to Identify

number
totalShards

The plan's total shard count, useful for a bucket key such as shardId modulo a concurrency

number
signal

Aborted when the SDK no longer needs this permit

AbortSignal
Returns
Promise<void>

SessionSnapshot#

The resumable state of one shard's gateway session, saved at shutdown and offered again at the next startup

It holds the session ID, which lets the bot's token resume the session, so store it as carefully as other secrets

interface SessionSnapshot
resumeUrl#

Gateway URL the session connected to

Fluxer publishes no separate resume URL, so this is the discovered gateway endpoint. A loaded snapshot is used only when it matches the endpoint the new client discovers

string
savedAt#

Wall-clock time the snapshot was taken, in Unix epoch milliseconds, after the session's socket closed

number
sequence#

Last dispatch sequence this client received on the session, a non-negative integer

number
sessionId#

Session ID from Fluxer's READY, or empty in the copy that marks a loaded snapshot as used

string
totalShards#

Total shard count of the plan the session identified with

A session belongs to that plan, so a loaded snapshot is used only when the new client's plan has the same total

number

SessionStore#

Persist resumable gateway sessions across restarts

Fluxer retains a disconnected session for 60,000 ms, so a process that restarts within that window can Resume and receive the dispatches it missed, subject to Fluxer's replay limits. Creation copies both functions, bound to their object. Resumable snapshots are saved only during shutdown, after each shard's socket has closed, never while a session is live and not after a permanent connection failure. Before resuming a loaded snapshot, the SDK replaces it with a used copy whose sessionId is empty, so a crash leaves no resumable snapshot and each snapshot is resumed at most once. A saved session closes with private-use code 4000 to preserve Resume. Without persistence, intentional final closure uses 1000, which destroys the session

interface SessionStore

load#

Return the snapshot saved for this shard, or undefined when none exists

The SDK calls this once per shard at the first connection attempt after discovery, and allows 5,000 ms, within the startup deadline. A snapshot older than 60,000 ms, saved more than 5,000 ms in the future, malformed, already marked as used, for a different gateway endpoint or for a plan with a different totalShards is ignored and logged at Warn with code lifecycle.sessionSnapshotIgnored. A rejection, thrown error or timeout is logged in full at Error with code lifecycle.sessionLoadFailed. Either way the shard starts a new session, so load problems never fail startup. If Fluxer no longer holds the session, Resume fails and the shard starts a new session as in any recovery. Partial replay can update caches before RESUMED. A fallback to Identify clears that shard's cached communities and dependent resources, then clears reads cached during the wait again at READY. A successful Resume retains the replay

load(shardId: number): Promise<SessionSnapshot | undefined>load(shardId: number): Promise<
  SessionSnapshot | undefined
>

Parameters

shardId

The local shard starting up

number
Returns
Promise<SessionSnapshot | undefined>

save#

Store a snapshot for this shard

The SDK calls this during shutdown for each shard that holds a resumable session, after its socket has closed and before shutdown completes, and allows each call 5,000 ms. Shutdown waits for these calls, then continues regardless of the outcome. At startup, after load returns a resumable snapshot, the SDK also calls this once with a copy whose sessionId is empty, with the same time limit as load. The shard resumes only after that call succeeds, and otherwise starts a new session. A rejection, thrown error or timeout is logged in full at Error with code lifecycle.sessionSaveFailed

save(shardId: number, snapshot: SessionSnapshot): Promise<void>save(
  shardId: number,
  snapshot: SessionSnapshot
): Promise<void>

Parameters

shardId

The local shard the snapshot belongs to

number
snapshot

The frozen resumable state, or at startup the used copy with an empty sessionId

SessionSnapshot
Returns
Promise<void>

ShardRecoveryDiagnostic#

Connection-attempt snapshot for one shard, a gateway connection owned by this client

Recovery means reconnecting after the shard has previously established a session. Endpoint, session credentials and provider failure details are excluded

interface ShardRecoveryDiagnostic
attempt#

One-based connection attempt number for this shard's managed run, counting startup and later recovery

During a retry delay, identifies the attempt that ended, not the next attempt

number
phase#

Whether this attempt belongs to initial startup or established-session recovery

"startup" | "recovery"
retryDelayMs#

Scheduled retry wait in milliseconds, or null while the current attempt is not waiting

This is not a remaining countdown

number | null

ShardState#

Frozen connection-state snapshot for one gateway shard owned by this client

Use client.shards to inspect local connections rather than the health of other processes or the whole bot. An explicit plan keeps its shards for the client's lifetime. A client without sharding options reports shard ID zero. An automatically sized client reports no shards until its first connect has chosen the plan. Both report the new plan's shards after they move to a larger plan

interface ShardState
gatewayLatencyMs#

Latest current-connection heartbeat round trip in milliseconds, or null when no measurement is current

number | null
recovery#

Current safe connection attempt or retry snapshot, or null when this shard is not attempting or waiting

ShardRecoveryDiagnostic | null
sessionEpoch#

Identifies this shard's current gateway session within the client

It is 0 until the shard's first new session and gets a new value, never used before by this client and larger than every earlier one, each time the shard starts a new session, including the shards of a larger plan after a move. A Resume, which replays every missed event, keeps it, and so does resuming a saved session after a restart, so a process that resumes a saved session reports 0 until that shard next starts a new session. A changed value means the events of that shard's communities between the two sessions may have been missed. Fluxer then sends each of those communities again as a guildCreate event, and a community that is unavailable sends guildDelete instead. This is the shard's current value, which can already be newer than the session of an event a handler is still processing, because events wait in each handler's queue. To tell which session an event belongs to, compare EventContext.sessionEpoch, which keeps the value from when the client accepted the event

number
shardId#

This client's local shard ID, retained in the configured local order

number
state#

Current connection status for this shard

ConnectionState

ShardingOptions#

Divide the bot's community events among gateway connections called shards

Set this when the bot needs more than one gateway connection or this client should own only part of a shared shard plan. One client can own several shards within one process. Separate processes use separate clients

interface ShardingOptions

Every process serving the same bot must use the same total and avoid overlapping ownership. Omit shardIds to own every ID from zero through totalShards minus one

Creation validates the plan and copies the supplied IDs in order without changing caller input. Invalid plans fail creation with ConfigurationError. An explicit plan cannot change during the client's lifetime. An automatic plan moves to a larger one while the client runs when Fluxer closes a shard with 4011 (sharding required), and so does the single shard of a client created without sharding settings

Shard zero receives direct-message gateway traffic. Include it when this client must receive direct messages. The SDK does not coordinate other processes unless identify supplies a coordinator

With totalShards set to 1, session startup sends no shard tuple in the gateway Identify command. Default-API and native clients accept the same plan. Native validation and copying happen when the creation Effect runs

identify optional#

Coordinate new-session Identify commands with other processes, for example through a shared lock service

The coordinator then owns pacing: The SDK waits for permit before each Identify and adds no spacing of its own. Resume never waits for it. See IdentifyCoordinator

IdentifyCoordinator
refillCaches optional#

Whether a shard that resumes a session loaded from sessions refills the enabled community, role and channel caches through REST, default true

Fluxer calls a community a guild. Resume replays missed dispatches but sends no fresh community snapshot, so without the refill those caches contain only observations from replay, later events and requests. Once every shard is ready, the SDK lists the bot's communities and fetches each one on a resumed shard, one request at a time, so application requests keep the other REST slots and every request respects rate limits. It logs lifecycle.cacheRefill when done, at Warn when communities failed or the refill stopped early. A community list page that does not move past the previous one stops the refill instead of paging forever. Set false to skip the refill, for example for a bot that reads no cache

boolean

Default

true
true

sessions optional#

Keep resumable sessions across process restarts, so a restart within Fluxer's 60-second resume window can Resume instead of starting new sessions

A fallback to a new session clears any partial restored replay from that shard's community caches and dependent resources. A successful Resume retains it. See SessionStore

SessionStore
shardIds optional#

Immutable non-empty local IDs, each unique integer from 0 through totalShards minus one

Omit to own every ID in ascending order. Automatic sizing requires omission

readonly number[]
totalShards#

Immutable total gateway shards for this bot, an integer from 1 through 16,384 shared by every process serving it

Fluxer closes a shard with 4011 (sharding required) when it serves more than 2,500 communities, and with an explicit total that closure ends the client with a ConnectionError. The value "auto" lets this client size the plan itself and own every shard, as the sharding value "auto" does, while keeping identify and sessions available

number | "auto"

Supervisor#

Parent that starts and stops child processes for one fixed set of local shards

Methods start their asynchronous work when called and return ResultAsync for expected failures. Unexpected defects reject with SdkDefect instead of returning Err, and a throwing waitForReady option or signal getter uses code application.defect with the thrown value as its cause. Creating this parent starts no child. Call shutdown to release its owned processes

interface Supervisor

shutdown#

Ask owned children to stop and return Ok only after their processes exit

After shutdownTimeoutMs, force-terminate an owned child that has not exited, then keep waiting for its exit. Concurrent and repeated calls share cleanup. Shutdown before start closes the parent without launching children. Returns Ok even after a supervisor failure or a child's message-channel loss. It does not erase waitForClose's retained failure

shutdown(): ResultAsync<void, never>
Returns
ResultAsync<void, never>

start#

Start the configured children and return Ok when each child accepts its shard assignment and finishes configure

This is setup completion, not gateway readiness. Use waitForReady to observe connected gateway sessions. Concurrent calls share startup. Calling again does not create extra children or await replacement startup. Failure returns SupervisorError only after owned processes exit. Start during or after shutdown returns reason closed. With totalShards "auto" it first counts the bot's communities, and a failed count returns reason shardCount. If a child remains alive after losing its message channel for shutdownTimeoutMs, pending startup fails with closed after cleanup

start(): ResultAsync<void, SupervisorError>start(): ResultAsync<
  void, SupervisorError
>
Returns
ResultAsync<void, SupervisorError>
Fails with

status#

Return one immutable safe local status snapshot without child output, environment, arguments or paths

status(): SupervisorStatus

waitForClose#

Wait until the supervisor's lifetime ends and its owned child processes have exited

Returns Ok after normal shutdown or Err with the retained SupervisorError after failure, even on a later call. Does not start or stop the supervisor. Calling before start waits until a later shutdown or failure

waitForClose(): ResultAsync<void, SupervisorError>waitForClose(): ResultAsync<
  void, SupervisorError
>
Returns
ResultAsync<void, SupervisorError>
Fails with

waitForReady#

Return Ok when every current child has reported its aggregate gateway state as Connected

Start the supervisor first. This observes reports, not simultaneous cross-process health or lasting readiness. Losing a child's message channel clears its readiness immediately. A later call waits for current readiness again. A signal returns CancelledError only for this wait and never stops or restarts a child. An already-aborted signal takes precedence even when the children are ready. A malformed signal returns ConfigurationError with field signal without starting observation. Unknown option keys return ConfigurationError before observation, with a suggested name when one is close. An idle, stopping or closed supervisor returns SupervisorError with reason closed. A failed supervisor returns its retained failure

waitForReady(options?: SupervisorWaitOptions): ResultAsync<
    void,
    ConfigurationError | SupervisorError | CancelledError
>waitForReady(
  options?: SupervisorWaitOptions
): ResultAsync<
  void,
  | ConfigurationError
  | SupervisorError
  | CancelledError
>

Parameters

options optional
SupervisorWaitOptions
Returns
ResultAsync<
    void,
    ConfigurationError | SupervisorError | CancelledError
>ResultAsync<
  void,
  | ConfigurationError
  | SupervisorError | CancelledError
>

SupervisorAssignment#

Gateway connections assigned to one child process by its parent supervisor

A shard is one gateway connection responsible for a portion of the bot's community events. The helper copies and freezes this assignment before creating the child client

interface SupervisorAssignment
shardIds#

Fixed shard IDs owned by this child, in configured order

Shards outside this list are not owned by this child

readonly number[]
totalShards#

Immutable total shard count used by this supervisor

number

SupervisorAssignmentOptions#

Name and shard IDs for one Node process that the supervisor starts and stops

Unknown option keys fail with ConfigurationError, with a suggested name when one is close

interface SupervisorAssignmentOptions
id#

Unique nonblank local identifier, at most 128 characters, shown in lifecycle failures and status snapshots

string
shardIds#

One or more unique shard IDs from zero through totalShards minus one

readonly number[]

SupervisorChildContext#

Client and fixed shard assignment available to configure before the helper starts the gateway connection

interface SupervisorChildContext
assignment#

Fixed assignment for this child process

It cannot be changed during this run

SupervisorAssignment
client#

Client created and owned by child.run

Register application behavior here rather than starting or stopping this client

Client
signal#

Signal aborted when the parent requests shutdown or its message channel disconnects

Setup work should check this signal and stop when it is aborted. The helper cannot forcibly cancel a JavaScript promise

AbortSignal

SupervisorChildDiagnostics#

One diagnostics snapshot a child sent to its parent: Gateway latency and shard states, REST queue use, cache use and running counters, as its client's diagnostics method returns them

interface SupervisorChildDiagnostics
client#

The child client's diagnostics at the time it sent them

See ClientDiagnostics

ClientDiagnostics
receivedAt#

Parent wall-clock time the snapshot arrived, in Unix epoch milliseconds

An old value means the child stopped reporting

number

SupervisorChildOptions#

Bot credentials, client settings and setup callback for a JavaScript module launched by a supervisor

Unknown option keys fail with ConfigurationError before waiting for the parent, with a suggested name when one is close

interface SupervisorChildOptions
clientOptions optional#

Every client setting except token is read by property name and copied before configure, including inherited and non-enumerable properties

The supervisor assigns the shards, so sharding accepts only sessions. Runtime validation rejects a token, a shard plan or identify coordinator in sharding, and any other own key that is not a client option, with ConfigurationError

& Omit<ClientOptions<undefined>, "token" | "sharding">
& { readonly sharding?: SupervisorChildSharding }& Omit<
    ClientOptions<undefined>,
    "token" | "sharding"
  >
& {
    readonly sharding?:
      SupervisorChildSharding
  }
configure#

Register subscriptions and local application behavior before the helper calls client.run

Return when setup is finished, not when the bot stops. Do not call client.run, connect or shutdown here. A thrown error, rejected promise or returned Err rejects child.run with SdkDefect code application.defect, whose cause is an ApplicationError with source "supervisor child configure" and the original value as its cause. A parent stop can finish child.run without waiting for this promise. Setup must check context.signal to avoid continuing afterward

(context: SupervisorChildContext) => unknown(context: SupervisorChildContext)
  => unknown
token#

Bot token for the client created by child.run, such as process.env.FLUXER_BOT_TOKEN

The parent assignment does not supply this credential. A missing or blank value fails child.run with ConfigurationError once the assignment arrives, as createClient does, and the parent sees the child fail during configuration

string | undefined

SupervisorChildSharding#

Sharding settings a supervised child may add to the shards its parent assigns

interface SupervisorChildSharding
sessions optional#

Keep this child's resumable sessions across process restarts, as the client option sharding.sessions does

A deploy that stops the supervisor and starts it again within Fluxer's 60-second resume window then resumes each shard instead of starting a new session. Resumable snapshots are saved only when the child shuts down normally, so a restart after a crash starts new sessions. The child saves while it shuts down, so saves must finish within the supervisor option shutdownTimeoutMs, after which the parent force-terminates the child. See SessionStore

SessionStore

SupervisorChildStatus#

Frozen snapshot of one child assignment and its current process, without launch settings or child output

interface SupervisorChildStatus
assignment#

Immutable assignment retained by this supervisor

SupervisorAssignment
connectionState#

Last aggregate gateway connection state reported by the current child process after configuration

Null before its first accepted report, after exit or when IPC is unavailable. Reports from different children are not simultaneous

ConnectionState | null
diagnostics#

Latest client diagnostics the current child process sent, or null before its first snapshot, after exit or when IPC is unavailable

A running child sends one when it finishes configuration and then every diagnosticsIntervalMs

SupervisorChildDiagnostics | null
generation#

Fork attempts for this assignment, starting at zero before startup and incrementing even if a fork fails

number
id#

Stable child identifier from the original assignment

string
pid#

Current owned child process ID, or null before a process starts or after verified exit

number | null
restarts#

Replacement attempts used from this child's current budget, including a replacement waiting for its delay

A restart that follows a healthy run of healthyResetMs counts from one again

number
state#

Current local lifecycle state

SupervisorChildState

SupervisorFileUrl#

File URL identifying the JavaScript module to run in each child process

A Node URL object satisfies this interface without requiring DOM types in default-API TypeScript consumers

interface SupervisorFileUrl
href#

Complete file URL string

string
protocol#

URL protocol, which must be file:

string

SupervisorIdentifyOptions#

Space out new gateway session starts across the children owned by one supervisor

A new gateway Identify command starts a session. Resuming an existing session does not use this spacing. The parent waits for a child to confirm its send before granting the next permit. Without a coordinator this does not coordinate another supervisor or an application-owned client. Unknown option keys fail with ConfigurationError, with a suggested name when one is close

interface SupervisorIdentifyOptions
coordinator optional#

Share Fluxer's Identify budget with other supervisors and clients, for example across several hosts, through the same IdentifyCoordinator a client accepts in sharding.identify

Before each grant the parent calls permit with the child's shard ID, the supervisor's total shard count and a signal, and grants the child only after the promise resolves. The coordinator then owns pacing, so the parent adds no spacing of its own. The signal aborts when the child no longer needs the permit, for example when its connection attempt times out, it exits or the supervisor stops. A rejection or thrown error is logged in full at Error with code supervisor.identifyPermitFailed, and the child retries its connection attempt as after a network failure. Creation copies the permit function, bound to its object

IdentifyCoordinator
minimumSpacingMs optional#

Minimum interval between child-confirmed fresh Identify sends in milliseconds, an integer from 1,000 through 2,147,483,647

Cannot be combined with coordinator

number

Default

1000
1000

SupervisorOptions#

Plan for running bot gateway connections in separate local Node processes

The supervisor is a parent process that starts, monitors and stops its child processes. Use it when separate processes are needed. A client can own multiple shards without a supervisor. Each child module must call supervisor.child.run from its chosen public entry point. Creation validates and copies the launch settings without starting a process. Default-API creation runs immediately. Native creation copies settings when its Effect runs

interface SupervisorOptions

Choose the child processes with exactly one of assignments, processes or shardsPerProcess. With processes or shardsPerProcess the supervisor splits the shards into contiguous blocks of almost equal size, one block per child, and names the children process-0, process-1 and so on. With totalShards set to "auto" the supervisor sizes the plan at start as a client with sharding "auto" does, from the number of communities the bot is in. Communities are what the API calls guilds. Assignments stay fixed across replacements. Without an identify coordinator, this supervisor does not coordinate other parents. Its children share a global rate-limit pause and the count of member requests through it, while per-route REST rate limits stay per child

args optional#

Program arguments for every owned child, at most 64 strings of at most 4,096 characters each

readonly string[]

Default

[]
[]

assignments optional#

One to totalShards fixed child assignments, with unique IDs and no overlapping shard IDs

Unassigned shards remain application-owned. Cannot be combined with processes or shardsPerProcess

readonly SupervisorAssignmentOptions[]
childEnvironment optional#

Up to 64 explicit string environment overrides copied over the inherited environment at creation

Keys use ASCII letters, digits and underscores, starting with a letter or underscore. Values have at most 4,096 characters. The parent retains this launch snapshot, including any credentials supplied there, until owned children exit. Status and errors do not contain these settings

Readonly<Record<string, string>>
childOutput optional#

How child standard output and error reach this process

"inherit" | "prefix" | "ignore"

The default, prefix, forwards each child line through this process in the format of the stream it goes to. Default-API children log JSON with no color, unless FLUXERLY_LOG_FORMAT or FLUXERLY_LOG_COLOR is set in the child environment. An Effect API child sends its records to Effect's logger unless its logging.format option is set, so set that option to json to forward structured records. In pretty format each SDK record prints as a readable line and each line gets a label: [shard N] for a child owning one shard, otherwise [child id]. Other text keeps its content behind the label. In json format the output stays valid JSON Lines: A child's SDK record gains a fields.child entry, another JSON object passes through unchanged, and other text becomes a supervisor.childOutput record. Each stream decides on its own, so with a terminal on standard output and standard error redirected to a file, standard output shows readable lines and the file receives the child's records with their level, code and fields. Lines longer than 262,144 characters are truncated with a marker, and child output pauses while this process's output applies backpressure. Exit handling waits up to one second after a child exits for its output to drain. A failed read of a child stream logs supervisor.outputFailed at Warn and stops forwarding that stream

The value inherit shares this process's streams without labels, and ignore discards child output

Default

"prefix"
"prefix"

diagnosticsIntervalMs optional#

How often each running child sends its client diagnostics to the parent, in milliseconds, an integer from 1,000 through 2,147,483,647

A child also sends one snapshot as soon as it finishes configuration. See SupervisorChildStatus

number

Default

5000
5000

entry#

Absolute module path string or file-URL object passed to every Node child-process fork

A file-URL string is not accepted

string | SupervisorFileUrl
execArgv optional#

Node executable arguments for every owned child

Omit to copy the parent's process.execArgv. At most 64 strings of at most 4,096 characters each. The SDK's development-only fluxerly-source condition is removed

readonly string[]
identify optional#

Parent-side fresh-Identify pacing shared by these children, or a coordinator shared with other processes

SupervisorIdentifyOptions
instance optional#

Fluxer instance for the community count when totalShards is "auto", as the client option instance

Rejected otherwise

InstanceOptions
logging optional#

Records for the automatic plan, child spawn, exit with code and signal, crash, restart and refused Identify permits, in the supervisor log category

A missed startup deadline, a forced termination and an unconfirmed Identify grant are each logged before the supervisor acts on them. Accepts the same settings as client logging. Default output prints these records at Info and higher. The native supervisor sends them to the Effect logger of the context that creates it unless a sink or format is set

LoggingOptions
processes optional#

Number of child processes that share every shard, an integer from 1 through 16,384

With a numeric totalShards it can be at most totalShards. With "auto", a plan with fewer shards than processes starts one process per shard

number
restart optional#

Replacement policy for unexpected local child exits

Omit it to restart with the defaults of SupervisorRestartOptions, or set false so that one unexpected exit stops the whole supervisor

false | SupervisorRestartOptions
shardsPerProcess optional#

Shards per child process, an integer from 1 through 16,384

The last process owns the remainder when the total does not divide evenly

number
shutdownTimeoutMs optional#

Time allowed for an owned child to exit after a stop request, in milliseconds, before the parent force-terminates it

A positive safe integer no greater than 2,147,483,647. Shutdown still awaits the process exit, which can take longer. A stopping child first lets running handlers and REST requests finish for up to this time minus one second, as the client shutdown option drainMs does, and keeps that second to close its connections. IPC is Node's parent-child message channel. If a current child loses IPC, it has this long to exit naturally. If that window expires, the supervisor fails with closed and force-terminates that child without a second grace period. Other owned children receive their normal stop request and grace period

number

Default

5000
5000

startupTimeoutMs optional#

Time allowed for each child to receive its assignment and finish configure, in milliseconds, including replacement children

This does not wait for the gateway READY event that establishes a connected session. With totalShards "auto" the community count before the first child starts has its own deadline of the same length. A positive safe integer no greater than 2,147,483,647. Timeout fails the supervisor, which stops its children and awaits their exit

number

Default

30000
30000

token optional#

Bot token used only to count the bot's communities when totalShards is "auto", such as process.env.FLUXER_BOT_TOKEN

Children still receive their own token through supervisor.child.run. Required with "auto" and rejected otherwise

string
totalShards#

Total gateway shard count for this bot, an integer from 1 through 16,384

Other processes serving it must use the same total. The value "auto" counts the bot's communities once, at start, by paging GET /users/@me/guilds within startupTimeoutMs, and uses one shard per 2,000 communities, from 1 through 16,384 shards. The count needs the token option, and it works only with processes or shardsPerProcess, because fixed assignments need a known total. A failed count fails start with SupervisorError reason shardCount, whose cause is the AuthenticationError, RateLimitError, ConnectionTimeoutError or ConnectionError of the count. Until the count completes, status lists no children. Restarts keep the plan. When Fluxer closes a child's shard with 4011 (sharding required) because the bot outgrew the plan, the supervisor stops every child, counts again and starts children for a larger plan, as a client with sharding "auto" does, logging a supervisor.resharded Warn record. Events sent during the move are missed. After 3 moves within an hour, or at 16,384 shards, a further 4011 fails the supervisor with reason closed instead

number | "auto"
transport optional#

HTTP implementation and User-Agent for the community count when totalShards is "auto", as the client option transport

Rejected otherwise

TransportOptions

SupervisorRestartOptions#

Restart a child process after it exits, unless the supervisor has begun shutdown or failed

Restart is on by default with the defaults below. The supervisor option restart set to false turns it off. Each child has its own budget of consecutive restarts. A child that ran for healthyResetMs after finishing configuration gets its full budget and the first delay back at its next exit, so only a crash loop exhausts the budget. Delays double after each replacement, up to maxDelayMs. Replacement starts only after the previous process exits. This starts a new process. It does not reconnect the client's gateway or recover its session

interface SupervisorRestartOptions
healthyResetMs optional#

Milliseconds a child must run after finishing configuration for its next exit to start a fresh restart budget, a positive safe integer no greater than 2,147,483,647

The supervisor.restart record then has fields.budgetReset true

number

Default

60000
60000

maxAttempts optional#

Maximum replacement attempts per child, an integer from 0 through 100

Zero permits no replacement

number

Default

3
3

maxDelayMs optional#

Maximum exponential replacement delay in milliseconds, a positive safe integer no greater than 2,147,483,647

number

Default

30000
30000

minDelayMs optional#

First replacement delay in milliseconds, a positive safe integer no greater than maxDelayMs

number

Default

1000
1000

SupervisorStatus#

Immutable safe local snapshot without child paths, arguments, environment or stdio

interface SupervisorStatus
children#

One snapshot per child assignment, in assignment order, including children with no current process

Empty with totalShards "auto" until start has counted the plan

readonly SupervisorChildStatus[]
state#

Current supervisor lifecycle state

SupervisorState

SupervisorTools#

Create a local parent supervisor or run its child module using the default API

interface SupervisorTools
child#

Child-module helper

Call run inside the module selected by the parent's entry option

{
    run(options: SupervisorChildOptions): ResultAsync<
        void,
        | ConfigurationError | SupervisorChildError | CancelledError
        | ConnectError
    >
}{
  run(
    options: SupervisorChildOptions
  ): ResultAsync<
    void,
    | ConfigurationError
    | SupervisorChildError
    | CancelledError | ConnectError
  >
}

create#

Validate and copy options now and return an idle supervisor

Invalid options throw ConfigurationError. Unknown keys in parent, assignment, restart and Identify options include a suggested name when one is close. Each option is read once. A throwing option getter throws SdkDefect with code application.defect and the thrown value as its cause, while another unexpected fault uses sdk.defect. Does not start a process or check whether the entry module can execute. Launch failures are reported by start

create(options: SupervisorOptions): Supervisorcreate(
  options: SupervisorOptions
): Supervisor

Parameters

Returns
Supervisor

SupervisorWaitOptions#

Cancel one default-API waitForReady call without stopping or restarting the supervisor

Unknown option keys return ConfigurationError before observation, with a suggested name when one is close

interface SupervisorWaitOptions
signal optional#

Cancels only this wait

An already-aborted signal cancels without starting, stopping or restarting any child

OperationSignal

Type Aliases#

SupervisorChildState#

Local process state for a fixed child assignment, not its gateway connection state

Running means the child finished configuration. Restarting means a replacement delay is pending

type SupervisorChildState =
    | "idle" | "starting" | "running" | "restarting" | "stopping"
    | "closed" | "failed"type SupervisorChildState =
    | "idle" | "starting"
    | "running" | "restarting"
    | "stopping" | "closed"
    | "failed"

SupervisorState#

Local parent-process lifetime state, not the bot's gateway readiness

Running means the children acknowledged their assignment and configuration. Failed can still include live children while cleanup waits for their exit

type SupervisorState =
    | "idle" | "starting" | "running" | "stopping" | "closed"
    | "failed"type SupervisorState =
    | "idle" | "starting"
    | "running" | "stopping"
    | "closed" | "failed"