Flow control and error handling for Node.js

Related tags

Control Flow zone
Overview

NOTE: This project is deprecated and no longer being actively developed or maintained. See Issue #50 for details.

StrongLoop zone library

Overview

The Zone library provides a way to represent the dynamic extent of asynchronous calls in Node. Just like the scope of a function defines where it may be used, the extent of a call represents the lifetime that is it active.

A Zone also provides execution context that can persist across the lifecycle of one or more asynchronous calls. This is similar to the concept of thread-local data in Java.

Zones provide a way to group and track resources and errors across asynchronous operations. In addition zones:

  • Enables more effective debugging by providing better stack traces for asynchronous functions
  • Makes it easier to write and understand asynchronous functions for Node applications
  • Makes it easier to handle errors raised asynchronously and avoid resulting resource leaks
  • Enables you to associate user data with asynchronous control flow

Dart's async library and Brian Ford's zone.js library provide similar functionality.

Implementation status

  • The zone library dynamically modifies Node's asynchronous APIs at runtime. As detailed below, some of the modules have not yet been completed, and thus you cannot use them with zones.

    The following modules have not been zone enabled:

    • cluster
    • crypto: pbkdf2, randomBytes, pseudoRandomBytes
    • fs: fs.watch, fs.watchFile, fs.FSWatcher
    • process object: process.on('SIGHUP') and other signals.
    • tls / https
    • udp
    • zlib

Using zones

To use zones, add the following as the very first line of your program:

require('zone').enable();

The zone library exports a global variable, zone. The zone global variable always refers to the currently active zone. Some methods that can always be found on the 'zone' object are actually static methods of the Zone class, so they don't do anything with the currently active zone.

After loading the zone library the program has entered the 'root' zone.

Creating a zone

There are a few different ways to create a zone. The canonical way to create a one-off zone is:

// Load the library
require('zone').enable();

// MyZone is the name of this zone which shows up in stack traces.
zone.create(function MyZone() {
  // At this point the 'zone' global points at the zone instance ("MyZone")
  // that we just created.
});

The zone constructor function is called synchronously.

Defining zone functions

Under some circumstances it may be desirable to create a function that is always wrapped within a zone. The obvious way to do this:

function renderTemplate(fileName, cb) {
  zone.create(function() {
    // Actual work here
    ...
  }).setCallback(cb);
}

To make this a little less verbose there is the 'zone.define()' API. With it you can wrap a function such that when it's called a zone is created. Example:

var renderTemplate = zone.define(function(fileName, cb) {
  zone.setCallback(cb);
  // Actual work here
  ...
});

Now you can use this zone template as follows:

renderTemplate('bar', function(err, result) {
  if (err)
    throw err;
  // Do something with the result
  ...
});

Obtaining the result of a zone

Zones are like asynchronous functions. From the outside perspective, they can return a single value or "throw" a single error. There are a couple of ways the outside zone may obtain the result of a zone. When a zone reports its outcome:

  • No more callbacks will run inside the zone.
  • All non-garbage-collectable resources have been cleaned up.

Zones also automatically exit when no explicit value is returned.

A way to obtain the outcome of a zone is:

require('zone').enable();
var net = require('net');

zone.create(function MyZone() {
  // This runs in the context of MyZone
  net.createConnection(...);
  fs.stat(...)

  if (Math.random() < 0.5)
    throw new Error('Chaos monkey!');
  else if (Math.random() < 0.5)
    zone.return('Chaos monkey in disguise!');
  else
    ; // Wait for the zone to auto-exit.

}).setCallback(function(err, result) {
  // Here we're back in the root zone.
  // Asynchronicity is guaranteed, even if the zone returns or throws immediately.
  // By the time we get here we are sure:
  //   * the connection has been closed one way or another
  //   * fs.stat has completed
});

You can also use the then and catch methods, as if it were a promise. Note that unlike promises you can't currently chain calls callbacks.

zone.create(function MyZone() {
  // Do whatever
}).then(function(result) {
  // Runs when succesful
}).catch(function(err) {
  // Handle error
});

Sharing resources between zones

Within a zone you may use resources that are "owned" by ancestor zones. So this is okay:

var server = http.createServer().listen(1234);
server.listen(1234);

zone.create(function ServerZone() {
  // Yes, allowed.
  server.on('connection', function(req, res) { ... });

  // Totally okay
  process.stdout.write('hello!');
});

However, using resources owned by child zones is not allowed:

var server;

zone.create(function SomeZone() {
 server = http.createServer().listen(1234);
});

