kitak's blog

Kみたいなエンジニアになりたいブログ

Node.js で Request Local なコンテキストを Zone.js で作る (2)

前回の続き Node.js で Request Local なコンテキストを Zone.js で作る - kitak blog

本当に Request Local になってるのかなーと思って、以下のようなコードを書いて、ab (ab -n 1000 -c 100) にかけて確かめた。

import * as express from 'express';
import uuidv1 = require('uuid/v1');
import 'zone.js';

interface MyRequest extends express.Request {
    trxId: string,
}

class TrxIdVerifier {
    verify(trxId: string) {
        if (trxId === Zone.current.get('trxId')) {
            console.log(`[trxId=${trxId}] Accept`)
        } else {
            console.error(`[trxId=${trxId}] Reject`)
        }
    }
}

const app = express();
const wait = (sec: number) => {
    return new Promise((resolve) => {
        setTimeout(resolve, sec);
    });
};

app.use(function (req: MyRequest, res, next) {
    const trxId = uuidv1();
    req.trxId = trxId;
    Zone.current.fork({
        name: 'request',
        properties: {
            trxId: trxId,
        },
    }).run(next);
});

app.get('/', async (req: MyRequest, res) => {
    await wait(Math.random() * 200 + 100);
    const verifier = new TrxIdVerifier();
    verifier.verify(req.trxId)
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('listening port on 3000.');
});

最初、全てが Reject になって、あれー... と思ったのだけど、いまいま Native の async/await を使うと Zone が動かないらしい ( Support for native async/await? · Issue #715 · angular/zone.js · GitHub ) 。ES2016 target にトランスパイルしたら意図通り全て Correct で表示された。