Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
147 lines (125 loc) · 3.92 KB
/
Copy pathindex.js
File metadata and controls
147 lines (125 loc) · 3.92 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import "moment-timezone"
import xapp from "@artsy/xapp"
import compression from "compression"
import { bodyParserMiddleware } from "./src/lib/bodyParserMiddleware"
import { info, error } from "./src/lib/loggers"
import config from "./src/config"
import { init as initTracer } from "./src/lib/tracer"
import { IpFilter as ipfilter } from "express-ipfilter"
import { errorHandler } from "./src/lib/errorHandler"
const {
ENABLE_ASYNC_STACK_TRACES,
ENABLE_QUERY_TRACING,
GRAVITY_API_URL,
GRAVITY_ID,
GRAVITY_SECRET,
IP_DENYLIST,
NODE_ENV,
PORT,
} = config
const port = PORT
const isDevelopment = NODE_ENV === "development"
const enableAsyncStackTraces = ENABLE_ASYNC_STACK_TRACES === "true"
const enableQueryTracing = ENABLE_QUERY_TRACING === "true"
let server, isShuttingDown, hasBooted
// This needs to happen as early as possible so the plugins can hook into the
// modules we use before any other code gets a chance to use them. Additionally,
// since dd-trace monkey patches express it needs to be loaded before creating
// the graphql server otherwise we will not have accurate tracing on those
// routes.
if (enableQueryTracing) {
if (isDevelopment) {
console.warn(
"[WARNING] You probably don't want ENABLE_QUERY_TRACING set to true in .env"
)
}
console.warn("[FEATURE] Enabling query tracing")
initTracer()
}
if (enableAsyncStackTraces) {
console.warn("[FEATURE] Enabling long async stack traces") // eslint-disable-line
require("longjohn")
}
// Use require here so that it definitely gets loaded /after/ initializing the
// datadog client, which is needed so it can hook into supported modules such as
// express.
const app = require("express")()
// `compressible` has no special case for `text/event-stream` (it falls
// through to the general `^text/` rule and returns true), so without this
// filter zlib would buffer the AI agent subscription's SSE stream and defeat
// incremental delivery.
app.use(
compression({
filter: (req, res) => {
const contentType = res.getHeader("Content-Type")
const isEventStream =
typeof contentType === "string" &&
contentType.startsWith("text/event-stream")
return !isEventStream && compression.filter(req, res)
},
})
)
xapp.on("error", (err) => {
error(
"Could not start Metaphysics because it could not set up the xapp token, this is likely due to your `GRAVITY_*` env vars:"
)
error(err)
process.exit(1)
})
const xappConfig = {
url: GRAVITY_API_URL,
id: GRAVITY_ID,
secret: GRAVITY_SECRET,
}
xapp.init(xappConfig, (_unused, token) => {
config.GRAVITY_XAPP_TOKEN = token
if (hasBooted) return
bootApp()
hasBooted = true
}) // eslint-disable-line
function bootApp() {
if (IP_DENYLIST) {
app.use(
ipfilter(IP_DENYLIST.split(","), {
allowedHeaders: ["x-forwarded-for"],
log: false,
mode: "deny",
})
)
}
app.use(bodyParserMiddleware)
app.get("/favicon.ico", (_req, res) => {
res.status(200).set({ "Content-Type": "image/x-icon" }).end()
})
app.get("/health", (req, res) => {
if (isShuttingDown) {
return res.status(503).end()
}
return res.status(200).end()
})
app.all("/graphql", (_req, res) => res.redirect("/v2"))
if (isDevelopment) {
const { createReloadable } = require("@artsy/express-reloadable")
const mountAndReload = createReloadable(app, require)
mountAndReload("./src")
} else {
app.use(require("./src").default)
}
server = require("http-shutdown")(
app.listen(port, () =>
info(`[Metaphysics] Listening on http://localhost:${port}/v2`)
)
)
// General error handler, should be last (and after Sentry's).
app.use(errorHandler)
}
process.on("SIGTERM", gracefulExit)
function gracefulExit() {
if (isShuttingDown) return
isShuttingDown = true
console.log("Received signal SIGTERM, shutting down")
server.shutdown(function () {
console.log("Closed existing connections.")
process.exit(0)
})
}