// NOT OKAY!
server.on('connection', function() { ... });

NOTE: Currently zones don't always enforce these rules, but you're not supposed to do this. It would also be dumb, since the server will disappear when SomeZone() exits itself!

The rules of engagement

It is okay for a zone to temporarily enter an ancestor zone. It is not allowed to enter child zones, siblings, etc. The rationale behind this is that when a zone is alive its parent must also be alive. Other zones may exit unless they are aware that code will run inside them.

zone.create(function OuterZone() {
  var childZone = zone.create(function ChildZone() {
    ...
  });

  // Fine.
  zone.parent.run(function() {
    console.log('Hello from the root zone!');
  });

  // NOT ALLOWED
  childZone.run(function() {
    console.log('Weird. This isn't supposed to work!');
  });
});

Exiting a zone

There are a few ways to explicitly exit a zone:

  • zone.return(value) sets the return value of the zone and starts cleanup.
  • zone.throw(error) sets the zone to failed state and starts cleanup. zone.throw itself does not throw, so statements after it will run.
  • throw error uses normal exception handling. If the exception is not caught before it reaches the binding layer, the active zone is set to failed state and starts cleanup.
  • zone.complete(err, value) is a zone-bound function that may be passed to subordinates to let them exit the zone.

A rather pointless example:

zone.create(function StatZone() {
  fs.stat('/some/file', function(err, result) {
    if (err)
      throw err;
    else
      zone.return(result);
  });
});

This is equivalent to:

zone.create(function StatZone() {
  fs.stat('/some/file', zone.complete);
});

To run code in a child zone, you can use zone.bindCallback and zone.bindAsyncCallback to create a callback object which can be invoked from a parent zone.

Sharing resources between zones

Within a zone you may use resources that are "owned" by ancestor zones. So this is okay:

var server = http.createServer().listen(1234);
server.listen(1234);

zone.create(function ServerZone() {
  // Yes, allowed.
  server.on('connection', function(req, res) { ... });

  // Totally okay
  process.stdout.write('hello!');
});

However, using resources owned by child zones is not allowed:

var server;

zone.create(function SomeZone() {
 server = http.createServer().listen(1234);
});

// NOT OKAY!
server.on('connection', function() { ... });

NOTE: Currently zones don't always enforce these rules, but you're not supposed to do this. It would also be dumb, since the server will disappear when SomeZone() exits itself!

Zone.data

zone.data is a magical property that that associates arbitrary data with a zone. In a way you can think of it as the 'scope' of a zone. Properties that are not explicitly defined within the scope of a zone are inherited from the parent zone.

  • In the root zone, zone.data equals the global object.
  • In any other zone, zone.data starts off as an empty object with the parent zone's data property as it's prototype.
  • In other words, zone.data.__proto__ === zone.parent.data.
Comments
  • Error: No such module (contextify)

    Error: No such module (contextify)

    Hi,

    I'm trying to use the library but it fails the simplest test:

    $ npm install zone
    $ vim zone-test.js
    
    require('zone').enable();
    
    $ node zone-test.js
    
    /Users/davojan/projects/megaplan/front/node_modules/zone/lib/wrappers/binding.js:35
          return realBinding(name);
                 ^
    Error: No such module
        at process.binding (/Users/davojan/projects/megaplan/front/node_modules/zone/lib/wrappers/binding.js:35:14)
        at Object.<anonymous> (/Users/davojan/projects/megaplan/front/node_modules/zone/lib/wrappers/node-lib/native_module.js:25:32)
        at Module._compile (module.js:456:26)
        at Object.Module._extensions..js (module.js:474:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:312:12)
        at Module.require (module.js:364:17)
        at require (module.js:380:17)
        at Object.<anonymous> (/Users/davojan/projects/megaplan/front/node_modules/zone/lib/wrappers/require.js:2:20)
        at Module._compile (module.js:456:26)
    

    Adding console.log shown that it can't find module "contextify", but installing it manually didn't help.

    What am I doing wrong?

    opened by davojan 11
  • Clean up for CI

    Clean up for CI

    • [x] teach test runner how to output TAP when the TAP environment variable is set
    • [x] Remove broken benchmarks script from npm test chain

    This should allow the tests to run on Windows on CI, as well, by removing the bash dependency in posttest.

    opened by rmg 4
  • Replace Gate by something better

    Replace Gate by something better

    The semantics of gates are nonobvious. This has to change.

    What gates do is basically tell the active zone that some other zone is going to call a callback in the active zone later. This is necessary because otherwise a zone cannot determine whether it's appropriate to exit or not (remember that a zone exits when no more callbacks can be run inside it).

    Anyone feel free to tell me this still sucks, or suggest better alternatives. I'm looking a bit at you @ritch and @btford if you care.

    I'm thinking of something like:

    1

    // allow `otherZone` to make callbacks into `zone`.
    var source = zone.createEventSource(otherZone);
    // Inside `otherZone` we could now:
    source.run(function() { console.log('Hello from `zone`'); })
    // To make a source unusable (so `zone` knows that it can exit safely)
    source.end();
    

    2

    An alternative option would be to use this as the zone that will produce events, and set the currently active zone (the value of the zone global at construction time) as the zone that callbacks will run in.

    // Allow `otherZone` to make callbacks in the current zone.
    var source = otherZone.createEventSource();
    

    3

    In many scenarios a callback made by another zone is a one-off event. We could add a generic promise type whose callbacks run in one zone but resolution/rejection is done from another.

    // Create a promise which is to be resolved/rejected from `otherZone, but 
    // who'se callback runs in `zone` .
    var promise = zone.createPromise(otherZone);
    

    4

    Alternative, same semantics as with snippet #2

    var promise = otherZone.createPromise();
    
    opened by piscisaureus 4
  • sdocs: not found

    sdocs: not found

    I'm not sure whether this module is supposed to be installable using NPM, but trying so, I got the error sdocs: not found. I then tried installing sdocs using the git repo url in your package.json without much luck as the url does not exist (or is private). How can I play with this?

    opened by tjconcept 3
  • Fix EE issue

    Fix EE issue

    When listeners are explicitly removed with removeListener, the registration with the source zone isn't properly removed.

    @kraman This is a bug fix against the "old" implementation. The fast implementation has the same issue but I couldn't figure out how to port the fix - do you have any suggestions?

    opened by piscisaureus 2
  • error in curl demo

    error in curl demo

    I was intrigued by the post on strongloop's blog, so I tried the curl demo with

    ~$ node showcase/curl/curl-zone.js 
    

    Unfortunately, I get the following error:

    /private/tmp/zone/lib/binding.js:37
          return realBinding(name);
                 ^
    Error: No such module
        at process.binding (/private/tmp/zone/lib/binding.js:37:14)
        at Object.<anonymous> (/private/tmp/zone/lib/node-lib/native_module.js:25:32)
        at Module._compile (module.js:456:26)
        at Object.Module._extensions..js (module.js:474:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:312:12)
        at Module.require (module.js:364:17)
        at require (module.js:380:17)
        at Object.<anonymous> (/private/tmp/zone/lib/require.js:4:20)
        at Module._compile (module.js:456:26)
    

    Any idea on what I'm doing wrong?

    opened by danielepolencic 2
  • Uncomment events, depend on strongloop/node-tap

    Uncomment events, depend on strongloop/node-tap

    In this branch, npm test appears to pass, but it lies. Run NOPATCH=events npm test, and you will see lots of tests pass, run with the EE patches, and most of the tests only have a test count of 1, because they are just exiting abruptly with a status of 0 (tap thinks that's success).

    opened by sam-github 2
  • bindCallback and bindAsyncCallback should not require thisArg as the first argument

    bindCallback and bindAsyncCallback should not require thisArg as the first argument

    The main purpose of the bind*Callback class of functions is to wrap a function so it is called within a particular zone.

    I don't see any reason why the wrapper should change the value of this within the wrapped function, and it certainly shouldn't be the first argument which makes it mandatory to specify a value for this. We could support it in the options object if we really need it.

    @kraman Do you agree?

    opened by piscisaureus 1
  • Getting multiple errors

    Getting multiple errors

    Environment:

    • On Windows 8.1
    • On Node 0.10.30 with Express 4.x

    Install: npm install zone

    Code:

    require('zone').enable();
    
    zone.create(function Call() {
      ...
    }).complete(function(err, args){
      ...
    }).catch(function(err) {
      ...
    });
    

    I get following errors:

    error: Caught exception: Error: No such module
        at process.binding (node_modules\zone\lib\wrappers\binding.js:35:14)
        at Object.<anonymous> (node_modules\zone\lib\wrappers\node-lib\native_module.js:25:32)
        at Module._compile (module.js:456:26)
    

    It can't find Contextify modules (not in dependencies) so I install it but still get the error and other errors:

    error: Caught exception: AssertionError: "undefined" == true
        at new ZoneCallback (node_modules\zone\lib\ZoneCallback.js:12:3)
        at Zone.bindAsyncCallback (node_modules\zone\lib\Zone.js:808:18)
        at TCP.connect (node_modules\zone\lib\wrappers\binding\stream-wrap.js:174:40)
        at connect (net.js:758:31)
        at net.js:845:9
    

    What am I missing ?

    opened by JpEncausse 1
  • Update URLs in CONTRIBUTING.md

    Update URLs in CONTRIBUTING.md

    Refs strongloop-internal/scrum-nodeops#1592

    This commit was auto-generated and is not being tracked.

    If you are a maintainer for this repo, please merge or close this pull request and then delete the branch.

    opened by rmg 0
  • Broken link on video page for piscisaureus's talk

    Broken link on video page for piscisaureus's talk

    This is actually a bug in Strongloop's web site but I figured I'd just report it here.

    Page: http://strongloop.com/node-js/videos/#Zones-Next-Generation-Async-Flow-Control-for-Node.js-with-Bert-Belder

    Text: "Slides used in the video are here."

    Broken link: http://strongloop.github.io/baynode-2014-zones/

    Looks like Strongloop's github pages site isn't live at the moment.

    Would be cool to get the slides.

    opened by francispotter 0
  • Recommend the zone add option that disabled patch the readonly properties

    Recommend the zone add option that disabled patch the readonly properties

    I use the third-part js framework in angular, it is babylon, When I use it`s function to import the xml file through the XMLHttpRequest, I can not do anything callback with the response, because the zone patch the DONE attribute of the XMLHttpRequest that became a function.

    In the babylon.js,there is a condition, if the condition is true, it should callback the response, howeaver, it is false.

    The condition is below:

    if (request.readyState === (XMLHttpRequest.DONE || 4)) { // do success callback }

    I try to use '__Zone_ignore_on_properties' and '__Zone_disable_XHR' to config the zone donot patch the XMLHttpRequest module, howeaver it is not work in angular.

    I think the problem is the DONE attribute patch of zone in XMLHttpRequest is conflict with other framework. Other attributes is also, for example, LOADING, OPENED.

    Because these attribute are readonly, I can not reset the value.

    So I recommend the zone should disable patch for readonly properties in the next version.

    opened by jinxiu3939 0
  • NotYetImplemented errors on runing angular universal server

    NotYetImplemented errors on runing angular universal server

    I migrated my application to angular universal V6 which is using express for server-side. When I run my build the app and run it, I get this error !! I total do not know what`s going on! I tested app in prodoction mode but had no error !!

    ERROR { Error: Uncaught (in promise): Error: NotYetImplemented Error: NotYetImplemented at Document.exports.nyi (C:\Users\PC-01\Desktop\project_path\dist\server.js:213490:9) at CookieService.check (C:\Users\PC-01\Desktop\project_path\dist\server.js:279517:48) at CookieService.get (C:\Users\PC-01\Desktop\project_path\dist\server.js:279525:47) at new DateFormatterByTimezonePipe (C:\Users\PC-01\Desktop\project_path\dist\server.js:161863:53) at createClass (C:\Users\PC-01\Desktop\project_path\dist\server.js:12945:20) at createPipeInstance (C:\Users\PC-01\Desktop\project_path\dist\server.js:12824:12) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14043:32) at callViewAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14366:13) at execComponentViewsAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14285:13) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14078:5) at createRootView (C:\Users\PC-01\Desktop\project_path\dist\server.js:13964:5) at Object.createProdRootView [as createRootView] (C:\Users\PC-01\Desktop\project_path\dist\server.js:14476:12) at ComponentFactory_.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:12310:29) at ComponentFactoryBoundToModule.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:7129:29) at ViewContainerRef_.createComponent (C:\Users\PC-01\Desktop\project_path\dist\server.js:12420:45) at RouterOutlet.activateWith (C:\Users\PC-01\Desktop\project_path\dist\server.js:239338:40) at ActivateRoutes.activateRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238683:40) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238635:19 at Array.forEach (<anonymous>) at ActivateRoutes.activateChildRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238634:29) at ActivateRoutes.activate (C:\Users\PC-01\Desktop\project_path\dist\server.js:238559:14) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238498:18 at resolvePromise (C:\Users\PC-01\Desktop\project_path\dist\server.js:1025:31) at resolvePromise (C:\Users\PC-01\Desktop\project_path\dist\server.js:982:17) at C:\Users\PC-01\Desktop\project_path\dist\server.js:1084:17 at ZoneDelegate.invokeTask (C:\Users\PC-01\Desktop\project_path\dist\server.js:632:31) at Object.onInvokeTask (C:\Users\PC-01\Desktop\project_path\dist\server.js:7611:33) at ZoneDelegate.invokeTask (C:\Users\PC-01\Desktop\project_path\dist\server.js:631:36) at Zone.runTask (C:\Users\PC-01\Desktop\project_path\dist\server.js:399:47) at drainMicroTaskQueue (C:\Users\PC-01\Desktop\project_path\dist\server.js:806:35) at ZoneTask.invokeTask (C:\Users\PC-01\Desktop\project_path\dist\server.js:711:21) at Server.ZoneTask.invoke (C:\Users\PC-01\Desktop\project_path\dist\server.js:696:48) at emitTwo (events.js:126:13) at Server.emit (events.js:214:7) at parserOnIncoming (_http_server.js:619:12) at HTTPParser.parserOnHeadersComplete (_http_common.js:115:23) rejection: Error: NotYetImplemented at Document.exports.nyi (C:\Users\PC-01\Desktop\project_path\dist\server.js:213490:9) at CookieService.check (C:\Users\PC-01\Desktop\project_path\dist\server.js:279517:48) at CookieService.get (C:\Users\PC-01\Desktop\project_path\dist\server.js:279525:47) at new DateFormatterByTimezonePipe (C:\Users\PC-01\Desktop\project_path\dist\server.js:161863:53) at createClass (C:\Users\PC-01\Desktop\project_path\dist\server.js:12945:20) at createPipeInstance (C:\Users\PC-01\Desktop\project_path\dist\server.js:12824:12) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14043:32) at callViewAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14366:13) at execComponentViewsAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14285:13) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14078:5) at createRootView (C:\Users\PC-01\Desktop\project_path\dist\server.js:13964:5) at Object.createProdRootView [as createRootView] (C:\Users\PC-01\Desktop\project_path\dist\server.js:14476:12) at ComponentFactory_.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:12310:29) at ComponentFactoryBoundToModule.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:7129:29) at ViewContainerRef_.createComponent (C:\Users\PC-01\Desktop\project_path\dist\server.js:12420:45) at RouterOutlet.activateWith (C:\Users\PC-01\Desktop\project_path\dist\server.js:239338:40) at ActivateRoutes.activateRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238683:40) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238635:19 at Array.forEach (<anonymous>) at ActivateRoutes.activateChildRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238634:29) at ActivateRoutes.activate (C:\Users\PC-01\Desktop\project_path\dist\server.js:238559:14) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238498:18, promise: ZoneAwarePromise { __zone_symbol__state: 0, __zone_symbol__value: Error: NotYetImplemented at Document.exports.nyi (C:\Users\PC-01\Desktop\project_path\dist\server.js:213490:9) at CookieService.check (C:\Users\PC-01\Desktop\project_path\dist\server.js:279517:48) at CookieService.get (C:\Users\PC-01\Desktop\project_path\dist\server.js:279525:47) at new DateFormatterByTimezonePipe (C:\Users\PC-01\Desktop\project_path\dist\server.js:161863:53) at createClass (C:\Users\PC-01\Desktop\project_path\dist\server.js:12945:20) at createPipeInstance (C:\Users\PC-01\Desktop\project_path\dist\server.js:12824:12) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14043:32) at callViewAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14366:13) at execComponentViewsAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14285:13) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14078:5) at createRootView (C:\Users\PC-01\Desktop\project_path\dist\server.js:13964:5) at Object.createProdRootView [as createRootView] (C:\Users\PC-01\Desktop\project_path\dist\server.js:14476:12) at ComponentFactory_.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:12310:29) at ComponentFactoryBoundToModule.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:7129:29) at ViewContainerRef_.createComponent (C:\Users\PC-01\Desktop\project_path\dist\server.js:12420:45) at RouterOutlet.activateWith (C:\Users\PC-01\Desktop\project_path\dist\server.js:239338:40) at ActivateRoutes.activateRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238683:40) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238635:19 at Array.forEach (<anonymous>) at ActivateRoutes.activateChildRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238634:29) at ActivateRoutes.activate (C:\Users\PC-01\Desktop\project_path\dist\server.js:238559:14) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238498:18 }, zone: Zone { _properties: { isAngularZone: true }, _parent: Zone { _properties: {}, _parent: null, _name: '<root>', _zoneDelegate: [Object] }, _name: 'angular', _zoneDelegate: ZoneDelegate { _taskCounts: [Object], zone: [Circular], _parentDelegate: [Object], _forkZS: null, _forkDlgt: null, _forkCurrZone: [Object], _interceptZS: null, _interceptDlgt: null, _interceptCurrZone: [Object], _invokeZS: [Object], _invokeDlgt: [Object], _invokeCurrZone: [Circular], _handleErrorZS: [Object], _handleErrorDlgt: [Object], _handleErrorCurrZone: [Circular], _scheduleTaskZS: [Object], _scheduleTaskDlgt: [Object], _scheduleTaskCurrZone: [Circular], _invokeTaskZS: [Object], _invokeTaskDlgt: [Object], _invokeTaskCurrZone: [Circular], _cancelTaskZS: [Object], _cancelTaskDlgt: [Object], _cancelTaskCurrZone: [Circular], _hasTaskZS: [Object], _hasTaskDlgt: [Object], _hasTaskDlgtOwner: [Circular], _hasTaskCurrZone: [Circular] } }, task: ZoneTask { _zone: Zone { _properties: [Object], _parent: [Object], _name: 'angular', _zoneDelegate: [Object] }, runCount: 0, _zoneDelegates: null, _state: 'notScheduled', type: 'microTask', source: 'Promise.then', data: ZoneAwarePromise { __zone_symbol__state: 0, __zone_symbol__value: Error: NotYetImplemented at Document.exports.nyi (C:\Users\PC-01\Desktop\project_path\dist\server.js:213490:9) at CookieService.check (C:\Users\PC-01\Desktop\project_path\dist\server.js:279517:48) at CookieService.get (C:\Users\PC-01\Desktop\project_path\dist\server.js:279525:47) at new DateFormatterByTimezonePipe (C:\Users\PC-01\Desktop\project_path\dist\server.js:161863:53) at createClass (C:\Users\PC-01\Desktop\project_path\dist\server.js:12945:20) at createPipeInstance (C:\Users\PC-01\Desktop\project_path\dist\server.js:12824:12) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14043:32) at callViewAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14366:13) at execComponentViewsAction (C:\Users\PC-01\Desktop\project_path\dist\server.js:14285:13) at createViewNodes (C:\Users\PC-01\Desktop\project_path\dist\server.js:14078:5) at createRootView (C:\Users\PC-01\Desktop\project_path\dist\server.js:13964:5) at Object.createProdRootView [as createRootView] (C:\Users\PC-01\Desktop\project_path\dist\server.js:14476:12) at ComponentFactory_.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:12310:29) at ComponentFactoryBoundToModule.create (C:\Users\PC-01\Desktop\project_path\dist\server.js:7129:29) at ViewContainerRef_.createComponent (C:\Users\PC-01\Desktop\project_path\dist\server.js:12420:45) at RouterOutlet.activateWith (C:\Users\PC-01\Desktop\project_path\dist\server.js:239338:40) at ActivateRoutes.activateRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238683:40) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238635:19 at Array.forEach (<anonymous>) at ActivateRoutes.activateChildRoutes (C:\Users\PC-01\Desktop\project_path\dist\server.js:238634:29) at ActivateRoutes.activate (C:\Users\PC-01\Desktop\project_path\dist\server.js:238559:14) at C:\Users\PC-01\Desktop\project_path\dist\server.js:238498:18 }, scheduleFn: undefined, cancelFn: null, callback: [Function], invoke: [Function] } }

    opened by ghost 0
  • Thread-local feature does not really work.

    Thread-local feature does not really work.

    The following express example just added a setTimeout on the route. If sending two request at the same time, for example, chrome and firefox. Notice the console log of the requestId are both 2. Also, this library does not work with the latest nodejs. With node 0.12.03, it occationally got the following error.

    TypeError: Cannot read property '_incrementScheduledTaskCount' of undefined at TCP.prototype.close (/home/gitadmin/pms/node_modules/zone/lib/wrappers/binding/stream-wrap.js:429:22) at Socket._destroy (net.js:483:18) at Socket.destroy (net.js:510:8) at Socket.onSocketFinish (net.js:226:17) at Zone.apply (/home/gitadmin/pms/node_modules/zone/lib/zone.js:617:15) at ZoneCallback.call as apply at Socket.wrapper (/home/gitadmin/pms/node_modules/zone/lib/zone.js:761:21) at Socket.emit (events.js:104:17) at Zone.apply (/home/gitadmin/pms/node_modules/zone/lib/zone.js:617:15) at Socket.emit (events.js:382:21)

    require('zone').enable(); express = require('express'); var Zone = zone.Zone;

    var app = express(); var router = express.Router(); Zone.longStackSupport = true;

    //Initialize the Request id in the root zone. //This value will be available to all child zones. zone.data.requestId = 0;

    app.use(function(req, res, next) { //Increment the request ID for every new request ++zone.data.requestId;

    //Create a new Zone for this request zone.create( function RequestZone() { //Store the request URL in the Request zone //This value will be only to this zone and its children zone.data.requestURL = req.url;

             //Continue to run other express middleware within this child zone
             next();
           })
      .setCallback(function(err,result) {
         if (!err) {
            res.write('Transaction succesful\n');
         } else {
            res.write('Transaction failed\n');
            res.write('x' + err.zoneStack + '\n');
         }
         res.end();
      });
    

    }); router.get('/', function(req, res) { setTimeout(function(){ if (Math.random() > 0.5) { //Simulate some async I/O call that throws an exception process.nextTick(function() { throw new Error("monkey wrench"); }); }

    res.write('Running request #' + zone.data.requestId + ' within zone: ' + zone.name + ' (URL:' + zone.data.requestURL + ')\n'); }, (zone.data.requestId %2 ?10:5 )* 1000); });

    app.use('/', router); app.listen(3001);

    opened by goodjius 0
  • Is this project dead?

    Is this project dead?

    It seams like this hasn't been worked on in quite some time, ~10 months at the time of this writing, and I was just wondering if this project is to be considered dead?

    If so, do you know any other project(s) which which provide similar features for node?

    opened by maxnordlund 9
  • TypeError in _stream_writable.js on NodeJS v4.x and v5.0

    TypeError in _stream_writable.js on NodeJS v4.x and v5.0

    It would seem that Zone is not usable beyond v0.12.x? I've tested on v4.0, v4.1, v4.2, and v5.0 with the same results:

    TypeError: Cannot read property 'length' of undefined
        at onwriteDrain (_stream_writable.js:354:12)
        at Zone.afterWrite (_stream_writable.js:344:5)
        at Zone._apply (./node_modules/zone/lib/zone.js:597:15)
        at Zone.apply (./node_modules/zone/lib/zone.js:621:23)
        at processCallbacks (./node_modules/zone/lib/scheduler.js:47:10)
        at processQueues (./node_modules/zone/lib/scheduler.js:67:5)
        at doNTCallback0 (node.js:419:9)
        at EventEmitter._tickCallback (node.js:348:13)
        at Function.Module.runMain (module.js:469:11)
        at startup (node.js:136:18)
    

    This result can be generated with the simplest of Express apps:

    require('zone').enable();
    
    var express = require('express');
    var app = express();
    var router = express.Router();
    
    app.use('/', router);
    app.listen(3000);
    

    I've also noticed that the last commit to this project is 9 months ago. Is this project dead/dying? Is there a successor?

    opened by ngConsulti 0
  • can't connect to mongo using mongoose on Node 0.12 or io.js when zones are enabled

    can't connect to mongo using mongoose on Node 0.12 or io.js when zones are enabled

    The following code appears to works on Node 0.10 but not on 0.12 or iojs 1.4.1:

    require('zone').enable();
    var mongoose = require('mongoose');
    
    mongoose.connect("mongodb://127.0.0.1:27017/test", function(err) {
      console.log("connected to database:", err);
    });
    

    On Node 0.12.0 and iojs 1.4.1 the following error is thrown using the zone package from NPM:

    connecting to database: [Error: connection closed]
    TypeError: undefined is not a function
        at connect (net.js:818:15)
        at net.js:928:9
        at Zone.<anonymous> (dns.js:85:18)
        at Zone._apply (/Users/adam/_dev/base/node_modules/zone/lib/zone.js:597:15)
        at Zone.apply (/Users/adam/_dev/base/node_modules/zone/lib/zone.js:621:23)
        at processCallbacks (/Users/adam/_dev/base/node_modules/zone/lib/scheduler.js:47:10)
        at processQueues (/Users/adam/_dev/base/node_modules/zone/lib/scheduler.js:67:5)
        at EventEmitter._tickCallback (node.js:355:11)
        at Function.Module.runMain (module.js:503:11)
        at startup (node.js:129:16)
    

    The behavior is different when using the latest version of Zone on github, node aborts before calling the example callback:

    net.js:806
        var req = new TCPConnectWrap();
                  ^
    TypeError: undefined is not a function
        at connect (net.js:806:15)
        at net.js:930:9
        at null.<anonymous> (dns.js:371:18)
        at Zone.apply (/Users/adam/_dev/base/node_modules/zone/lib/zone.js:616:15)
        at ZoneCallback.call [as apply] (/Users/adam/_dev/base/node_modules/zone/lib/zone-callback.js:94:31)
        at wrapper [as _onTimeout] (/Users/adam/_dev/base/node_modules/zone/lib/zone.js:758:21)
        at Timer.listOnTimeout (timers.js:88:15)
    
    opened by aszs 0
Owner
StrongLoop and IBM API Connect
API lifecycle from creation to management
StrongLoop and IBM API Connect
An async control-flow library that makes stepping through logic easy.

Step A simple control-flow library for node.JS that makes parallel execution, serial execution, and error handling painless. How to install Simply cop

Tim Caswell 2.2k Dec 22, 2022
:surfer: Asynchronous flow control with a functional taste to it

Asynchronous flow control with a functional taste to it λ aims to stay small and simple, while powerful. Inspired by async and lodash. Methods are imp

Nicolás Bevacqua 763 Jan 4, 2023
The ultimate generator based flow-control goodness for nodejs (supports thunks, promises, etc)

co Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way. Co v4 co@4

TJ Holowaychuk 11.8k Jan 2, 2023
Handling iterables like lazy arrays.

Iterum iterum library provides a class for handling iterable transformations inspired in Array methods and lodash/fp functions. This library also supp

Xavier Garcia Buils 28 Nov 5, 2021
An extension to Async adding better handling of mixed Series / Parallel tasks via object chaining

async-chainable Flow control for NodeJS applications. This builds on the foundations of the Async library while adding better handling of mixed Series

Matt Carter 25 Jul 15, 2019
Async utilities for node and the browser

Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed f

Caolan McMahon 27.8k Dec 31, 2022
A solid, fast Promises/A+ and when() implementation, plus other async goodies.

when.js When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim. It's a powerful combinati

The Javascript Architectural Toolkit 3.4k Dec 18, 2022
Helps you write libraries that accept both promises and callbacks.

What is it? promise-breaker makes it easy to write functions that will accept an optional callback, or return a Promise if a callback is not provided.

Jason Walton 83 Aug 11, 2022
Memoize promise-returning functions. Includes cache expire and prefetch.

promise-memoize Memoize promise-returning functions. Includes cache expire and prefetch. When data expire mode enabled, new values are fetched in adva

Nodeca 56 Nov 1, 2022
GraphErr is an open-source error handling library for GraphQL implementations in Deno. It's a lightweight solution that provides developers with descriptive error messages, reducing ambiguity and improving debugging.

GraphErr Descriptive GraphQL error handling for Deno/Oak servers. Features Provides additional context to GraphQL's native error messaging for faster

OSLabs Beta 35 Nov 1, 2022
Callback-free control flow for Node using ES6 generators.

suspend Generator-based control-flow for Node enabling asynchronous code without callbacks, transpiling, or selling your soul. Suspend is designed to

Jeremy Martin 550 Jul 9, 2022
An async control-flow library that makes stepping through logic easy.

Step A simple control-flow library for node.JS that makes parallel execution, serial execution, and error handling painless. How to install Simply cop

Tim Caswell 2.2k Dec 22, 2022
:surfer: Asynchronous flow control with a functional taste to it

Asynchronous flow control with a functional taste to it λ aims to stay small and simple, while powerful. Inspired by async and lodash. Methods are imp

Nicolás Bevacqua 763 Jan 4, 2023
The ultimate generator based flow-control goodness for nodejs (supports thunks, promises, etc)

co Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way. Co v4 co@4

TJ Holowaychuk 11.8k Jan 2, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A three.js and roslibjs powered web-control for zju fast-drone-250 for laptop-free flight control

Web Control for ZJU Fast-Drone-250 A three.js and roslibjs powered web-control for zju fast-drone-250 for laptop-free flight control (tested on Xiaomi

null 6 Nov 11, 2022
Web based application that uses playerctl in it backend to control remotely your audio using the frontend as remote control.

Linux Remote This is a web based application that uses playerctl in it backend to control remotely your audio using the frontend as remote control. Do

Gabriel Guerra 4 Jul 6, 2022
Import flow for Excel (.xlsx) and CSV file with automated column matching and validation.

RSI react-spreadsheet-import ⚡️ A component used for importing XLS / XLSX / CSV documents built with Chakra UI. Import flow combines: ?? Uploader ⚙️ P

Ugnis 123 Dec 24, 2022