Skip to content

Commit

Permalink
test: add new scenario for async-local storage
Browse files Browse the repository at this point in the history
Add a new scenario of multiple clients sharing a single data
callback function managing their response data through
AsyncLocalStorage APIs

Refs: nodejs#32063
Refs: nodejs#32060
Refs: nodejs#32062 (comment)

Co-authored-by: Gireesh Punathil <gpunathi@in.ibm.com>

PR-URL: nodejs#32082
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
HarshithaKP authored and targos committed Apr 25, 2020
1 parent a478212 commit a68da78
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions test/parallel/test-async-local-storage-http-multiclients.js
@@ -0,0 +1,65 @@
'use strict';
const common = require('../common');
const Countdown = require('../common/countdown');
const assert = require('assert');
const { AsyncLocalStorage } = require('async_hooks');
const http = require('http');
const cls = new AsyncLocalStorage();
const NUM_CLIENTS = 10;

// Run multiple clients that receive data from a server
// in multiple chunks, in a single non-closure function.
// Use the AsyncLocalStorage (ALS) APIs to maintain the context
// and data download. Make sure that individual clients
// receive their respective data, with no conflicts.

// Set up a server that sends large buffers of data, filled
// with cardinal numbers, increasing per request
let index = 0;
const server = http.createServer((q, r) => {
// Send a large chunk as response, otherwise the data
// may be sent in a single chunk, and the callback in the
// client may be called only once, defeating the purpose of test
r.end((index++ % 10).toString().repeat(1024 * 1024));
});

const countdown = new Countdown(NUM_CLIENTS, () => {
server.close();
});

server.listen(0, common.mustCall(() => {
for (let i = 0; i < NUM_CLIENTS; i++) {
cls.run(new Map(), common.mustCall(() => {
const options = { port: server.address().port };
const req = http.get(options, common.mustCall((res) => {
const store = cls.getStore();
store.set('data', '');

// Make ondata and onend non-closure
// functions and fully dependent on ALS
res.setEncoding('utf8');
res.on('data', ondata);
res.on('end', common.mustCall(onend));
}));
req.end();
}));
}
}));

// Accumulate the current data chunk with the store data
function ondata(d) {
const store = cls.getStore();
assert.notStrictEqual(store, undefined);
let chunk = store.get('data');
chunk += d;
store.set('data', chunk);
}

// Retrieve the store data, and test for homogeneity
function onend() {
const store = cls.getStore();
assert.notStrictEqual(store, undefined);
const data = store.get('data');
assert.strictEqual(data, data[0].repeat(data.length));
countdown.dec();
}

0 comments on commit a68da78

Please sign in to comment.