You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.9 KiB

import http from 'http';
import { nanoid } from 'nanoid';
import { Pull, Push } from 'zeromq';
const host = 'localhost';
const port = 3000;
const sender = new Push();
await sender.bind(`tcp://127.0.0.1:5557`);
const receiver = new Pull();
await receiver.bind(`tcp://127.0.0.1:5558`);
const generateId = () => nanoid(32);
const clients: Record<string, http.ServerResponse> = {};
const server = http.createServer((req, res) => {
switch (req.url) {
case '/run':
const jobId = generateId();
const code = 'echo a';
const image = 'ghcr.io/moshell-lang/moshell:master';
const buffer = Buffer.allocUnsafe(jobId.length + image.length + code.length + 8);
buffer.write(jobId, 0);
buffer.writeUInt32BE(image.length, jobId.length);
buffer.writeUInt32BE(code.length, jobId.length + 4);
buffer.write(image, jobId.length + 8);
buffer.write(code, jobId.length + 8 + image.length);
res.writeHead(200, {
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Origin': process.env.ALLOW_ORIGIN || '*',
});
sender.send(buffer).then(() => {
res.write('event: connected\n');
res.write(`data: ${jobId}\n`);
res.write('id: 0\n\n');
});
req.on('close', () => {
res.end('OK');
delete clients[jobId];
});
clients[jobId] = res;
break;
default:
res.writeHead(404);
res.end('404!');
}
});
server.listen(port, () => {
console.log(`Server is running on http://${host}:${port}`);
});
for await (const [buff] of receiver) {
const jobId = buff.subarray(0, 32).toString();
console.log(`Received ${jobId}`);
const res = clients[jobId];
if (!res) {
continue;
}
res.write('event: message\n');
res.write(`data: ${encodeURIComponent(buff.subarray(32).toString())}\n`);
res.write('id: 1\n\n');
}