From 57f1b77ddd3f090e89ecd0c4c40a264d2ffd7bcc Mon Sep 17 00:00:00 2001 From: Timothy Jones Date: Sun, 23 Mar 2025 13:26:10 +1100 Subject: [PATCH 1/3] fix(connector): Start the connector on ipv6 --- .../case-connector/src/connectors/grpc/contract-case-stream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts index bbdcacc52..ee3fb558e 100644 --- a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts +++ b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts @@ -18,7 +18,7 @@ export function main(): void { contractVerification, }); server.bindAsync( - `0.0.0.0:${freePort}`, + `[::1]:${freePort}`, ServerCredentials.createInsecure(), (error, port) => { if (error != null) { From 2e3bc1bb182d71c830eaf7c0f0decd24cf472638 Mon Sep 17 00:00:00 2001 From: Timothy Jones Date: Sun, 23 Mar 2025 13:41:47 +1100 Subject: [PATCH 2/3] fix(connector): Improve error handling when the core can't start --- .../src/connectors/grpc/contract-case-stream.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts index ee3fb558e..8ea8e1edc 100644 --- a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts +++ b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts @@ -24,7 +24,11 @@ export function main(): void { if (error != null) { // Console used here because there's nothing sensible we can do with this error // eslint-disable-next-line no-console - console.error(`[${versionString}]`, `Unable to start: ${error}`); + console.error( + `[${versionString}]`, + `ContractCase's internal server was unable to start: ${error}`, + ); + process.exit(1); } else { // This is needed to communicate with clients // Must have the port number after the `:` From 5eb1014485526baa678d2324503ed0d76700347e Mon Sep 17 00:00:00 2001 From: Timothy Jones Date: Sun, 23 Mar 2025 13:58:18 +1100 Subject: [PATCH 3/3] feat(connector): Start the service on ipv4 if ipv6 fails to bind --- .../connectors/grpc/contract-case-stream.ts | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts index 8ea8e1edc..5b6f37322 100644 --- a/packages/case-connector/src/connectors/grpc/contract-case-stream.ts +++ b/packages/case-connector/src/connectors/grpc/contract-case-stream.ts @@ -5,11 +5,36 @@ import getPort from 'get-port'; import { contractDefinition } from './contractDefinition.js'; import { contractVerification } from './contractVerification.js'; import { versionString } from '../../versionString.js'; +import { maintainerLog } from '../../domain/maintainerLog.js'; + +type ServerInfo = { port: string; address: string }; + +const bind = ( + server: Server, + host: string, + freePort: number, +): Promise => + new Promise((resolve, reject) => { + const address = `${host}:${freePort}`; + maintainerLog(`Attempting to bind server: ${address}`); + server.bindAsync( + address, + ServerCredentials.createInsecure(), + (error, port) => { + if (error != null) { + reject(error); + } else { + resolve({ port: `${port}`, address }); + } + }, + ); + }); /** * Starts a gRPC server for defining and verifying ContractCase contracts */ export function main(): void { + maintainerLog(`Starting ContractCase connector @ ${versionString}`); const server = new Server(); getPort().then((freePort) => { @@ -17,11 +42,21 @@ export function main(): void { contractDefinition, contractVerification, }); - server.bindAsync( - `[::1]:${freePort}`, - ServerCredentials.createInsecure(), - (error, port) => { - if (error != null) { + + return bind(server, '[::1]', freePort) + .catch((error) => { + maintainerLog('Server bind failed with error: ', error); + return bind(server, '127.0.0.1', freePort); + }) + .then( + ({ port, address }) => { + maintainerLog(`Successfully started server at ${address}`); + // This is needed to communicate with clients + // Must have the port number after the `:` + // eslint-disable-next-line no-console + console.log('[SERVER]', `Started on port: ${port}`); + }, + (error) => { // Console used here because there's nothing sensible we can do with this error // eslint-disable-next-line no-console console.error( @@ -29,13 +64,7 @@ export function main(): void { `ContractCase's internal server was unable to start: ${error}`, ); process.exit(1); - } else { - // This is needed to communicate with clients - // Must have the port number after the `:` - // eslint-disable-next-line no-console - console.log('[SERVER]', `Started on port: ${port}`); - } - }, - ); + }, + ); }); }