Managing shared state in Node.js without compromising on data lose and security issues
Backend Call
Backend Call
DB Query
Backend Call
DB Query
Backend Call
Practical Examples
X-request-id
Aspects
Experiments
Cache
Local State
Requirements
Maintain context throughout an async flow
Ensure accessibility of the context only within the same async flow
Async Flow
Backend �API Call
Backend �API Call
DB Query
Requset
Response
Ideas?
Global Object?
Global Object?
How the event loop works?
Backend �API Call 2
DB Query 2
Backend �API Call 2
Response 1
Response 2
Request 1
Request 2
Main Thread
Backend �API Call 1
Backend �API Call 1
DB Query 1
How Multi-Threading works?
Thread 2
Multi-Threading
Backend �API Call 1
Backend �API Call 1
DB Query 1
Request 1
Response 1
Backend �API Call 2
Backend �API Call 2
DB Query 2
Request 2
Response 2
Thread 1
VS
Thread 2
Multi-Threading
Backend �API Call 1
Backend �API Call 1
DB Query 1
Request 1
Response 1
Backend �API Call 2
Backend �API Call 2
DB Query 2
Request 2
Response 2
Thread 1
Event-Loop
Backend �API Call 1
DB Query 1
Backend �API Call 2
Backend �API Call 1
DB Query 2
Backend �API Call 2
Response 1
Response 2
Request 1
Request 2
Main Thread
Thread Local Storage
“If you can’t solve a problem, then there is an easier problem you can solve: find it.”
- George Polya
Multi-Threading in Node?
Multi-Threading in Node?
A new thread for each incoming request
Multi-Threading in Node?
A new thread for each incoming request
Child proccess
Multi-Threading in Node?
A new thread for each incoming request
Child proccess Worker threads
Multi-Threading in Node?
A new thread for each incoming request
Child proccess Worker threads Clusters
“Workers (threads) are useful for performing CPU-intensive JavaScript operations. ��They do not help much with I/O-intensive work. ��The Node.js built-in asynchronous I/O operations are more efficient than Workers can be.”
- docs
Built in Node API
The solution
��
A built-in Node.js API that provides a way of propagating the context of the current async operation through the call chain without the need to explicitly pass it as a function parameter. ��It is similar to thread-local storage in other languages.
AsyncLocalStorage��
Performance
“While you can create your own implementation on top of the node:async_hooks module, AsyncLocalStorage should be preferred as it is a performant and memory safe implementation that involves significant optimizations that are non-obvious to implement.”
- docs
async_hooks Performance Analysis
Context Loss
In most cases, AsyncLocalStorage works without issues. In rare situations, the current store is lost in one of the asynchronous operations.��If your code is promise-based there should be no problem otherwise if it is callback-based, it is enough to promisify it with util.promisify() so it starts working with native promises.
Summary
AsyncLocalStorage is the best option for a TLS-like solution to store a local context between an async flow. �
Before using it you should be aware of its pitfalls�
Thank You