UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

81 lines (71 loc) 2.73 kB
// SPDX-License-Identifier: Apache-2.0 import net from 'node:net'; import * as constants from '../../core/constants.js'; import {type SoloLogger} from '../../core/logging/solo-logger.js'; /** * Utility class for port-related operations */ export class PortUtilities { /** * Check if a TCP port is available on the local machine * @param port Port number to check * @returns Promise that resolves to true if port is available, false otherwise */ public static async isPortAvailable(port: number): Promise<boolean> { return new Promise<boolean>((resolve, reject): void => { const server: net.Server = net.createServer(); const timeout: NodeJS.Timeout = setTimeout((): void => { server.close(); reject(new Error(`Timeout while checking port ${port}`)); }, 5000); // 5-second timeout server.once('error', (error): void => { clearTimeout(timeout); if ((error as NodeJS.ErrnoException).code === 'EADDRINUSE') { // Port is in use resolve(false); } else { // Unexpected error reject(error); } }); server.once('listening', (): void => { clearTimeout(timeout); // Port is available server.close((): void => { resolve(true); }); }); server.listen(port, constants.LOCAL_HOST); }); } /** * Find an available port starting from the given port * @param startPort Port number to start checking from * @param timeoutMs Timeout in milliseconds before giving up (default: 30000) * @param logger logger for debug messages * @returns Promise that resolves to the first available port or throws an error if timeout is reached * @throws Error if no available port is found within the timeout period */ public static async findAvailablePort( startPort: number, timeoutMs: number = 30_000, logger: SoloLogger, ): Promise<number> { if (!Number.isInteger(startPort) || startPort < 1 || startPort > 65_535) { throw new Error(`Invalid startPort: ${startPort}. Must be an integer between 1 and 65535.`); } let port: number = startPort; const startTime: number = Date.now(); while (!(await this.isPortAvailable(port))) { logger.debug(`Port ${port} is not available, trying ${port + 1}`); port++; if (Date.now() - startTime > timeoutMs) { const errorMessage: string = `Failed to find an available port after ${timeoutMs}ms timeout, starting from port ${startPort}`; logger.error(errorMessage); throw new Error(errorMessage); } } return port; } } // The managePortForward function has been moved to components-data-wrapper.ts