Node js – Preserving Data Across Async Callbacks in continuation-local-storage and MongoDB client


The problem when we use a lot of promises to handle callback in node js it will be destroyed variable “process.domain” in callback context when using it in the wrong way.

To more details of this problem you can read this post: https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

The Problem

The ability to track a single request by a transaction id and the fact that call stacks stop at the event loop both arise because after control goes back to the Node.js event loop, there is no guarantee which asynchronous function will run next.

In the diagram below func1 is trying to set the current transaction id (tid) on the global state. However, because we don’t know if func2 will be run immediately after, we can’t guarantee tidwill still be 10 when func2 runs. If you wanted to have data preserved, you’d have to manually make it available to each callback either as an argument or via a closure.

Recently a push from Trevor Norris, Tim Caswell, and Forrest Norvell introduced the AsyncListener API and continuation-local-storage.

With the AsyncListener API you can set functions to be executed when a callback is instantiated, before the callback is executed, and after the callback is executed. This provides the necessary building block to solve the problem illustrated in the diagram above, we can associate some data or state with func2 when we call process.nextTick(func2). When func2 is run, we can look it up again. However, how the AsyncListener API works and how it’s used by continuation-local-storage is enough for it’s own post.

The continuation-local-storage module builds on the AsyncListener API to make associating arbitrary data with a callback very easy. For example you can associate the current request or stack trace from when a callback was instantiated, and look it up when the callback is executed. This new ability makes debugging easier by having more informative logs. In the rest of this post we’ll dive into the nitty-gritty of how to use the continuation-local-storage module. In a future post I’ll explain how the continuation-local-storage module, and the AsyncListener API works.

As a backdrop to this post, our goal will be to:

  1. Generate a transaction id for every request our express app receives.
  2. Have that transaction id available to our logger so we can know which log statements are related.

So with that, let’s get started.

 

and maybe this ask a lot: https://stackoverflow.com/questions/34017888/node-continuation-local-storage

To resolve this problem please flow this way:

With promise:

  • Always using “then” and “catch” don’t put the function to a callback, it will make problem again.
  • Can flow this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

With Mongo Client

  • Always using then and catch, and avoid use callback function
  • Can flow http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html

 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s