or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

fiber-core.mdfuture.mdindex.md
tile.json

fiber-core.mddocs/

Core Fiber Operations

Low-level fiber creation, execution control, and cooperative yielding functionality. These primitives enable building custom async abstractions and implementing synchronous-style APIs over asynchronous operations.

Capabilities

Fiber Constructor

Creates a new fiber that executes the given function when run.

/**
 * Instantiate a new Fiber. You may invoke this either as a function or as
 * a constructor; the behavior is the same.
 *
 * When run() is called on this fiber for the first time, `fn` will be
 * invoked as the first frame on a new stack. Execution will continue on
 * this new stack until `fn` returns, or Fiber.yield() is called.
 *
 * After the function returns the fiber is reset to original state and
 * may be restarted with another call to run().
 * 
 * @param {Function} fn - Function to execute in the fiber
 * @returns {Fiber} New fiber instance
 */
function Fiber(fn) { /* [native code] */ }

Usage Examples:

var Fiber = require('fibers');

// Create and run a simple fiber
var fiber = Fiber(function() {
  console.log('Inside fiber');
  Fiber.yield('yielded value');
  console.log('Resumed fiber');
  return 'final value';
});

var result1 = fiber.run(); // Logs: "Inside fiber", returns: "yielded value"
var result2 = fiber.run(); // Logs: "Resumed fiber", returns: "final value"

Current Fiber Reference

Static property containing the currently-running fiber.

/**
 * `Fiber.current` will contain the currently-running Fiber. It will be
 * `undefined` if there is no fiber (i.e. the main stack of execution).
 *
 * See "Garbage Collection" for more information on responsible use of
 * `Fiber.current`.
 */
Fiber.current = undefined;

Usage Examples:

function getCurrentFiber() {
  if (Fiber.current) {
    console.log('Running in fiber');
    return Fiber.current;
  } else {
    console.log('Running on main stack');
    return null;
  }
}

Fiber(function() {
  var current = getCurrentFiber(); // Returns the current fiber
}).run();

getCurrentFiber(); // Returns null

Fiber Yielding

Halts execution of the current fiber and returns control back to the caller.

/**
 * `Fiber.yield()` will halt execution of the current fiber and return control
 * back to original caller of run(). If an argument is supplied to yield(),
 * run() will return that value.
 *
 * When run() is called again, yield() will return.
 *
 * Note that this function is a global to allow for correct garbage
 * collection. This results in no loss of functionality because it is only
 * valid to yield from the currently running fiber anyway.
 *
 * Note also that `yield` is a reserved word in Javascript. This is normally
 * not an issue, however some code linters may complain. Rest assured that it
 * will run fine now and in future versions of Javascript.
 * 
 * @param {*} param - Optional value to return to caller
 * @returns {*} Value passed to next run() call
 */
Fiber.yield = function(param) { /* [native code] */ }

Usage Examples:

// Incremental generator example
var inc = Fiber(function(start) {
  var total = start;
  while (true) {
    total += Fiber.yield(total);
  }
});

for (var ii = inc.run(1); ii <= 10; ii = inc.run(1)) {
  console.log(ii); // Prints: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
}

Run Method

Starts or resumes fiber execution.

/**
 * run() will start execution of this Fiber, or if it is currently yielding,
 * it will resume execution. If an argument is supplied, this argument will
 * be passed to the fiber, either as the first parameter to the main
 * function [if the fiber has not been started] or as the return value of
 * yield() [if the fiber is currently yielding].
 *
 * This function will return either the parameter passed to yield(), or the
 * returned value from the fiber's main function.
 * 
 * @param {*} param - Optional parameter to pass to fiber
 * @returns {*} Value passed to yield() or fiber return value
 */
Fiber.prototype.run = function(param) { /* [native code] */ }

Reset Method

Terminates a running fiber and restores it to its original state.

/**
 * reset() will terminate a running Fiber and restore it to its original
 * state, as if it had returned execution.
 *
 * This is accomplished by causing yield() to throw an exception, and any
 * futher calls to yield() will also throw an exception. This continues
 * until the fiber has completely unwound and returns.
 *
 * If the fiber returns a value it will be returned by reset().
 *
 * If the fiber is not running, reset() will have no effect.
 * 
 * @returns {*} Return value from fiber if any
 */
Fiber.prototype.reset = function() { /* [native code] */ }

Usage Examples:

var fiber = Fiber(function() {
  try {
    while (true) {
      Fiber.yield('continuing');
    }
  } catch (e) {
    console.log('Fiber was reset');
    return 'cleaned up';
  }
});

fiber.run(); // Returns: 'continuing'
var result = fiber.reset(); // Logs: "Fiber was reset", returns: 'cleaned up'

Throw Into Method

Causes a yielding fiber's yield() call to throw instead of return.

/**
 * throwInto() will cause a currently yielding fiber's yield() call to
 * throw instead of return gracefully. This can be useful for notifying a
 * fiber that you are no longer interested in its task, and that it should
 * give up.
 *
 * Note that if the fiber does not handle the exception it will continue to
 * bubble up and throwInto() will throw the exception right back at you.
 * 
 * @param {Error} exception - Exception to throw in fiber
 */
Fiber.prototype.throwInto = function(exception) { /* [native code] */ }

Usage Examples:

var fiber = Fiber(function() {
  try {
    Fiber.yield('yielding');
    console.log('This will not execute');
  } catch (e) {
    console.log('Caught exception:', e.message);
    return 'handled error';
  }
});

fiber.run(); // Returns: 'yielding'
var result = fiber.throwInto(new Error('Stop processing'));
// Logs: "Caught exception: Stop processing", returns: 'handled error'

Error Handling

Fibers are exception-safe; exceptions will continue travelling through fiber boundaries:

var fn = Fiber(function() {
  console.log('async work here...');
  Fiber.yield();
  console.log('still working...');
  Fiber.yield();
  console.log('just a little bit more...');
  Fiber.yield();
  throw new Error('oh crap!');
});

try {
  while (true) {
    fn.run();
  }
} catch(e) {
  console.log('safely caught that error!');
  console.log(e.stack);
}

Garbage Collection Considerations

  • All fibers must eventually unwind to prevent memory leaks
  • Avoid grabbing references to Fiber.current without proper cleanup
  • Library will force unwinding by causing yield() to throw when necessary
  • Never catch and ignore exceptions thrown during fiber unwinding