ThreadsafeFn

Thread-safe wrapper around a JS function. T is the per-call payload type. Built via Callback.threadsafe(env, name, T).

const tsfn = try cb.threadsafe(env, "progress", u8);

For the conceptual model and lifecycle rules, see Threadsafe functions.

T semantics

T valueBehavior
voidNo payload. JS callback is invoked with no arguments.
Any convertibleEach call sends a T. The bridge converts to JS via type conversion.

Methods

MethodReturnsPurpose
call(value, mode)!voidQueue a call from any thread. mode is .blocking/.non_blocking.
release()!voidRelease this thread's reference.
abort()!voidRelease and reject pending calls.
acquire()!voidRegister an additional thread.
ref(env)!voidKeep the event loop alive while this exists (default).
unref(env)!voidAllow the event loop to exit even if this exists.

call(value, mode)

try tsfn.call(42, .non_blocking);

mode is napi.ThreadsafeFn(T).Mode:

  • .blocking waits if the queue is full.
  • .non_blocking returns error.QueueFull if the queue is full.

For T = void, the call signature is try tsfn.call({}, mode).

call deep-copies slice-backed data in supported structural payloads before enqueueing. Conversion failures and exceptions thrown by the JavaScript callback are forwarded exactly once through Node.js's uncaughtException path.

Lifecycle pattern

const tsfn = try cb.threadsafe(env, "events", u32);

// each new thread:
try tsfn.acquire();
defer tsfn.release() catch {};

// when emitting:
try tsfn.call(value, .non_blocking);

// the original thread must release once at the end (it holds the
// initial refcount):
try tsfn.release();