Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 29 additions & 31 deletions web/packages/teleterm/src/mainProcess/mainProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ export default class MainProcess {
)
);
private readonly agentRunner: AgentRunner;
/**
* A promise responsible for initializing clients for tshd gRPC services once the addresses of
* child processes are resolved. Set in the constructor.
*
* If the client setup fails, the resulting error will propagate to callsites which use
* tshdClients.
*/
private tshdClients: Promise<{
terminalService: TshdClient;
autoUpdateService: AutoUpdateClient;
Expand Down Expand Up @@ -168,16 +175,16 @@ export default class MainProcess {
this.setAppMenu();
this.initTshd();
this.initSharedProcess();
this.initResolvingChildProcessAddresses();
this.initResolvingChildProcessAddressesAndTshdClients();
this.initIpc();

const getClusterVersions = async () => {
const { autoUpdateService } = await this.getTshdClients();
const { autoUpdateService } = await this.tshdClients;
const { response } = await autoUpdateService.getClusterVersions({});
return response;
};
const getDownloadBaseUrl = async () => {
const { autoUpdateService } = await this.getTshdClients();
const { autoUpdateService } = await this.tshdClients;
const {
response: { baseUrl },
} = await autoUpdateService.getDownloadBaseUrl({});
Expand All @@ -198,7 +205,7 @@ export default class MainProcess {
process.env[TELEPORT_TOOLS_VERSION_ENV_VAR]
);
this.clusterStore = new ClusterStore(
() => this.getTshdClients().then(c => c.terminalService),
() => this.tshdClients.then(c => c.terminalService),
this.windowsManager
);
}
Expand All @@ -220,29 +227,6 @@ export default class MainProcess {
]);
}

/**
* Returns the tshd client.
*
* If the client setup fails, the resulting error will propagate
* to callers of this method.
*/
private async getTshdClients(): Promise<{
terminalService: TshdClient;
autoUpdateService: AutoUpdateClient;
}> {
if (!this.tshdClients) {
this.tshdClients = this.resolvedChildProcessAddresses.then(
({ tsh: tshdAddress }) =>
setUpTshdClients({
runtimeSettings: this.settings,
tshdAddress,
})
);
}

return this.tshdClients;
}

private initTshd() {
const { binaryPath, homeDir } = this.settings.tshd;
this.logger.info(`Starting tsh daemon from ${binaryPath}`);
Expand Down Expand Up @@ -343,16 +327,17 @@ export default class MainProcess {
}

/**
* Initializes the resolution of child process addresses.
* Initializes the resolution of child process addresses and sets up tshd clients.
* On Windows, the setup of tshd clients also initialized the main process cert for mTLS.
*
* Both the internal tshd client (in the main process) and the one in the renderer
* depend on this initialization promise.
*
* If the promise rejects, the error will propagate to the renderer via the IPC
* handler (causing the renderer to stop initialization and show the error)
* and also surface when attempting to access `getTshdClients()`.
* and also surface when attempting to access the tshdClients property.
*/
private initResolvingChildProcessAddresses(): void {
private initResolvingChildProcessAddressesAndTshdClients(): void {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not want to create a separate initTshdClients methods because both this.tshdClients and this.resolvedChildProcessAddresses are interlinked, so it didn't make sense to me to split them into separate methods.

this.resolvedChildProcessAddresses = Promise.all([
resolveNetworkAddress(
this.settings.tshd.requestedNetworkAddress,
Expand All @@ -379,6 +364,19 @@ export default class MainProcess {
)
),
]).then(([tsh, shared]) => ({ tsh, shared }));

this.tshdClients = this.resolvedChildProcessAddresses.then(
({ tsh: tshdAddress }) =>
setUpTshdClients({
runtimeSettings: this.settings,
tshdAddress,
})
);
// Log the error just to avoid unhandled promise rejection if setUpTshdClients fails before
// anything reads tshdClients.
this.tshdClients.catch(error => {
this.logger.error('Could not initialize tshd clients', error);
});
}

private initIpc() {
Expand Down Expand Up @@ -633,7 +631,7 @@ export default class MainProcess {
}

const [dirPath] = value.filePaths;
const { terminalService } = await this.getTshdClients();
const { terminalService } = await this.tshdClients;
await terminalService.setSharedDirectoryForDesktopSession({
desktopUri: args.desktopUri,
login: args.login,
Expand Down
Loading