fix: second work-over
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
import * as path from 'path';
|
||||
import { Worker } from 'worker_threads';
|
||||
|
||||
export interface BlogmarkWorkerLike {
|
||||
on(event: string, listener: (...args: unknown[]) => void): void;
|
||||
postMessage(message: unknown): void;
|
||||
terminate(): void;
|
||||
removeAllListeners(): void;
|
||||
}
|
||||
|
||||
export type BlogmarkWorkerFactory = (workerPath: string) => BlogmarkWorkerLike;
|
||||
|
||||
interface WorkerRunTransformRequest {
|
||||
type: 'runTransform';
|
||||
requestId: string;
|
||||
@@ -45,7 +54,7 @@ interface ActiveRequest extends QueuedRequest {
|
||||
}
|
||||
|
||||
export class BlogmarkPythonWorkerRuntime {
|
||||
private worker: Worker | null = null;
|
||||
private worker: BlogmarkWorkerLike | null = null;
|
||||
private workerReady = false;
|
||||
private workerStartPromise: Promise<void> | null = null;
|
||||
private workerStartResolve: (() => void) | null = null;
|
||||
@@ -53,6 +62,11 @@ export class BlogmarkPythonWorkerRuntime {
|
||||
private activeRequest: ActiveRequest | null = null;
|
||||
private queue: QueuedRequest[] = [];
|
||||
private requestCounter = 0;
|
||||
private readonly workerFactory: BlogmarkWorkerFactory;
|
||||
|
||||
constructor(workerFactory?: BlogmarkWorkerFactory) {
|
||||
this.workerFactory = workerFactory ?? ((workerPath: string) => new Worker(workerPath) as unknown as BlogmarkWorkerLike);
|
||||
}
|
||||
|
||||
async executeTransform(params: {
|
||||
scriptContent: string;
|
||||
@@ -96,6 +110,12 @@ export class BlogmarkPythonWorkerRuntime {
|
||||
|
||||
await this.ensureWorkerStarted();
|
||||
|
||||
// Re-check guard after await — another dispatchNext() may have
|
||||
// activated a request while we were waiting for the worker.
|
||||
if (this.activeRequest || this.queue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nextRequest = this.queue.shift();
|
||||
if (!nextRequest) {
|
||||
return;
|
||||
@@ -131,18 +151,20 @@ export class BlogmarkPythonWorkerRuntime {
|
||||
}
|
||||
|
||||
const workerPath = path.join(__dirname, 'blogmarkPython.worker.js');
|
||||
this.worker = new Worker(workerPath);
|
||||
this.worker = this.workerFactory(workerPath);
|
||||
this.workerReady = false;
|
||||
|
||||
this.worker.on('message', (message: WorkerResponseMessage) => {
|
||||
this.handleWorkerMessage(message);
|
||||
this.worker.on('message', (...args: unknown[]) => {
|
||||
this.handleWorkerMessage(args[0] as WorkerResponseMessage);
|
||||
});
|
||||
|
||||
this.worker.on('error', (error) => {
|
||||
this.worker.on('error', (...args: unknown[]) => {
|
||||
const error = args[0];
|
||||
this.handleWorkerCrash(error instanceof Error ? error : new Error(String(error)));
|
||||
});
|
||||
|
||||
this.worker.on('exit', (code) => {
|
||||
this.worker.on('exit', (...args: unknown[]) => {
|
||||
const code = args[0] as number;
|
||||
if (code !== 0) {
|
||||
this.handleWorkerCrash(new Error(`Python worker exited with code ${code}`));
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ function validateParamValue(methodName: string, param: PythonApiParamContractV1,
|
||||
|
||||
type EngineGetter = () => Record<string, (...args: unknown[]) => unknown>;
|
||||
|
||||
const ENGINE_MAP: Record<string, EngineGetter> = {
|
||||
export const ENGINE_MAP: Record<string, EngineGetter> = {
|
||||
posts: () => {
|
||||
const { getPostEngine } = require('../engine/PostEngine');
|
||||
return getPostEngine();
|
||||
|
||||
@@ -772,6 +772,9 @@ export function registerIpcHandlers(): void {
|
||||
return engine.getAllScripts();
|
||||
});
|
||||
|
||||
// Internal: used by the editor macro plugin to detect known Python macros.
|
||||
// Intentionally excluded from the Python API contract and API.md because
|
||||
// it is an internal renderer helper, not a user-facing scripting API.
|
||||
safeHandle('scripts:getEnabledMacroSlugs', async () => {
|
||||
const engine = getScriptEngine();
|
||||
const scripts = await engine.getEnabledMacroScripts();
|
||||
|
||||
@@ -589,6 +589,7 @@ export interface ElectronAPI {
|
||||
delete: (id: string) => Promise<boolean>;
|
||||
get: (id: string) => Promise<ScriptData | null>;
|
||||
getAll: () => Promise<ScriptData[]>;
|
||||
/** Internal: editor macro plugin helper. Not exposed via Python API contract. */
|
||||
getEnabledMacroSlugs: () => Promise<string[]>;
|
||||
rebuildFromFiles: () => Promise<void>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user