@iprokit/service
Version:
Powering distributed systems with simplicity and speed.
225 lines (224 loc) • 7.95 kB
TypeScript
/**
* @iProKit/Service
* Copyright (c) 2019-2025 Rutvik Katuri / iProTechs
* SPDX-License-Identifier: Apache-2.0
*/
/// <reference types="node" />
import { EventEmitter } from 'events';
import { Mode, Parameters } from './rfi';
import Protocol, { Incoming, Outgoing } from './protocol';
import Coordinator from './coordinator';
declare const pool: unique symbol;
/**
* `Client` manages connections to an SCP server.
* Once connected, it subscribes to receive broadcasts and handles the executions.
*
* @emits `connect` when the connection is successfully established.
* @emits `<operation>` when a broadcast is received.
* @emits `pool:create` when a new socket is created and added to the connection pool.
* @emits `pool:acquire` when a socket is acquired from the connection pool.
* @emits `pool:drain` when all sockets(message) are removed from the connection pool.
* @emits `error` when an error occurs.
* @emits `close` when all the connections are closed.
*/
export default class Client extends EventEmitter {
#private;
/**
* Unique identifier of the client.
*/
readonly identifier: string;
/**
* Socket connection pool.
*/
private readonly [pool];
/**
* Creates an instance of SCP `Client`.
*
* @param identifier unique identifier of the client.
* @param options options of the client.
*/
constructor(identifier: string, options?: Options);
/**
* Remote port of the client.
*/
get remotePort(): number | null;
/**
* Remote address of the client.
*/
get remoteAddress(): string | null;
/**
* `true` when all sockets in the pool are connected, `false` otherwise.
*/
get connected(): boolean;
/**
* Returns the current state of the connection pool.
*/
get pool(): {
size: number;
busy: number;
idle: number;
};
/**
* Subscribes to the server to receive broadcasts.
*/
private subscribe;
/**
* Process the `Incoming` broadcast stream.
*
* @emits `<operation>` when a broadcast is received.
*/
private onBroadcast;
/**
* Sends a message to the server and returns a promise resolving to a reply.
*
* @param operation operation pattern.
* @param args arguments to send.
*/
message<Returned>(operation: string, ...args: Array<any>): Promise<Returned>;
/**
* Sends a message to the server and returns a promise that resolves to `void`, enabling the coordination of signals.
*
* @param operation operation pattern.
* @param coordinator coordinator that coordinates signals.
* @param args arguments to send.
*/
conduct(operation: string, coordinator: Coordinator, ...args: Array<any>): Promise<void>;
/**
* Creates and returns a new `Incoming` and `Outgoing` stream.
*
* @param mode mode of the remote function.
* @param operation operation of the remote function.
* @param parameters optional parameters of the remote function.
* @param socket optional socket to use. If not provided, a socket will be acquired from the connection pool.
*/
IO(mode: Mode, operation: string, parameters?: Parameters, socket?: Socket): Promise<{
outgoing: Outgoing;
incoming: Incoming;
}>;
/**
* Returns the least busy and available socket from the connection pool.
*
* @emits `pool:acquire` when a socket is acquired from the connection pool.
*/
private acquireSocket;
/**
* Creates and initializes a new connected socket, then adds it to the connection pool.
*
* @param options options of the socket.
* @param port remote port.
* @param host remote host.
* @emits `pool:create` when a new socket is created and added to the connection pool.
* @emits `pool:drain` when all sockets(message) are removed from the connection pool.
* @emits `error` when an error occurs.
* @emits `close` when all the connections are closed.
*/
private createSocket;
/**
* Initiates a connection to the server.
*
* @param port remote port.
* @param host remote host.
* @param callback optional callback added as a one-time listener for the `connect` event.
*/
connect(port: number, host: string, callback?: () => void): this;
/**
* Closes all connections to the server.
*
* @param callback optional callback added as a one-time listener for the `close` event.
*/
close(callback?: () => void): this;
}
export interface Options {
/**
* Maximum number of sockets that can exist in the connection pool.
* When the limit is reached, no new sockets will be created. Instead,
* existing sockets' I/O queue will be used to handle new messages,
* leveraging their FIFO mechanism to ensure proper message ordering.
*
* @default 10
*/
maxPoolSize?: number;
/**
* Maximum number of messages that a single socket can process before it is closed.
* A new socket will be created for further messages.
*
* @default 100
*/
maxMessages?: number;
/**
* Maximum amount of time (in milliseconds) that a socket can remain idle before it is closed.
* The timer resets on activity. If set to `0`, the idle timeout is disabled,
* allowing the socket to remain open indefinitely unless explicitly closed.
*
* @default 0
*/
idleTimeout?: number;
}
/**
* Represents a socket connection used by the SCP `Client`.
*
* @emits `connect` when a connection is successfully established.
* @emits `<mode>` when a new incoming stream is received.
* @emits `io:drain` when all callbacks in the I/O queue are executed.
*/
export declare class Socket extends Protocol {
#private;
/**
* Creates an instance of SCP `Socket`.
*
* @param options options of the socket.
*/
constructor(options: SocketOptions);
/**
* `true` when the socket is connected, `false` otherwise.
*/
get connected(): boolean;
/**
* Number of I/O streams queued to process.
*/
get ioQueue(): number;
/**
* Creates a new `Incoming` and `Outgoing` stream.
*
* @param mode mode of the remote function.
* @param operation operation of the remote function.
* @param parameters parameters of the remote function.
* @param callback callback executed when the I/O stream is ready.
*/
createIO(mode: Mode, operation: string, parameters: Parameters, callback: (outgoing: Outgoing, incoming: Incoming) => void): this;
/**
* Executes one I/O callback at a time in FIFO manner.
* Invoked recursively on the `close` event of the current incoming stream.
*
* @emits `io:drain` when all callbacks in the I/O queue are executed.
*/
private executeIO;
/**
* Creates a new `Incoming` stream.
* Invoked recursively on the `close` event of the current incoming stream to continuously listen for incoming streams.
*
* @emits `<mode>` when a new incoming stream is received.
*/
cycleIncoming(): this;
/**
* Initiates a connection to the server.
*
* @param port remote port.
* @param host remote host.
* @param callback optional callback added as a one-time listener for the `connect` event.
*/
connect(port: number, host: string, callback?: () => void): this;
}
export interface SocketOptions {
/**
* Maximum number of messages this socket can process before it is closed.
*/
maxMessages: number;
/**
* Maximum amount of time (in milliseconds) that this socket can remain idle before it is closed.
* The timer resets on activity. If set to `0`, the idle timeout is disabled,
* allowing the socket to remain open indefinitely unless explicitly closed.
*/
idleTimeout: number;
}
export {};