README.md

fibers(1) -- Fiber support for v8 and Node

INSTALLING

via npm

npm install fibers

You're done!

from source

git clone git://github.com/laverdet/node-fibers.git

cd node-fibers

npm install

Note: node-fibers uses node-gyp for
building. To manually invoke the build process, you can use node-gyp rebuild.
This will put the compiled extension in build/Release/fibers.node. However,
when you do require('fibers'), it will expect the module to be in, for
example, bin/linux-x64-v8-3.11/fibers.node. You can manually put the module
here every time you build, or you can use the included build script. Either
npm install or node build -f will do this for you. If you are going to be
hacking on node-fibers, it may be worthwhile to first do node-gyp configure
and then for subsequent rebuilds you can just do node-gyp build which will
be faster than a full npm install or node-gyp rebuild.

important!

It's recommended that you use node 0.6.18 or higher with node-fibers. Using
other versions may lead to instability during high loads.

using windows 8?

Windows 8 is a beta operating system and you may have issues with fibers. To use
fibers in Windows 8 you may need to run node.exe in Windows 7 compatibility
mode. Once Windows 8 is released this issue will be revisited. See gh-70 for
more information.

other notes

Unlike most NodeJS projects, node-fibers is a C++ project. Some extra work is
required to compile node-fibers, but pretty much every platform is supported
in some way. Binary distributions in 32 and 64-bit forms are provided in npm for
Linux, OS X, and Windows (special thanks to
Jeroen Janssen for his work on fibers in Windows).

Support for Solaris, FreeBSD, and OpenBSD is provided by compiling the extension
on your system during install time via
node-gyp. If your operating system
isn't listed here you may have luck copying the build process for one of the
other OS's, assuming you are running a POSIX-like OS.

node 0.6.x is required to run this release of node-fibers. Older versions of
node (0.4.x) are supported in older releases of node-fibers. See the 0.5.x
branch of node-fibers for documentation.

EXAMPLES

The examples below describe basic use of Fiber, but note that it is not
recommended to use Fiber without an abstraction in between your code and
fibers. See "FUTURES" below for additional information.

Sleep

This is a quick example of how you can write sleep() with fibers. Note that
while the sleep() call is blocking inside the fiber, node is able to handle
other events.

Incremental Generator

Yielding execution will resume back in the fiber right where you left off. You
can also pass values back and forth through yield() and run(). Again, the node
event loop is never blocked while this script is running.

Fibonacci Generator

Expanding on the incremental generator above, we can create a generator which
returns a new Fibonacci number with each invocation. You can compare this with
the ECMAScript Harmony
Generator Fibonacci
example.

FUTURES

Using the Fiber class without an abstraction in between your code and the raw
API is not recommended. Fiber is meant to implement the smallest amount of
functionality in order make possible many different programming patterns. This
makes the Fiber class relatively lousy to work with directly, but extremely
powerful when coupled with a decent abstraction. There is no right answer for
which abstraction is right for you and your project. Included with node-fibers
is an implementation of "futures" which is fiber-aware. Usage of this library
is documented below. There are several other externally-maintained options
which can be found on the wiki.
You should feel encouraged to be creative with fibers and build a solution
which works well with your project. For instance, Future is not a good
abstraction to use if you want to build a generator function (see Fibonacci
example above).

Using Future to wrap existing node functions. At no point is the node event
loop blocked:

API DOCUMENTATION

Fiber's definition looks something like this:

/** * 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().*/functionFiber(fn) {
[native code]
}
/** * `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;
/** * `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.*/Fiber.yield=function(param) {
[native code]
}
/** * 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.*/Fiber.prototype.run=function(param) {
[native code]
}
/** * 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.*/Fiber.prototype.reset=function() {
[native code]
}
/** * 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.*/Fiber.prototype.throwInto=function(exception) {
[native code]
}

GARBAGE COLLECTION

If you intend to build generators, iterators, or "lazy lists", you should be
aware that all fibers must eventually unwind. This is implemented by causing
yield() to throw unconditionally when the library is trying to unwind your
fiber-- either because reset() was called, or all handles to the fiber were lost
and v8 wants to delete it.

Something like this will, at some point, cause an infinite loop in your
application:

If you either call reset() on this fiber, or the v8 garbage collector decides it
is no longer in use, the fiber library will attempt to unwind the fiber by
causing all calls to yield() to throw. However, if you catch these exceptions
and continue anyway, an infinite loop will occur.

There are other garbage collection issues that occur with misuse of fiber
handles. If you grab a handle to a fiber from within itself, you should make
sure that the fiber eventually unwinds. This application will leak memory:

There is no way to get back into the fiber that was started, however it's
impossible for v8's garbage collector to detect this. With a handle to the fiber
still outstanding, v8 will never garbage collect it and the stack will remain in
memory until the application exits.