forked from oxen-io/lokinet-gui
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathipcNode.ts
More file actions
125 lines (109 loc) · 3.73 KB
/
ipcNode.ts
File metadata and controls
125 lines (109 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* eslint-disable @typescript-eslint/no-explicit-any */
import Electron, { BrowserWindow } from 'electron';
import { initialLokinetRpcDealer } from './lokinetRpcCall';
import {
IPC_CHANNEL_KEY,
IPC_GLOBAL_ERROR,
IPC_LOG_LINE,
StatusErrorType
} from './sharedIpc';
const { ipcMain } = Electron;
import * as rpcCalls from './lokinetRpcCall';
import * as lokinetProcessManager from './lokinetProcessManager';
import * as utilityIPCCalls from './utilityIPCCalls';
const eventsByJobId: Record<string, Electron.IpcMainEvent> =
Object.create(null);
const getEventByJobId = (jobId: string): Electron.IpcMainEvent => {
const event = eventsByJobId[jobId];
if (!event) {
throw new Error(`Could not find the event for jobId ${jobId}`);
}
return event;
};
const deleteJobId = (jobId: string) => {
if (eventsByJobId[jobId]) {
delete eventsByJobId[jobId];
}
};
export const sendIpcReplyAndDeleteJob = (
jobId: string,
error: any,
result: string | undefined
) => {
try {
const event = getEventByJobId(jobId);
event.sender?.send(`${IPC_CHANNEL_KEY}-done`, jobId, error, result);
deleteJobId(jobId);
} catch (e: any) {
console.warn(
`sendIpcReplyAndDeleteJob for ${jobId} failed with `,
e.message
);
}
};
let getMainWindowLocal: () => BrowserWindow | null;
/**
* Returns the function to call for that RPC call, so with zeromq client, or undefined.
*/
function isRpcCall(fnName: string) {
return (rpcCalls as any)[fnName];
}
/**
* Returns the function to call for that Lokinet Process Manager call, or undefined.
*/
function isLokinetProcessManagerCall(fnName: string) {
return (lokinetProcessManager as any)[fnName];
}
/**
* Returns the function to call for that Utility IPC call.
*/
function isUtilityCall(fnName: string) {
return (utilityIPCCalls as any)[fnName];
}
export async function initializeIpcNodeSide(
getMainWindow: () => BrowserWindow | null
): Promise<void> {
await initialLokinetRpcDealer();
getMainWindowLocal = getMainWindow;
ipcMain.on(IPC_CHANNEL_KEY, async (event, jobId, callName, ...args) => {
try {
// Try to find a matching rpc call, or a matching lokinetProcessManager call or a matching utility call
const rpcCall = isRpcCall(callName);
const lokinetProcessManagerCall = isLokinetProcessManagerCall(callName);
const utilityCall = isUtilityCall(callName);
const fnToCall = rpcCall || lokinetProcessManagerCall || utilityCall;
if (!fnToCall) {
// if that fn is not defined at all, there is not much we can do.
throw new Error(
`ipc channel: ${callName} is not an available function`
);
}
if (eventsByJobId[jobId]) {
throw new Error(`There is already a event for this jobId ${jobId}`);
}
eventsByJobId[jobId] = event;
// this call just trigger the RPC call. The reply will come from somewhere else
await fnToCall(jobId, ...args);
} catch (error: any) {
const errorForDisplay = error && error.msg ? error.msg : error;
console.log(
`ipc channel error with call ${callName}: ${errorForDisplay}`
);
sendIpcReplyAndDeleteJob(jobId, errorForDisplay || null, '');
}
});
}
export function logLineToAppSide(logLine: string): void {
const withTimestamp = `${logLine}`;
if (utilityIPCCalls.getRendererReady()) {
getMainWindowLocal()?.webContents?.send(IPC_LOG_LINE, withTimestamp);
}
}
export function sendGlobalErrorToAppSide(globalError: StatusErrorType): void {
if (utilityIPCCalls.getRendererReady()) {
console.info(`sendGlobalErrorToAppSide: global error "${globalError}"`);
getMainWindowLocal()?.webContents?.send(IPC_GLOBAL_ERROR, globalError);
} else {
console.info('sendGlobalErrorToAppSide : renderer is not ready');
}
}