Skip to content

Commit 9b45e5c

Browse files
authored
main: pick a random port for the cli (#106)
1 parent 6951800 commit 9b45e5c

File tree

3 files changed

+71
-34
lines changed

3 files changed

+71
-34
lines changed

.node-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v15.14.0

src/cli.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
2+
import * as Sentry from '@sentry/electron';
3+
import { ChannelCredentials } from '@grpc/grpc-js';
4+
import { createServer } from 'net';
5+
6+
import { pomeriumCli } from './main/binaries';
7+
import { ConfigClient, ListenerClient } from './shared/pb/api';
8+
9+
async function pickPort(): Promise<number> {
10+
const srv = createServer();
11+
srv.listen(0);
12+
const address = srv.address();
13+
srv.close();
14+
if (typeof address === 'object') {
15+
return address?.port || 0;
16+
}
17+
return 0;
18+
}
19+
20+
export type CLI = {
21+
process: ChildProcessWithoutNullStreams;
22+
configClient: ConfigClient;
23+
listenerClient: ListenerClient;
24+
};
25+
26+
export async function start(sentryDSN: string): Promise<CLI> {
27+
const grpcPort = await pickPort();
28+
const grpcAddress = `127.0.0.1:${grpcPort}`;
29+
30+
const args = ['api', '--sentry-dsn', sentryDSN, '--grpc-addr', grpcAddress];
31+
const process = spawn(pomeriumCli, args);
32+
process.stdout.on('data', (data) => console.info(`${data}`));
33+
process.stderr.on('data', (data) => console.error(`${data}`));
34+
process.on('error', (error) => {
35+
Sentry.captureEvent({
36+
message: 'API process failed to start',
37+
extra: { error },
38+
});
39+
});
40+
process.on('close', (code, signal) => {
41+
if (signal != null) return;
42+
Sentry.captureEvent({
43+
message: 'API process unexpectedly quit',
44+
extra: { code },
45+
});
46+
});
47+
48+
const configClient = new ConfigClient(
49+
grpcAddress,
50+
ChannelCredentials.createInsecure()
51+
);
52+
const listenerClient = new ListenerClient(
53+
grpcAddress,
54+
ChannelCredentials.createInsecure()
55+
);
56+
57+
return { process, configClient, listenerClient };
58+
}

src/main.dev.ts

+12-34
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { app, BrowserWindow, dialog, ipcMain } from 'electron';
1313
import installExtension, { REDUX_DEVTOOLS } from 'electron-devtools-installer';
1414
import * as grpc from '@grpc/grpc-js';
1515
import * as Sentry from '@sentry/electron';
16-
import * as child_process from 'child_process';
1716
import log from 'electron-log';
1817
import { autoUpdater } from 'electron-updater';
1918
import { menubar } from 'menubar';
@@ -47,18 +46,16 @@ import {
4746
} from './shared/constants';
4847
import Helper from './trayMenu/helper';
4948
import {
50-
ConfigClient,
5149
ConnectionStatusUpdate,
5250
ExportRequest,
5351
GetTagsRequest,
5452
ImportRequest,
55-
ListenerClient,
5653
ListenerUpdateRequest,
5754
Record as ListenerRecord,
5855
Selector,
5956
StatusUpdatesRequest,
6057
} from './shared/pb/api';
61-
import { pomeriumCli } from './main/binaries';
58+
import { start } from './cli';
6259

6360
const SentryDSN =
6461
'https://[email protected]/6146413';
@@ -70,24 +67,6 @@ Sentry.init({
7067
let mainWindow: BrowserWindow | null;
7168
let updateStream: grpc.ClientReadableStream<ConnectionStatusUpdate> | undefined;
7269

73-
const cliProcess = child_process
74-
.spawn(pomeriumCli, ['api', '--sentry-dsn', SentryDSN])
75-
.on('error', (error) => {
76-
Sentry.captureEvent({
77-
message: 'API process failed to start',
78-
extra: { error },
79-
});
80-
})
81-
.on('close', (code, signal) => {
82-
if (signal != null) return;
83-
Sentry.captureEvent({
84-
message: 'API process unexpectedly quit',
85-
extra: { code },
86-
});
87-
});
88-
89-
cliProcess.stderr.on('data', (data) => console.error(data.toString()));
90-
cliProcess.stdout.on('data', (data) => console.info(data.toString()));
9170
class AppUpdater {
9271
constructor() {
9372
log.transports.file.level = 'info';
@@ -105,16 +84,6 @@ if (isDev || prodDebug) {
10584
require('electron-debug')();
10685
}
10786

108-
const configClient = new ConfigClient(
109-
'127.0.0.1:8800',
110-
grpc.ChannelCredentials.createInsecure()
111-
);
112-
113-
const listenerClient = new ListenerClient(
114-
'127.0.0.1:8800',
115-
grpc.ChannelCredentials.createInsecure()
116-
);
117-
11887
const onUncaughtException = (() => {
11988
let shuttingDown = false;
12089
return async (err: Error) => {
@@ -153,7 +122,14 @@ app.on('activate', async () => {
153122
if (mainWindow === null) mainWindow = createWindow();
154123
});
155124

156-
app.on('ready', async () => {
125+
async function init(): Promise<void> {
126+
const [cli] = await Promise.all([
127+
start(SentryDSN),
128+
new Promise((resolve) => app.on('ready', resolve)),
129+
]);
130+
const cliProcess = cli.process;
131+
const { configClient, listenerClient } = cli;
132+
157133
// Remove this if your app does not use auto updates
158134
// eslint-disable-next-line
159135
new AppUpdater();
@@ -368,4 +344,6 @@ app.on('ready', async () => {
368344
mainWindow?.close();
369345
});
370346
});
371-
});
347+
}
348+
349+
init();

0 commit comments

Comments
 (0)