From 6518776596be15d6cbdc33084381460978ac4b08 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 30 Mar 2024 01:06:48 +0800 Subject: [PATCH 1/4] test use db in worker_thread --- packages/sqlite-plugin/src/index.ts | 2 +- .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 8 +++ .../OPEN_SETTING_WINDOW/utils/db/index.ts | 57 +++++++++++++++++++ .../utils/db/worker/index.ts | 53 +++++++++++++++++ .../src/page/BootstrapSplash/index.vue | 6 ++ 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts create mode 100644 packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts diff --git a/packages/sqlite-plugin/src/index.ts b/packages/sqlite-plugin/src/index.ts index ff07b44..b35097b 100644 --- a/packages/sqlite-plugin/src/index.ts +++ b/packages/sqlite-plugin/src/index.ts @@ -17,7 +17,7 @@ import sqlite3 from 'sqlite3'; import * as cliHighlight from 'cli-highlight'; Boolean(cliHighlight); -function initDb(dbFilePath) { +export function initDb(dbFilePath) { const { DataSource } = requireTypeorm() const appDataSource = new DataSource({ type: "sqlite", diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index 7da07ac..903a04f 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -17,6 +17,7 @@ import { getAnyAvailablePuppeteerExecutable } from '../../../flow/CHECK_AND_DOWN import { sleep } from '@geekgeekrun/utils/sleep.mjs' import { AUTO_CHAT_ERROR_EXIT_CODE } from '../../../../common/enums/auto-start-chat' import { mainWindow } from '../../../window/mainWindow' +import { getAutoStartChatRecord, initDbWorker } from '../utils/db/index' export default function initIpc () { ipcMain.on('open-external-link', (_, link) => { @@ -257,4 +258,11 @@ export default function initIpc () { const cookies = readStorageFile('boss-cookies.json') return checkCookieListFormat(cookies) }) + + ipcMain.handle('connect-db', async () => { + const worker = await initDbWorker() + console.log(worker) + const a = await getAutoStartChatRecord() + console.log(a) + }) } diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts new file mode 100644 index 0000000..af0b450 --- /dev/null +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts @@ -0,0 +1,57 @@ +import createDbWorker from './worker/index?nodeWorker&url' +import { type Worker } from 'node:worker_threads' +import { randomUUID } from 'node:crypto' + +let worker: Worker | null = null +let workerExitCode: number | null = null +export const initDbWorker = () => { + if (!worker || typeof workerExitCode === 'number') { + worker = createDbWorker() + workerExitCode = null + return new Promise((resolve, reject) => { + worker.once('exit', (exitCode) => { + workerExitCode = exitCode + worker = null + }) + worker.on('message', function handler(data) { + if (data.type === 'DB_INIT_SUCCESS') { + resolve(worker) + // attach more event + worker?.off('message', handler) + } else if (data.type === 'DB_INIT_FAIL') { + reject(undefined) + worker?.terminate() + worker?.off('message', handler) + worker = null + } + }) + }) + } else { + return worker + } +} + +const createWorkerPromise = async (data) => { + await initDbWorker() + const uuid = randomUUID() + worker.postMessage({ + _uuid: uuid, + ...data + }) + return new Promise((resolve) => { + worker.on('message', function handler(data) { + const { _uuid, ...payload } = data ?? {} + if (_uuid === uuid) { + resolve(payload) + worker!.off('message', handler) + } + }) + }) +} + +export const getAutoStartChatRecord = async () => { + const res = await createWorkerPromise({ + type: 'getAutoStartChatRecord' + }) + return res +} diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts new file mode 100644 index 0000000..560151c --- /dev/null +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts @@ -0,0 +1,53 @@ +import { parentPort } from 'node:worker_threads' +import { initDb } from '@geekgeekrun/sqlite-plugin' +import typeorm from 'typeorm' +import { type DataSource } from 'typeorm' +import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' + +const dbInitPromise = initDb(getPublicDbFilePath()) +let dataSource = null + +dbInitPromise.then( + (_dataSource) => { + dataSource = _dataSource + attachMessageHandler() + parentPort?.postMessage({ + type: 'DB_INIT_SUCCESS' + }) + }, + (error) => { + parentPort?.postMessage({ + type: 'DB_INIT_FAIL', + error + }) + process.exit(1) + } +) + +const payloadHandler = { + getAutoStartChatRecord(payload, callback) { + callback({ + x: 'zzzz', + ...payload + }) + } +} + +async function attachMessageHandler() { + if (!dataSource) { + await dbInitPromise + } + parentPort?.on('message', (event) => { + const { _uuid, ...restObj } = event + const { type } = event + + const callback = (result) => { + parentPort?.postMessage({ + _uuid, + data: result + }) + } + + payloadHandler[type](restObj, callback) + }) +} diff --git a/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue b/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue index 90138c0..990291e 100644 --- a/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue +++ b/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue @@ -52,4 +52,10 @@ onMounted(async () => { } }) }) + +electron.ipcRenderer.invoke('connect-db').then(() => { + debugger +}, () => { + debugger +}) From 5256066c34e8248760d26413cc3d14e861744ecc Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 30 Mar 2024 09:03:44 +0800 Subject: [PATCH 2/4] enhance db operation code style --- .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 4 +--- .../OPEN_SETTING_WINDOW/utils/db/index.ts | 10 ++++----- .../utils/db/worker/index.ts | 21 ++++++++----------- .../src/page/BootstrapSplash/index.vue | 2 +- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index 903a04f..abba378 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -259,9 +259,7 @@ export default function initIpc () { return checkCookieListFormat(cookies) }) - ipcMain.handle('connect-db', async () => { - const worker = await initDbWorker() - console.log(worker) + ipcMain.handle('get-auto-start-chat-record', async () => { const a = await getAutoStartChatRecord() console.log(a) }) diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts index af0b450..d411e94 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/index.ts @@ -9,11 +9,11 @@ export const initDbWorker = () => { worker = createDbWorker() workerExitCode = null return new Promise((resolve, reject) => { - worker.once('exit', (exitCode) => { + worker!.once('exit', (exitCode) => { workerExitCode = exitCode worker = null }) - worker.on('message', function handler(data) { + worker!.on('message', function handler(data) { if (data.type === 'DB_INIT_SUCCESS') { resolve(worker) // attach more event @@ -34,16 +34,16 @@ export const initDbWorker = () => { const createWorkerPromise = async (data) => { await initDbWorker() const uuid = randomUUID() - worker.postMessage({ + worker!.postMessage({ _uuid: uuid, ...data }) return new Promise((resolve) => { - worker.on('message', function handler(data) { + worker!.on('message', function handler(data) { const { _uuid, ...payload } = data ?? {} if (_uuid === uuid) { resolve(payload) - worker!.off('message', handler) + worker?.off('message', handler) } }) }) diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts index 560151c..afe0a5b 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts @@ -25,11 +25,11 @@ dbInitPromise.then( ) const payloadHandler = { - getAutoStartChatRecord(payload, callback) { - callback({ + async getAutoStartChatRecord(payload) { + return { x: 'zzzz', ...payload - }) + } } } @@ -37,17 +37,14 @@ async function attachMessageHandler() { if (!dataSource) { await dbInitPromise } - parentPort?.on('message', (event) => { + parentPort?.on('message', async (event) => { const { _uuid, ...restObj } = event const { type } = event - const callback = (result) => { - parentPort?.postMessage({ - _uuid, - data: result - }) - } - - payloadHandler[type](restObj, callback) + const result = await payloadHandler[type](restObj) + parentPort?.postMessage({ + _uuid, + data: result + }) }) } diff --git a/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue b/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue index 990291e..e3d5336 100644 --- a/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue +++ b/packages/ui/src/renderer/src/page/BootstrapSplash/index.vue @@ -53,7 +53,7 @@ onMounted(async () => { }) }) -electron.ipcRenderer.invoke('connect-db').then(() => { +electron.ipcRenderer.invoke('get-auto-start-chat-record').then(() => { debugger }, () => { debugger From dd9ebfc4d08437a58d84231e2c827be556669227 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sun, 31 Mar 2024 10:16:59 +0800 Subject: [PATCH 3/4] add measureExecutionTime --- packages/ui/src/common/utils/performance.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 packages/ui/src/common/utils/performance.ts diff --git a/packages/ui/src/common/utils/performance.ts b/packages/ui/src/common/utils/performance.ts new file mode 100644 index 0000000..f4f4135 --- /dev/null +++ b/packages/ui/src/common/utils/performance.ts @@ -0,0 +1,21 @@ +export const measureExecutionTime = async < + T extends Promise | ((...args: unknown[]) => unknown), + U = T extends Promise + ? T + : T extends (...args: unknown[]) => unknown + ? ReturnType + : never +>( + promiseOrFunction: T +): Promise => { + const startTime = new Date() + if (promiseOrFunction instanceof Promise) { + await promiseOrFunction + console.log(`execution duration ${Number(new Date()) - Number(startTime)}ms`) + return promiseOrFunction as U + } else { + const result = await promiseOrFunction() + console.log(`execution duration ${Number(new Date()) - Number(startTime)}ms`) + return result as U + } +} From 3100bb385479efae169beca5033d128331f7ce5d Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sun, 31 Mar 2024 10:23:51 +0800 Subject: [PATCH 4/4] add the view of chatStartupLog --- .../src/entity/VChatStartupLog.ts | 63 +++++++++++++++++++ packages/sqlite-plugin/src/index.ts | 2 + .../utils/db/worker/index.ts | 25 +++++--- 3 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 packages/sqlite-plugin/src/entity/VChatStartupLog.ts diff --git a/packages/sqlite-plugin/src/entity/VChatStartupLog.ts b/packages/sqlite-plugin/src/entity/VChatStartupLog.ts new file mode 100644 index 0000000..95e1c9d --- /dev/null +++ b/packages/sqlite-plugin/src/entity/VChatStartupLog.ts @@ -0,0 +1,63 @@ +import { requireTypeorm } from "../utils/module-loader"; +const { ViewEntity, ViewColumn } = requireTypeorm(); +@ViewEntity({ + expression: `SELECT + job_info.*, + user_info.name as userName, + chat_startup_log.date, + boss_info.name AS bossName, + company_info.name AS companyName + FROM + chat_startup_log + LEFT JOIN job_info ON chat_startup_log.encryptJobId = job_info.encryptJobId + LEFT JOIN user_info ON chat_startup_log.encryptCurrentUserId = user_info.encryptUserId + LEFT JOIN boss_info ON boss_info.encryptBossId = job_info.encryptBossId + LEFT JOIN company_info ON company_info.encryptCompanyId = job_info.encryptCompanyId + `, +}) +export class VChatStartupLog { + @ViewColumn() + encryptJobId: number; + + @ViewColumn() + jobName: string; + + @ViewColumn() + positionName: string; + + @ViewColumn() + salaryLow: number | null; + + @ViewColumn() + salaryHeigh: number | null; + + @ViewColumn() + salaryMonth: number | null; + + @ViewColumn() + experienceName: number | null; + + @ViewColumn() + publishDate: Date | null; + + @ViewColumn() + degreeName: string; + + @ViewColumn() + address: string; + + @ViewColumn() + description: string; + + @ViewColumn() + userName: string; + + @ViewColumn() + date: string; + + @ViewColumn() + bossName: string; + + @ViewColumn() + companyName: string; +} diff --git a/packages/sqlite-plugin/src/index.ts b/packages/sqlite-plugin/src/index.ts index b35097b..4ce4b26 100644 --- a/packages/sqlite-plugin/src/index.ts +++ b/packages/sqlite-plugin/src/index.ts @@ -12,6 +12,7 @@ import { JobInfo } from "./entity/JobInfo"; import { JobInfoChangeLog } from "./entity/JobInfoChangeLog"; import { BossActiveStatusRecord } from "./entity/BossActiveStatusRecord"; import { UserInfo } from "./entity/UserInfo"; +import { VChatStartupLog } from "./entity/VChatStartupLog"; import sqlite3 from 'sqlite3'; import * as cliHighlight from 'cli-highlight'; @@ -36,6 +37,7 @@ export function initDb(dbFilePath) { JobInfoChangeLog, BossActiveStatusRecord, UserInfo, + VChatStartupLog ], }); return appDataSource.initialize(); diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts index afe0a5b..ce1ebb3 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/utils/db/worker/index.ts @@ -1,11 +1,13 @@ +import 'reflect-metadata' import { parentPort } from 'node:worker_threads' import { initDb } from '@geekgeekrun/sqlite-plugin' -import typeorm from 'typeorm' import { type DataSource } from 'typeorm' import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' +import { VChatStartupLog } from '@geekgeekrun/sqlite-plugin/dist/entity/VChatStartupLog' +import { measureExecutionTime } from '../../../../../../common/utils/performance' const dbInitPromise = initDb(getPublicDbFilePath()) -let dataSource = null +let dataSource: DataSource | null = null dbInitPromise.then( (_dataSource) => { @@ -26,21 +28,26 @@ dbInitPromise.then( const payloadHandler = { async getAutoStartChatRecord(payload) { - return { - x: 'zzzz', - ...payload - } + const result = await measureExecutionTime( + dataSource! + .createQueryBuilder() + .select('*') + .from(VChatStartupLog, 'vChatStartupLog') + .getRawMany() + ) + console.log(result) + return result } } async function attachMessageHandler() { - if (!dataSource) { - await dbInitPromise - } parentPort?.on('message', async (event) => { const { _uuid, ...restObj } = event const { type } = event + if (!dataSource) { + await dbInitPromise + } const result = await payloadHandler[type](restObj) parentPort?.postMessage({ _uuid,