-
Notifications
You must be signed in to change notification settings - Fork 5
/
server.js
97 lines (73 loc) · 2.51 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import {
createServer
} from 'node:http'
import { once } from 'node:events'
import { promisify } from 'node:util'
import { randomUUID } from 'node:crypto'
import { AsyncLocalStorage } from 'node:async_hooks'
import { Sequelize, DataTypes } from 'sequelize'
const getConnectionString = () => {
const host = process.env.POSTGRES_HOST || "localhost"
const db = process.env.POSTGRES_DB || "heroes"
const password = process.env.POSTGRES_PASSWORD || "mysecretpassword"
const port = parseInt(process.env.POSTGRES_PORT || "5432")
return `postgres://postgres:${password}@${host}:${port}/${db}`
}
async function getDB() {
const sequelize = new Sequelize(
getConnectionString(),
{
logging: false,
native: false,
}
);
await sequelize.authenticate();
console.log("postgres is running");
const Hero = sequelize.define("hero", {
name: DataTypes.STRING,
power: DataTypes.STRING,
});
await Hero.sync({ force: true });
return {
Hero,
sequelize,
}
}
const { Hero, sequelize } = await getDB()
async function handleRequest(request, response) {
// some validation should be done here
const data = JSON.parse(await once(request, 'data'))
const result = await Hero.create(data)
return response.end(JSON.stringify(result))
}
const storage = new AsyncLocalStorage()
// cannot add `async` here otherwise it's gonna be on a different async context
const server = createServer((request, response) => {
storage.enterWith({ response, id: randomUUID() })
return handleRequest(request, response)
})
.listen(3000)
.once('listening', () =>
console.log('server running at', server.address().port)
)
for (const error of ['uncaughtException', 'unhandledRejection']) {
process.once(error, async (message) => {
const { response, id } = storage.getStore()
const shortenId = id.slice(0, 3)
console.log(`req: [${shortenId}] crashed but will be nicely handled!`)
console.log(`${error} received!\nmessage: ${message}\n`)
response.end(`wow! - req id: ${shortenId}`)
await promisify(server.close.bind(server))()
console.log('http server closed')
await sequelize.close()
console.log('DB connection closed')
process.exit(1)
})
}
/*
// turn off docker container to simulate a critical error
curl \
-H "Content-Type: application/json" \
-d '{"name":"John Wick", "power": "superhuman strength"}' \
localhost:3000
*/