@google-cloud/spanner
Version:
Cloud Spanner Client Library for Node.js
472 lines (471 loc) • 14.1 kB
TypeScript
/*!
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from 'events';
import PQueue from 'p-queue';
import { Database } from './database';
import { Session } from './session';
import { Transaction } from './transaction';
import { NormalCallback } from './common';
import { GoogleError, grpc } from 'google-gax';
import trace = require('stack-trace');
import { ObservabilityOptions } from './instrument';
import { GetSessionCallback } from './session-factory';
/**
* @callback SessionPoolCloseCallback
* @param {?Error} error Closing error, if any.
*/
export interface SessionPoolCloseCallback {
(error?: SessionLeakError): void;
}
/** @deprecated. Use GetSessionCallback instead. */
export type GetReadSessionCallback = NormalCallback<Session>;
/** @deprecated. Use GetSessionCallback instead. */
export interface GetWriteSessionCallback {
(err: Error | null, session?: Session | null, transaction?: Transaction | null): void;
}
/**
* Interface for implementing custom session pooling logic, it should extend the
* {@link https://nodejs.org/api/events.html|EventEmitter} class and emit any
* asynchronous errors via an error event.
*
* @interface SessionPoolInterface
* @extends external:{@link https://nodejs.org/api/events.html|EventEmitter}
*/
/**
* @constructs SessionPoolInterface
* @param {Database} database The database to create a pool for.
*/
export interface SessionPoolInterface extends EventEmitter {
/**
* Will be called via {@link Database#close}. Indicates that the pool should
* perform any necessary teardown actions to its resources.
*
* @name SessionPoolInterface#close
* @param {SessionPoolCloseCallback} callback The callback function.
*/
/**
* Will be called by the Database object, should be used to start creating
* sessions/etc.
*
* @name SessionPoolInterface#open
*/
/**
* When called returns a session.
*
* @name SessionPoolInterface#getSession
* @param {GetSessionCallback} callback The callback function.
*/
/**
* When called returns a session.
*
* @deprecated Use getSession instead.
* @name SessionPoolInterface#getReadSession
* @param {GetReadSessionCallback} callback The callback function.
*/
/**
* When called returns a session.
*
* @deprecated Use getSession instead.
* @name SessionPoolInterface#getWriteSession
* @param {GetWriteSessionCallback} callback The callback function.
*/
/**
* To be called when releasing a session back into the pool.
*
* @name SessionPoolInterface#release
* @param {Session} session The session to be released.
*/
close(callback: SessionPoolCloseCallback): void;
open(): void;
getSession(callback: GetSessionCallback): void;
getReadSession(callback: GetReadSessionCallback): void;
getWriteSession(callback: GetWriteSessionCallback): void;
release(session: Session): void;
}
/**
* Session pool configuration options.
*
* @typedef {object} SessionPoolOptions
* @property {number} [acquireTimeout=Infinity] Time in milliseconds before
* giving up trying to acquire a session. If the specified value is
* `Infinity`, a timeout will not occur.
* @property {number} [concurrency=Infinity] How many concurrent requests the pool is
* allowed to make.
* @property {boolean} [fail=false] If set to true, an error will be thrown when
* there are no available sessions for a request.
* @property {number} [idlesAfter=10] How long until a resource becomes idle, in
* minutes.
* @property {number} [keepAlive=30] How often to ping idle sessions, in
* minutes. Must be less than 1 hour.
* @property {Object<string, string>} [labels] Labels to apply to any session
* created by the pool.
* @property {number} [max=100] Maximum number of resources to create at any
* given time.
* @property {number} [maxIdle=1] Maximum number of idle resources to keep in
* the pool at any given time.
* @property {number} [min=25] Minimum number of resources to keep in the pool at
* any given time.
* @property {number} [writes=0.0]. Deprecated.
* @property {number} [incStep=25] The number of new sessions to create when at
* least one more session is needed.
*/
export interface SessionPoolOptions {
acquireTimeout?: number;
concurrency?: number;
fail?: boolean;
idlesAfter?: number;
keepAlive?: number;
labels?: {
[label: string]: string;
};
max?: number;
maxIdle?: number;
min?: number;
/**
* @deprecated. Starting from v6.5.0 the same session can be reused for
* different types of transactions.
*/
writes?: number;
incStep?: number;
databaseRole?: string | null;
}
/**
* Error to be thrown when attempting to release unknown resources.
*
* @private
*/
export declare class ReleaseError extends GoogleError {
resource: unknown;
constructor(resource: unknown);
}
/**
* Error to be thrown when session leaks are detected.
*
* @private
*/
export declare class SessionLeakError extends GoogleError {
messages: string[];
constructor(leaks: string[]);
}
/**
* Error to be thrown when the session pool is exhausted.
*/
export declare class SessionPoolExhaustedError extends GoogleError {
messages: string[];
constructor(leaks: string[]);
}
/**
* Checks whether the given error is a 'Session not found' error.
* @param error the error to check
* @return true if the error is a 'Session not found' error, and otherwise false.
*/
export declare function isSessionNotFoundError(error: grpc.ServiceError | undefined): boolean;
interface SessionInventory {
sessions: Session[];
borrowed: Set<Session>;
}
/** @deprecated. */
export interface CreateSessionsOptions {
writes?: number;
reads?: number;
}
/**
* Class used to manage connections to Spanner.
*
* **You don't need to use this class directly, connections will be handled for
* you.**
*
* @class
* @extends {EventEmitter}
*/
export declare class SessionPool extends EventEmitter implements SessionPoolInterface {
database: Database;
isOpen: boolean;
options: SessionPoolOptions;
_acquires: PQueue;
_evictHandle: NodeJS.Timer;
_inventory: SessionInventory;
_onClose: Promise<void>;
_pending: number;
_waiters: number;
_pingHandle: NodeJS.Timer;
_requests: PQueue;
_traces: Map<string, trace.StackFrame[]>;
_observabilityOptions?: ObservabilityOptions;
/**
* Formats stack trace objects into Node-like stack trace.
*
* @param {object[]} trace The trace object.
* @return {string}
*/
static formatTrace(frames: trace.StackFrame[]): string;
/**
* Total number of available sessions.
* @type {number}
*/
get available(): number;
/** @deprecated Starting from v6.5.0 the same session can be reused for
* different types of transactions.
*/
get currentWriteFraction(): number;
/**
* Total number of borrowed sessions.
* @type {number}
*/
get borrowed(): number;
/**
* Flag to determine if Pool is full.
* @type {boolean}
*/
get isFull(): boolean;
/** @deprecated Use `size()` instead. */
get reads(): number;
/**
* Total size of pool.
* @type {number}
*/
get size(): number;
/** @deprecated Use `size()` instead. */
get writes(): number;
/** @deprecated Starting v6.5.0 the pending prepare state is obsolete. */
get pendingPrepare(): number;
/**
* Number of sessions being created or prepared for a read/write transaction.
* @type {number}
*/
get totalPending(): number;
/** @deprecated Use totalWaiters instead. */
get numReadWaiters(): number;
/** @deprecated Use totalWaiters instead. */
get numWriteWaiters(): number;
/**
* Sum of read and write waiters.
* @type {number}
*/
get totalWaiters(): number;
/**
* @constructor
* @param {Database} database The DB instance.
* @param {SessionPoolOptions} [options] Configuration options.
*/
constructor(database: Database, options?: SessionPoolOptions);
/**
* Closes and the pool.
*
* @emits SessionPool#close
* @param {SessionPoolCloseCallback} callback The callback function.
*/
close(callback: SessionPoolCloseCallback): void;
/**
* Retrieve a read session.
*
* @deprecated Use getSession instead.
* @param {GetReadSessionCallback} callback The callback function.
*/
getReadSession(callback: GetReadSessionCallback): void;
/**
* Retrieve a read/write session.
*
* @deprecated use getSession instead.
* @param {GetWriteSessionCallback} callback The callback function.
*/
getWriteSession(callback: GetWriteSessionCallback): void;
/**
* Retrieve a session.
*
* @param {GetSessionCallback} callback The callback function.
*/
getSession(callback: GetSessionCallback): void;
/**
* Opens the pool, filling it to the configured number of read and write
* sessions.
*
* @emits SessionPool#open
* @return {Promise}
*/
open(): void;
/**
* Releases session back into the pool.
*
* @throws {Error} For unknown sessions.
* @emits SessionPool#available
* @emits SessionPool#error
* @fires SessionPool#session-available
* @fires @deprecated SessionPool#readonly-available
* @fires @deprecated SessionPool#readwrite-available
* @param {Session} session The session to release.
*/
release(session: Session): void;
/**
* Attempts to borrow a session from the pool.
*
* @private
*
* @returns {Promise<Session>}
*/
_acquire(): Promise<Session>;
/**
* Moves a session into the borrowed group.
*
* @private
*
* @param {Session} session The session object.
*/
_borrow(session: Session): void;
/**
* Borrows the first session from the inventory.
*
* @private
*
* @return {Session}
*/
_borrowFrom(): Session;
/**
* Grabs the next available session.
*
* @private
*
* @returns {Promise<Session>}
*/
_borrowNextAvailableSession(): Session;
/**
* Attempts to create a single session.
*
* @private
*
* @returns {Promise}
*/
_createSession(): Promise<void>;
/**
* Batch creates sessions.
*
* @private
*
* @param {number} [amount] Config specifying how many sessions to create.
* @returns {Promise}
* @emits SessionPool#createError
*/
_createSessions(amount: number): Promise<void>;
/**
* Attempts to delete a session, optionally creating a new one of the same
* type if the pool is still open and we're under the configured min value.
*
* @private
*
* @fires SessionPool#error
* @param {Session} session The session to delete.
* @returns {Promise}
*/
_destroy(session: Session): Promise<void>;
/**
* Deletes idle sessions that exceed the maxIdle configuration.
*
* @private
*/
_evictIdleSessions(): void;
/**
* Fills the pool with the minimum number of sessions.
*
* @return {Promise}
*/
_fill(): Promise<void>;
/**
* Retrieves a list of all the idle sessions.
*
* @private
*
* @returns {Session[]}
*/
_getIdleSessions(): Session[];
/**
* Returns stack traces for sessions that have not been released.
*
* @return {string[]}
*/
_getLeaks(): string[];
/**
* Returns true if the pool has a usable session.
* @private
*/
_hasSessionUsableFor(): boolean;
/**
* Attempts to get a session.
*
* @private
*
* @param {number} startTime Timestamp to use when determining timeouts.
* @returns {Promise<Session>}
*/
_getSession(startTime: number): Promise<Session>;
/**
* Checks to see whether or not session is expired.
*
* @param {Session} session The session to check.
* @returns {boolean}
*/
_isValidSession(session: Session): boolean;
/**
* Pings an individual session.
*
* @private
*
* @param {Session} session The session to ping.
* @returns {Promise}
*/
_ping(session: Session): Promise<void>;
/**
* Makes a keep alive request to all the idle sessions.
*
* @private
*
* @returns {Promise}
*/
_pingIdleSessions(): Promise<void>;
/**
* Creates a transaction for a session.
*
* @private
*
* @param {Session} session The session object.
* @param {object} options The transaction options.
*/
_prepareTransaction(session: Session): void;
/**
* Releases a session back into the pool.
*
* @private
*
* @fires SessionPool#available
* @fires SessionPool#session-available
* @fires @deprecated SessionPool#readonly-available
* @fires @deprecated SessionPool#readwrite-available
* @param {Session} session The session object.
*/
_release(session: Session): void;
/**
* Starts housekeeping (pinging/evicting) of idle sessions.
*
* @private
*/
_startHouseKeeping(): void;
/**
* Stops housekeeping.
*
* @private
*/
_stopHouseKeeping(): void;
}
export {};