Skip to content

Instantly share code, notes, and snippets.

@florentdupont
Created February 2, 2022 17:15
Show Gist options
  • Save florentdupont/daec5a318cfd8d6306d5fb8e5d63332e to your computer and use it in GitHub Desktop.
Save florentdupont/daec5a318cfd8d6306d5fb8e5d63332e to your computer and use it in GitHub Desktop.
Exemple de fuite de CLS Hornet
import express, {Request,Response,Application} from 'express';
const HornetPromise = require("../dist/index").BluebirdPromise;
const { Utils } = require("../dist/utils");
const fetch = require('node-fetch');
const app:Application = express();
const PORT = process.env.PORT || 8000;
app.use(function (req, res, next) {
// Le namespace ne doit être créé qu'une seule fois.
// il faut donc faire un create, puis ensuite un get.
// S'il n'y a pas plusieurs requêtes en cours, alors il n'y a plus de namespace, il faudra donc le recréer.
// s'il y'a déjà une requête en cours, ca va poser problème de recréer un namespace existant : il faut donc le récupérer.
// du coup, c'est bien ce qui est fait ave le getOrCreate de Hornet : on tente de le récupérer, et s'il n'existe pas, on le créé.
// ce qui fait qu'il sera créé la premieère fois, mais les autres fois, on s'appuie sur l'existant.
let cls_ = Utils.getOrCreateContinuationStorage()
cls_.bindEmitter(req);
cls_.bindEmitter(res);
cls_.run(() => {
cls_.set("foo", req.query.name);
// HornetPromise.resolve(Promise.resolve(null)).then( () => { // avec une construction de cette forme, avec Promise native, ca marche très bien
HornetPromise.resolve(null).then( () => {
// pourquoi ca marche ici alors que dans le TU ca marche pas ?
let cls = Utils.getOrCreateContinuationStorage();
let foo = cls.get("foo")
if(!foo) {
let msg = "foo is undefined";
console.log('\x1b[1m\x1b[37m%s\x1b[0m', msg);
}
// Réalise un autre appel asynchrone ici qui soit aléatoire
// si name est 0, alors, le result est a
// si name est 1, alors, le result est b
// pour faire comme en Hornet, j'encapsule dans un HornetPromise
return HornetPromise.resolve(fetch('http://localhost:8080?name=' + foo))
}).then((res:any) => {
// je suis déjà dans une HornetPromise ici, pas nécessaire de ré-encapsuler
return res.json()
}).then( (body:any) => {
let cls = Utils.getOrCreateContinuationStorage();
// positionne le résultat dans le cls
cls.set("result", body.result)
}).then(() => {
let date = new Date().toISOString().replace(/T/, ' ');
let cls = Utils.getOrCreateContinuationStorage();
// ICI, on teste : foo devrait être toujours renseigné, et c'est le cas, je ne vois jamais de message d'erreur
if(!cls.get("foo")) {
let msg = "" + date + " AIE : FOO est undefined" ;
console.log('\x1b[33m%s\x1b[0m', msg);
} else {
// si foo est '0', alors result doit être 'a'
// si foo est '1', alors result doit être 'b'
// On se rend compte que ce n'est pas toujours le cas !!
if(cls.get("foo") === "0" && cls.get("result") !== "a") {
console.log('\x1b[33m%s\x1b[0m', "ERREUR : pour Foo=0 et result != a");
res.status(503);
}
if(cls.get("foo") === "1" && cls.get("result") !== "b") {
console.log('\x1b[33m%s\x1b[0m', "ERREUR : pour Foo=1 et result != b");
res.status(503);
}
}
})
.catch((e:any) => {
console.log("ERREUR catchée : ", e);
});
next();
});
});
app.get("/", (req:Request, res:Response):void => {
res.send("Hello Typescript with Node.js!");
});
app.listen(PORT, ():void => {
console.log(`Server Running here 👉 http://localhost:${PORT}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment