Skip to content

Commit 227d220

Browse files
committed
Update to retain the TCP -> HTTP conversion but drop the queue depth.
- In a separate PR, we will add an endpoint to realm server to report on queue stats starting with queue depth.
1 parent 84cc7b2 commit 227d220

File tree

4 files changed

+57
-59
lines changed

4 files changed

+57
-59
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ Instead of running `pnpm start:base`, you can alternatively use `pnpm start:all`
8282
| :4201 | `/seed` seed realm || 🚫 |
8383
| :4202 | `/test` host test realm, `/node-test` node test realm || 🚫 |
8484
| :4205 | `/test` realm for matrix client tests (playwright controlled) | 🚫 | 🚫 |
85-
| :4210 | Worker Manager (spins up 1 worker by default in development) || 🚫 |
86-
| :4211 | Worker Manager (spins up 1 worker by default) || 🚫 |
85+
| :4210 | Development Worker Manager (spins up 1 worker by default) || 🚫 |
86+
| :4211 | Test Worker Manager (spins up 1 worker by default) || 🚫 |
8787
| :4212 | Worker Manager for matrix client tests (playwright controlled - 1 worker) || 🚫 |
8888
| :4213 | Worker Manager for matrix client tests - base realm server (playwright controlled - 1 worker) || 🚫 |
8989
| :5001 | Mail user interface for viewing emails sent to local SMTP || 🚫 |
@@ -290,7 +290,7 @@ To run the `packages/realm-server/` workspace tests start:
290290
### Boxel UI
291291

292292
1. `cd packages/boxel-ui/test-app`
293-
2. `pnpm test` (or `pnpm start` and visit http://localhost:4210/tests to run tests in the browser)
293+
2. `pnpm test` (or `pnpm start` and visit http://localhost:4220/tests to run tests in the browser)
294294

295295
### Boxel Motion
296296

packages/realm-server/scripts/start-worker-production.sh

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
NODE_NO_WARNINGS=1 \
44
ts-node \
55
--transpileOnly worker-manager \
6-
--port=4210 \
76
--allPriorityCount="${WORKER_ALL_PRIORITY_COUNT:-1}" \
87
--highPriorityCount="${WORKER_HIGH_PRIORITY_COUNT:-0}" \
98
--matrixURL='https://matrix.boxel.ai' \

packages/realm-server/scripts/start-worker-staging.sh

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
NODE_NO_WARNINGS=1 \
44
ts-node \
55
--transpileOnly worker-manager \
6-
--port=4210 \
76
--allPriorityCount="${WORKER_ALL_PRIORITY_COUNT:-1}" \
87
--highPriorityCount="${WORKER_HIGH_PRIORITY_COUNT:-0}" \
98
--matrixURL='https://matrix-staging.stack.cards' \

packages/realm-server/worker-manager.ts

+54-54
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
logger,
55
userInitiatedPriority,
66
systemInitiatedPriority,
7-
query,
87
} from '@cardstack/runtime-common';
98
import yargs from 'yargs';
109
import * as Sentry from '@sentry/node';
@@ -14,7 +13,14 @@ import pluralize from 'pluralize';
1413
import Koa from 'koa';
1514
import Router from '@koa/router';
1615
import { ecsMetadata, fullRequestURL, livenessCheck } from './middleware';
17-
import { PgAdapter } from '@cardstack/postgres';
16+
import { Server } from 'http';
17+
18+
/* About the Worker Manager
19+
*
20+
* This process runs on each queue worker container and is responsible starting and monitoring the worker processes. It does this via IPC (inter-process communication).
21+
* In test and development environments, the worker manager is also responsible for providing a readiness check HTTP endpoint so that tests can wait until the worker
22+
* manager is ready before proceeding.
23+
*/
1824

1925
let log = logger('worker-manager');
2026

@@ -41,7 +47,6 @@ let {
4147
description:
4248
'HTTP port for worker manager to communicate readiness and status',
4349
type: 'number',
44-
demandOption: true,
4550
},
4651
highPriorityCount: {
4752
description:
@@ -81,70 +86,65 @@ let isExiting = false;
8186
process.on('SIGINT', () => (isExiting = true));
8287
process.on('SIGTERM', () => (isExiting = true));
8388

84-
let dbAdapter = new PgAdapter({});
85-
86-
let webServer = new Koa<Koa.DefaultState, Koa.Context>();
87-
let router = new Router();
88-
router.head('/', livenessCheck);
89-
router.get('/', async (ctxt: Koa.Context, _next: Koa.Next) => {
90-
let result = {
91-
ready: isReady,
92-
} as Record<string, boolean | number>;
93-
if (isReady) {
94-
let [{ queue_depth }] = (await query(dbAdapter, [
95-
`SELECT COUNT(*) as queue_depth FROM jobs WHERE status='unfulfilled'`,
96-
])) as {
97-
queue_depth: string;
98-
}[];
99-
result = {
100-
...result,
101-
highPriorityWorkers: highPriorityCount,
102-
allPriorityWorkers: allPriorityCount,
103-
queueDepth: parseInt(queue_depth, 10),
104-
};
105-
}
106-
ctxt.set('Content-Type', 'application/json');
107-
ctxt.body = JSON.stringify(result);
108-
ctxt.status = isReady ? 200 : 503;
109-
});
89+
let webServerInstance: Server | undefined;
11090

111-
webServer
112-
.use(router.routes())
113-
.use((ctxt: Koa.Context, next: Koa.Next) => {
114-
log.info(
115-
`<-- ${ctxt.method} ${ctxt.req.headers.accept} ${
116-
fullRequestURL(ctxt).href
117-
}`,
118-
);
91+
if (port) {
92+
let webServer = new Koa<Koa.DefaultState, Koa.Context>();
93+
let router = new Router();
94+
router.head('/', livenessCheck);
95+
router.get('/', async (ctxt: Koa.Context, _next: Koa.Next) => {
96+
let result = {
97+
ready: isReady,
98+
} as Record<string, boolean | number>;
99+
if (isReady) {
100+
result = {
101+
...result,
102+
highPriorityWorkers: highPriorityCount,
103+
allPriorityWorkers: allPriorityCount,
104+
};
105+
}
106+
ctxt.set('Content-Type', 'application/json');
107+
ctxt.body = JSON.stringify(result);
108+
ctxt.status = isReady ? 200 : 503;
109+
});
119110

120-
ctxt.res.on('finish', () => {
111+
webServer
112+
.use(router.routes())
113+
.use((ctxt: Koa.Context, next: Koa.Next) => {
121114
log.info(
122-
`--> ${ctxt.method} ${ctxt.req.headers.accept} ${
115+
`<-- ${ctxt.method} ${ctxt.req.headers.accept} ${
123116
fullRequestURL(ctxt).href
124-
}: ${ctxt.status}`,
117+
}`,
125118
);
126-
log.debug(JSON.stringify(ctxt.req.headers));
127-
});
128-
return next();
129-
})
130-
.use(ecsMetadata);
131119

132-
webServer.on('error', (err: any) => {
133-
console.error(`worker manager HTTP server error: ${err.message}`);
134-
});
120+
ctxt.res.on('finish', () => {
121+
log.info(
122+
`--> ${ctxt.method} ${ctxt.req.headers.accept} ${
123+
fullRequestURL(ctxt).href
124+
}: ${ctxt.status}`,
125+
);
126+
log.debug(JSON.stringify(ctxt.req.headers));
127+
});
128+
return next();
129+
})
130+
.use(ecsMetadata);
135131

136-
let webServerInstance = webServer.listen(port);
137-
log.info(`worker manager HTTP listening on port ${port}`);
132+
webServer.on('error', (err: any) => {
133+
log.error(`worker manager HTTP server error: ${err.message}`);
134+
});
135+
136+
webServerInstance = webServer.listen(port);
137+
log.info(`worker manager HTTP listening on port ${port}`);
138+
}
138139

139140
const shutdown = (onShutdown?: () => void) => {
140141
log.info(`Shutting down server for worker manager...`);
141-
webServerInstance.closeAllConnections();
142-
webServerInstance.close((err?: Error) => {
142+
webServerInstance?.closeAllConnections();
143+
webServerInstance?.close((err?: Error) => {
143144
if (err) {
144145
log.error(`Error while closing the server for worker manager HTTP:`, err);
145146
process.exit(1);
146147
}
147-
dbAdapter.close(); // warning this is async
148148
log.info(`worker manager HTTP on port ${port} has stopped.`);
149149
onShutdown?.();
150150
process.exit(0);
@@ -164,7 +164,7 @@ process.on('message', (message) => {
164164
process.send?.('stopped');
165165
});
166166
} else if (message === 'kill') {
167-
console.log(`Ending worker manager process for ${port}...`);
167+
log.info(`Ending worker manager process for ${port}...`);
168168
process.exit(0);
169169
}
170170
});

0 commit comments

Comments
 (0)