From 963b8ec82f44bb4b83ad0ff678420a15d6d21072 Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 20 Sep 2022 16:39:11 +0200 Subject: [PATCH] start backend in seperate worker thread --- backend/src/projects/projects.service.ts | 3 +- frontend/src/targets/electron/main.ts | 31 ++++----------- frontend/src/targets/electron/worker.ts | 49 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 26 deletions(-) create mode 100644 frontend/src/targets/electron/worker.ts diff --git a/backend/src/projects/projects.service.ts b/backend/src/projects/projects.service.ts index cfa1790a..e14e122a 100644 --- a/backend/src/projects/projects.service.ts +++ b/backend/src/projects/projects.service.ts @@ -119,8 +119,7 @@ export class ProjectsService { async cleanupProject() { try { - // remove all existing data of previously used project - // TODO(milestone-x): persist data for projects by default? + // Remove all cached data of previously used project await this.commonService.removeBlockchainData(); } catch (e) { throw new InternalServerErrorException("Database cleanup failed"); diff --git a/frontend/src/targets/electron/main.ts b/frontend/src/targets/electron/main.ts index ca98eed5..addf92cd 100644 --- a/frontend/src/targets/electron/main.ts +++ b/frontend/src/targets/electron/main.ts @@ -1,33 +1,14 @@ import * as path from "path"; import { app, BrowserWindow, shell, dialog } from "electron"; -import { createApp, ProcessManagerService } from "@flowser/backend"; +import { ProcessManagerService } from "@flowser/backend"; import fixPath from "fix-path"; -import { INestApplication } from "@nestjs/common"; +import * as worker from "./worker"; fixPath(); const minWidth = 900; const minHeight = 600; -let backend: INestApplication; - -async function startBackend() { - const userDataPath = app.getPath("userData"); - const databaseFilePath = path.join(userDataPath, "flowser.sqlite"); - if (backend) { - await backend.close(); - } - backend = await createApp({ - database: { - type: "sqlite", - name: databaseFilePath, - }, - common: { - httpServerPort: 6061, - }, - }); -} - async function createWindow() { const win = new BrowserWindow({ width: minWidth, @@ -54,7 +35,7 @@ async function createWindow() { async function handleStart() { try { - await startBackend(); + await worker.start(); } catch (error) { await handleBackendError({ error, @@ -87,8 +68,10 @@ app.on("activate", function () { app.on("will-quit", async function () { // Make sure to stop all child processes, so that they don't become orphans - const processManagerService = backend.get(ProcessManagerService); - await processManagerService.stopAll(); + if (worker.backend) { + const processManagerService = worker.backend.get(ProcessManagerService); + await processManagerService.stopAll(); + } }); type ErrorWithCode = { code: string }; diff --git a/frontend/src/targets/electron/worker.ts b/frontend/src/targets/electron/worker.ts new file mode 100644 index 00000000..fe7e8fc4 --- /dev/null +++ b/frontend/src/targets/electron/worker.ts @@ -0,0 +1,49 @@ +import { Worker, isMainThread, parentPort, workerData } from "worker_threads"; +import path from "path"; +import { app } from "electron"; +import { createApp } from "@flowser/backend"; +import { INestApplication } from "@nestjs/common"; + +export let backend: INestApplication; + +async function startBackend({ userDataPath }: { userDataPath: string }) { + const databaseFilePath = path.join(userDataPath, "flowser.sqlite"); + if (backend) { + await backend.close(); + } + backend = await createApp({ + database: { + type: "sqlite", + name: databaseFilePath, + }, + common: { + httpServerPort: 6061, + }, + }); +} + +export let start: () => Promise; + +if (isMainThread) { + start = async function () { + const userDataPath = app.getPath("userData"); + return new Promise((resolve, reject) => { + const worker = new Worker(__filename, { + workerData: { + userDataPath, + }, + }); + worker.on("message", resolve); + worker.on("error", reject); + worker.on("exit", (code) => { + if (code !== 0) + reject(new Error(`Worker stopped with exit code ${code}`)); + }); + }); + }; +} else { + const { userDataPath } = workerData; + startBackend({ + userDataPath, + }).then(() => parentPort?.postMessage("Backend started")); +}