Я пишу АПИ на яваскрит и `bun`. Моя задача - это приложение которое будет опрашивать разные устройства, например раз в секунду. Пользователь заходит на приложение, создает подключение к устройству, и запекает его. Начинается опрос. Код который опрашивает просто сохраняет результаты в Redis базе денных. Другая точка доступа АПИ эти данные читает и выдает пользователю если это нужно. Опрос продолжается пока пользователь не его не остановит.
Мне нужно хорошее решение в точке АПИ где пользователь запускает процесс, и останавливает. Получается мне нужно запустить процесс и его хендлер сохранить. В другой точке доступа этим управлять типа, остановить, перегрузить, ...
Получается мне нужно запустить независимый процесс. Я посмотрел на Workers в Bun но мне показалось это не совсем то что нужно. Какие есть технические решения для запуска этой задачи именно на яваскрипт.
Ну например у меня устройство MQTT. и запускает опрос устройства кнопкой старт на сайте. Мой АПИ должен запустить подписаться на топики и венуть код HTTP200 при этом сохранив ссылку на этот процесс по ID. Все процесс сидит себе и ждет сообщений, как получит, так в базу запишет. Если пользователь нажал кнопку остановить опрос, то я беру ссылку на этот процесс, и останавливаю его.
Моет текущее решение выглядит вот так
index.ts
import { Elysia, t } from "elysia";
const app = new Elysia()
const workers: Worker[] = [];
app.get("/w_start/:id", (ctx) => {
if (workers[ctx.params.id] === undefined) {
const worker = new Worker(new URL(`./worker1.ts`, import.meta.url));
workers[ctx.params.id] = worker;
}
workers[ctx.params.id].postMessage({
s: true,
id: ctx.params.id
})
return { success: true }
}, {
params: t.Object({
id: t.Number()
})
})
app.get("/w_stopall", (ctx) => {
workers.forEach((w, index) => {
w.postMessage({
s: false,
id: index,
});
});
return { success: true }
})
app.get("/w_stop/:id", (ctx) => {
if (workers[ctx.params.id] !== undefined) {
workers[ctx.params.id].postMessage({
s: false,
id: ctx.params.id
})
}
return { success: true }
}, {
params: t.Object({
id: t.Number()
})
})
app.listen(3000);
console.log(
`Workers ${app.server?.hostname}:${app.server?.port}`
);
worker1.ts
import { sleep } from "bun";
// prevents TS errors
declare var self: Worker;
const path = "./file.txt";
var start:boolean = false
self.onmessage = (event) => {
console.log("From main:", event.data);
let {s, id} = event.data
start = s
if(start) {
endlessAsyncLoop(id);
console.log('Loop has started and this message will display immediately.');
}
};
async function endlessAsyncLoop(id: Number) {
let counter = 0;
while (start) {
await Bun.sleep(1000)
await Bun.write(path, `${counter++}`);
console.log(`${id} - ${counter}`)
}
}
Это все работает. Но я в самом начале пути, когда можно решить большинство проблем просто посоветовавшись с умными людьми. Это будет работать в долгосрочной перспективе?