lambda + serverlessでRDBを使う際、リクエスト毎にコネクションを閉じたい訳ですが
express + serverless-httpでやった場合
こんなソースだとして
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const app = express();
app.use(async (req, res, next) => {
console.timeEnd("express");
console.time("express");
console.timeLog("express", "express middleware begin");
await next();
await wait(1000);
console.timeLog("express", "express middleware end");
});
app.get("/express/hello", async (req, res) => {
console.timeLog("express", "express open connection");
res.send({ result: "Hello Express!" });
await wait(2000);
console.timeLog("express", "express close connection");
});
結果は
express: 0.003ms express middleware begin
express: 0.32ms express open connection
offline: (λ: app1) RequestId: ckxk2061u000quh9kep97ey7h Duration: 38.19 ms Billed Duration: 39 ms
express: 1.002s express middleware end
express: 2.003s express close connection
という感じで、
- 順番がバラバラ
- res.sendの時点で、レスポンスが返ってしまう・処理が終わってしまう
という問題があります。
nextにawait出来ないのつらい
高負荷の場合、前のリクエストのconnection closeと次のリクエストのconnection openが重なり、エラーとなる場合も
koa + serverless-http の場合
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const app = new Koa();
app.use(async (ctx, next) => {
console.timeEnd("koa");
console.time("koa");
console.timeLog("koa", "koa middleware begin");
await next();
await wait(1000);
console.timeLog("koa", "koa middleware end");
});
app.use(
_.get("/koa/hello", async (ctx) => {
console.timeLog("koa", "koa open connection");
ctx.body = { message: "Hello Koa!" };
await wait(2000);
console.timeLog("koa", "koa close connection");
})
);
koa: 0.003ms koa middleware begin
koa: 0.589ms koa open connection
koa: 2.002s koa close connection
koa: 3.004s koa middleware end
offline: (λ: app2) RequestId: ckxk1v21c000nuh9k1aqk6n4i Duration: 3028.71 ms Billed Duration: 3029 ms
綺麗に順番通り流れてくれた上で、レスポンスが帰るのも全部の処理が終わってから、素敵。