import type { EndpointInfo as ProtoEndpointInfo } from '@ydbjs/api/discovery';
import type { ChannelCredentials, ChannelOptions } from 'nice-grpc';
import { type Connection } from './conn.js';
import type { DriverIdentity } from './driver-identity.js';
import type { DriverHooks, EndpointInfo } from './hooks.js';
export declare const POOL_INJECT_FOR_TESTING: unique symbol;
export declare const POOL_GET_ACTIVE_FOR_TESTING: unique symbol;
export declare const POOL_GET_RETIRED_FOR_TESTING: unique symbol;
export declare const POOL_GET_PESSIMIZED_FOR_TESTING: unique symbol;
export declare const POOL_RUN_IDLE_SWEEP_FOR_TESTING: unique symbol;
export declare const POOL_GET_LAST_ACQUIRED_FOR_TESTING: unique symbol;
export interface ConnectionPoolOptions {
    hooks?: DriverHooks | undefined;
    channelOptions?: ChannelOptions | undefined;
    channelCredentials: ChannelCredentials;
    idleTimeout: number;
    idleInterval: number;
    pessimizationTimeout: number;
    /** Stamped onto every `ydb:driver.connection.*` event so multi-driver subscribers can attribute. */
    identity: DriverIdentity;
}
export declare class ConnectionPool implements Disposable {
    #private;
    readonly options: ConnectionPoolOptions;
    constructor(options: ConnectionPoolOptions);
    get activeSize(): number;
    get retiredSize(): number;
    get pessimizedSize(): number;
    /**
     * Acquire a connection for an RPC.
     *
     * Priority order:
     *   1. Preferred node (active), if preferNodeId is given
     *   2. Round-robin over active connections
     *   3. Preferred node (pessimized) — sessions/transactions are node-bound
     *   4. Any pessimized connection — last resort when pool is fully pessimized
     *
     * Note: returning a pessimized preferred node is intentional. Sessions and
     * transactions are bound to a specific nodeId. Silently routing to a different
     * node would cause BAD_SESSION errors that are harder to diagnose than an
     * explicit transport error.
     */
    acquire(preferNodeId?: bigint): Connection;
    /**
     * Pessimize a connection — move it out of active rotation for
     * PESSIMIZATION_TIMEOUT_MS milliseconds.
     */
    pessimize(conn: Connection): void;
    /**
     * Add (or replace) an endpoint in the pool.
     *
     * If a connection with the same nodeId already exists (active or pessimized),
     * it is closed and replaced with a fresh GrpcConnection. This handles the case
     * where an endpoint disappears from discovery and later re-appears — it gets a
     * clean channel.
     */
    add(endpoint: ProtoEndpointInfo): void;
    /**
     * Atomically sync the pool with a fresh discovery endpoint list.
     *
     * Endpoints no longer present in the list are removed from routing but
     * their gRPC channels are NOT closed — existing streams (topic reader/writer,
     * coordination sessions) continue to work. Removed connections are moved to
     * the #retired list where the idle sweep will close them once grpc-js reports
     * the channel as IDLE (all streams ended).
     *
     * New endpoints are added via add(), which also handles re-appeared endpoints.
     *
     * Returns { added, removed } for the onDiscovery hook.
     */
    sync(endpoints: ProtoEndpointInfo[]): {
        added: EndpointInfo[];
        removed: EndpointInfo[];
    };
    /**
     * Check whether a nodeId is currently routable (active or pessimized).
     */
    isAvailable(nodeId: bigint): boolean;
    /**
     * Close all connections (active, pessimized, and retired) and clear the pool.
     * Stops the idle sweep timer. Called by Driver.close() / Symbol.dispose.
     */
    close(): void;
    [Symbol.dispose](): void;
    /**
     * Inject a pre-built Connection directly into the active list.
     *
     * @internal
     */
    [POOL_INJECT_FOR_TESTING](conn: Connection): void;
    /**
     * Return the active connections array (read-only view).
     *
     * @internal
     */
    [POOL_GET_ACTIVE_FOR_TESTING](): Connection[];
    /**
     * Return the pessimized Map (conn → pessimizedUntil timestamp).
     *
     * @internal
     */
    [POOL_GET_PESSIMIZED_FOR_TESTING](): Map<Connection, number>;
    /**
     * Return the retired connections list.
     *
     * @internal
     */
    [POOL_GET_RETIRED_FOR_TESTING](): Set<Connection>;
    /**
     * Return the lastAcquiredAt Map (conn → timestamp).
     *
     * @internal
     */
    [POOL_GET_LAST_ACQUIRED_FOR_TESTING](): Map<Connection, number>;
    /**
     * Run the idle sweep synchronously (same logic as the background timer).
     * Useful in tests to avoid waiting for real timers.
     *
     * @internal
     */
    [POOL_RUN_IDLE_SWEEP_FOR_TESTING](): void;
}
//# sourceMappingURL=pool.d.ts.map