Spaces:
Runtime error
Runtime error
Download static/node_modules/mongodb/src/sdam/server.ts from kaab4321/NarrativeFlow: direct link, hf CLI and curl.
- Browser
- Download file 16 kB
-
https://huggingface.co/spaces/kaab4321/NarrativeFlow/resolve/main/static/node_modules/mongodb/src/sdam/server.ts
- Command line
-
hf download hf://spaces/kaab4321/NarrativeFlow/static/node_modules/mongodb/src/sdam/server.ts
-
curl -L -o server.ts https://huggingface.co/spaces/kaab4321/NarrativeFlow/resolve/main/static/node_modules/mongodb/src/sdam/server.ts
16 kB
| import type { Document } from '../bson'; | |
| import { type AutoEncrypter } from '../client-side-encryption/auto_encrypter'; | |
| import { type CommandOptions, Connection } from '../cmap/connection'; | |
| import { | |
| ConnectionPool, | |
| type ConnectionPoolEvents, | |
| type ConnectionPoolOptions | |
| } from '../cmap/connection_pool'; | |
| import { PoolClearedError } from '../cmap/errors'; | |
| import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses'; | |
| import { | |
| APM_EVENTS, | |
| CLOSED, | |
| CMAP_EVENTS, | |
| CONNECT, | |
| DESCRIPTION_RECEIVED, | |
| ENDED, | |
| HEARTBEAT_EVENTS, | |
| SERVER_HEARTBEAT_FAILED, | |
| SERVER_HEARTBEAT_STARTED, | |
| SERVER_HEARTBEAT_SUCCEEDED | |
| } from '../constants'; | |
| import { | |
| type AnyError, | |
| isNetworkErrorBeforeHandshake, | |
| isNodeShuttingDownError, | |
| isSDAMUnrecoverableError, | |
| MONGODB_ERROR_CODES, | |
| MongoError, | |
| MongoErrorLabel, | |
| MongoInvalidArgumentError, | |
| MongoNetworkError, | |
| MongoNetworkTimeoutError, | |
| MongoRuntimeError, | |
| MongoServerClosedError, | |
| type MongoServerError, | |
| needsRetryableWriteLabel | |
| } from '../error'; | |
| import type { ServerApi } from '../mongo_client'; | |
| import { TypedEventEmitter } from '../mongo_types'; | |
| import type { GetMoreOptions } from '../operations/get_more'; | |
| import type { ClientSession } from '../sessions'; | |
| import { isTransactionCommand } from '../transactions'; | |
| import { | |
| type EventEmitterWithState, | |
| makeStateMachine, | |
| maxWireVersion, | |
| type MongoDBNamespace, | |
| supportsRetryableWrites | |
| } from '../utils'; | |
| import { | |
| type ClusterTime, | |
| STATE_CLOSED, | |
| STATE_CLOSING, | |
| STATE_CONNECTED, | |
| STATE_CONNECTING, | |
| TopologyType | |
| } from './common'; | |
| import type { | |
| ServerHeartbeatFailedEvent, | |
| ServerHeartbeatStartedEvent, | |
| ServerHeartbeatSucceededEvent | |
| } from './events'; | |
| import { Monitor, type MonitorOptions } from './monitor'; | |
| import { compareTopologyVersion, ServerDescription } from './server_description'; | |
| import type { Topology } from './topology'; | |
| const stateTransition = makeStateMachine({ | |
| [STATE_CLOSED]: [STATE_CLOSED, STATE_CONNECTING], | |
| [STATE_CONNECTING]: [STATE_CONNECTING, STATE_CLOSING, STATE_CONNECTED, STATE_CLOSED], | |
| [STATE_CONNECTED]: [STATE_CONNECTED, STATE_CLOSING, STATE_CLOSED], | |
| [STATE_CLOSING]: [STATE_CLOSING, STATE_CLOSED] | |
| }); | |
| /** @internal */ | |
| export type ServerOptions = Omit<ConnectionPoolOptions, 'id' | 'generation' | 'hostAddress'> & | |
| MonitorOptions; | |
| /** @internal */ | |
| export interface ServerPrivate { | |
| /** The server description for this server */ | |
| description: ServerDescription; | |
| /** A copy of the options used to construct this instance */ | |
| options: ServerOptions; | |
| /** The current state of the Server */ | |
| state: string; | |
| /** MongoDB server API version */ | |
| serverApi?: ServerApi; | |
| /** A count of the operations currently running against the server. */ | |
| operationCount: number; | |
| } | |
| /** @public */ | |
| export type ServerEvents = { | |
| serverHeartbeatStarted(event: ServerHeartbeatStartedEvent): void; | |
| serverHeartbeatSucceeded(event: ServerHeartbeatSucceededEvent): void; | |
| serverHeartbeatFailed(event: ServerHeartbeatFailedEvent): void; | |
| /** Top level MongoClient doesn't emit this so it is marked: @internal */ | |
| connect(server: Server): void; | |
| descriptionReceived(description: ServerDescription): void; | |
| closed(): void; | |
| ended(): void; | |
| } & ConnectionPoolEvents & | |
| EventEmitterWithState; | |
| /** @internal */ | |
| export class Server extends TypedEventEmitter<ServerEvents> { | |
| /** @internal */ | |
| s: ServerPrivate; | |
| /** @internal */ | |
| topology: Topology; | |
| /** @internal */ | |
| pool: ConnectionPool; | |
| serverApi?: ServerApi; | |
| hello?: Document; | |
| monitor: Monitor | null; | |
| /** @event */ | |
| static readonly SERVER_HEARTBEAT_STARTED = SERVER_HEARTBEAT_STARTED; | |
| /** @event */ | |
| static readonly SERVER_HEARTBEAT_SUCCEEDED = SERVER_HEARTBEAT_SUCCEEDED; | |
| /** @event */ | |
| static readonly SERVER_HEARTBEAT_FAILED = SERVER_HEARTBEAT_FAILED; | |
| /** @event */ | |
| static readonly CONNECT = CONNECT; | |
| /** @event */ | |
| static readonly DESCRIPTION_RECEIVED = DESCRIPTION_RECEIVED; | |
| /** @event */ | |
| static readonly CLOSED = CLOSED; | |
| /** @event */ | |
| static readonly ENDED = ENDED; | |
| /** | |
| * Create a server | |
| */ | |
| constructor(topology: Topology, description: ServerDescription, options: ServerOptions) { | |
| super(); | |
| this.serverApi = options.serverApi; | |
| const poolOptions = { hostAddress: description.hostAddress, ...options }; | |
| this.topology = topology; | |
| this.pool = new ConnectionPool(this, poolOptions); | |
| this.s = { | |
| description, | |
| options, | |
| state: STATE_CLOSED, | |
| operationCount: 0 | |
| }; | |
| for (const event of [...CMAP_EVENTS, ...APM_EVENTS]) { | |
| this.pool.on(event, (e: any) => this.emit(event, e)); | |
| } | |
| this.pool.on(Connection.CLUSTER_TIME_RECEIVED, (clusterTime: ClusterTime) => { | |
| this.clusterTime = clusterTime; | |
| }); | |
| if (this.loadBalanced) { | |
| this.monitor = null; | |
| // monitoring is disabled in load balancing mode | |
| return; | |
| } | |
| // create the monitor | |
| this.monitor = new Monitor(this, this.s.options); | |
| for (const event of HEARTBEAT_EVENTS) { | |
| this.monitor.on(event, (e: any) => this.emit(event, e)); | |
| } | |
| this.monitor.on('resetServer', (error: MongoServerError) => markServerUnknown(this, error)); | |
| this.monitor.on(Server.SERVER_HEARTBEAT_SUCCEEDED, (event: ServerHeartbeatSucceededEvent) => { | |
| this.emit( | |
| Server.DESCRIPTION_RECEIVED, | |
| new ServerDescription(this.description.hostAddress, event.reply, { | |
| roundTripTime: this.monitor?.roundTripTime, | |
| minRoundTripTime: this.monitor?.minRoundTripTime | |
| }) | |
| ); | |
| if (this.s.state === STATE_CONNECTING) { | |
| stateTransition(this, STATE_CONNECTED); | |
| this.emit(Server.CONNECT, this); | |
| } | |
| }); | |
| } | |
| get clusterTime(): ClusterTime | undefined { | |
| return this.topology.clusterTime; | |
| } | |
| set clusterTime(clusterTime: ClusterTime | undefined) { | |
| this.topology.clusterTime = clusterTime; | |
| } | |
| get description(): ServerDescription { | |
| return this.s.description; | |
| } | |
| get name(): string { | |
| return this.s.description.address; | |
| } | |
| get autoEncrypter(): AutoEncrypter | undefined { | |
| if (this.s.options && this.s.options.autoEncrypter) { | |
| return this.s.options.autoEncrypter; | |
| } | |
| return; | |
| } | |
| get loadBalanced(): boolean { | |
| return this.topology.description.type === TopologyType.LoadBalanced; | |
| } | |
| /** | |
| * Initiate server connect | |
| */ | |
| connect(): void { | |
| if (this.s.state !== STATE_CLOSED) { | |
| return; | |
| } | |
| stateTransition(this, STATE_CONNECTING); | |
| // If in load balancer mode we automatically set the server to | |
| // a load balancer. It never transitions out of this state and | |
| // has no monitor. | |
| if (!this.loadBalanced) { | |
| this.monitor?.connect(); | |
| } else { | |
| stateTransition(this, STATE_CONNECTED); | |
| this.emit(Server.CONNECT, this); | |
| } | |
| } | |
| /** Destroy the server connection */ | |
| destroy(): void { | |
| if (this.s.state === STATE_CLOSED) { | |
| return; | |
| } | |
| stateTransition(this, STATE_CLOSING); | |
| if (!this.loadBalanced) { | |
| this.monitor?.close(); | |
| } | |
| this.pool.close(); | |
| stateTransition(this, STATE_CLOSED); | |
| this.emit('closed'); | |
| } | |
| /** | |
| * Immediately schedule monitoring of this server. If there already an attempt being made | |
| * this will be a no-op. | |
| */ | |
| requestCheck(): void { | |
| if (!this.loadBalanced) { | |
| this.monitor?.requestCheck(); | |
| } | |
| } | |
| public async command<T extends MongoDBResponseConstructor>( | |
| ns: MongoDBNamespace, | |
| command: Document, | |
| options: CommandOptions | undefined, | |
| responseType: T | undefined | |
| ): Promise<typeof responseType extends undefined ? Document : InstanceType<T>>; | |
| public async command( | |
| ns: MongoDBNamespace, | |
| command: Document, | |
| options?: CommandOptions | |
| ): Promise<Document>; | |
| public async command( | |
| ns: MongoDBNamespace, | |
| cmd: Document, | |
| options: CommandOptions, | |
| responseType?: MongoDBResponseConstructor | |
| ): Promise<Document> { | |
| if (ns.db == null || typeof ns === 'string') { | |
| throw new MongoInvalidArgumentError('Namespace must not be a string'); | |
| } | |
| if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) { | |
| throw new MongoServerClosedError(); | |
| } | |
| // Clone the options | |
| const finalOptions = Object.assign({}, options, { | |
| wireProtocolCommand: false, | |
| directConnection: this.topology.s.options.directConnection | |
| }); | |
| // There are cases where we need to flag the read preference not to get sent in | |
| // the command, such as pre-5.0 servers attempting to perform an aggregate write | |
| // with a non-primary read preference. In this case the effective read preference | |
| // (primary) is not the same as the provided and must be removed completely. | |
| if (finalOptions.omitReadPreference) { | |
| delete finalOptions.readPreference; | |
| } | |
| const session = finalOptions.session; | |
| let conn = session?.pinnedConnection; | |
| this.incrementOperationCount(); | |
| if (conn == null) { | |
| try { | |
| conn = await this.pool.checkOut(); | |
| if (this.loadBalanced && isPinnableCommand(cmd, session)) { | |
| session?.pin(conn); | |
| } | |
| } catch (checkoutError) { | |
| this.decrementOperationCount(); | |
| if (!(checkoutError instanceof PoolClearedError)) this.handleError(checkoutError); | |
| throw checkoutError; | |
| } | |
| } | |
| try { | |
| try { | |
| return await conn.command(ns, cmd, finalOptions, responseType); | |
| } catch (commandError) { | |
| throw this.decorateCommandError(conn, cmd, finalOptions, commandError); | |
| } | |
| } catch (operationError) { | |
| if ( | |
| operationError instanceof MongoError && | |
| operationError.code === MONGODB_ERROR_CODES.Reauthenticate | |
| ) { | |
| await this.pool.reauthenticate(conn); | |
| try { | |
| return await conn.command(ns, cmd, finalOptions, responseType); | |
| } catch (commandError) { | |
| throw this.decorateCommandError(conn, cmd, finalOptions, commandError); | |
| } | |
| } else { | |
| throw operationError; | |
| } | |
| } finally { | |
| this.decrementOperationCount(); | |
| if (session?.pinnedConnection !== conn) { | |
| this.pool.checkIn(conn); | |
| } | |
| } | |
| } | |
| /** | |
| * Handle SDAM error | |
| * @internal | |
| */ | |
| handleError(error: AnyError, connection?: Connection) { | |
| if (!(error instanceof MongoError)) { | |
| return; | |
| } | |
| const isStaleError = | |
| error.connectionGeneration && error.connectionGeneration < this.pool.generation; | |
| if (isStaleError) { | |
| return; | |
| } | |
| const isNetworkNonTimeoutError = | |
| error instanceof MongoNetworkError && !(error instanceof MongoNetworkTimeoutError); | |
| const isNetworkTimeoutBeforeHandshakeError = isNetworkErrorBeforeHandshake(error); | |
| const isAuthHandshakeError = error.hasErrorLabel(MongoErrorLabel.HandshakeError); | |
| if (isNetworkNonTimeoutError || isNetworkTimeoutBeforeHandshakeError || isAuthHandshakeError) { | |
| // In load balanced mode we never mark the server as unknown and always | |
| // clear for the specific service id. | |
| if (!this.loadBalanced) { | |
| error.addErrorLabel(MongoErrorLabel.ResetPool); | |
| markServerUnknown(this, error); | |
| } else if (connection) { | |
| this.pool.clear({ serviceId: connection.serviceId }); | |
| } | |
| } else { | |
| if (isSDAMUnrecoverableError(error)) { | |
| if (shouldHandleStateChangeError(this, error)) { | |
| const shouldClearPool = maxWireVersion(this) <= 7 || isNodeShuttingDownError(error); | |
| if (this.loadBalanced && connection && shouldClearPool) { | |
| this.pool.clear({ serviceId: connection.serviceId }); | |
| } | |
| if (!this.loadBalanced) { | |
| if (shouldClearPool) { | |
| error.addErrorLabel(MongoErrorLabel.ResetPool); | |
| } | |
| markServerUnknown(this, error); | |
| process.nextTick(() => this.requestCheck()); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Ensure that error is properly decorated and internal state is updated before throwing | |
| * @internal | |
| */ | |
| private decorateCommandError( | |
| connection: Connection, | |
| cmd: Document, | |
| options: CommandOptions | GetMoreOptions | undefined, | |
| error: unknown | |
| ): Error { | |
| if (typeof error !== 'object' || error == null || !('name' in error)) { | |
| throw new MongoRuntimeError('An unexpected error type: ' + typeof error); | |
| } | |
| if (error.name === 'AbortError' && 'cause' in error && error.cause instanceof MongoError) { | |
| error = error.cause; | |
| } | |
| if (!(error instanceof MongoError)) { | |
| // Node.js or some other error we have not special handling for | |
| return error as Error; | |
| } | |
| if (connectionIsStale(this.pool, connection)) { | |
| return error; | |
| } | |
| const session = options?.session; | |
| if (error instanceof MongoNetworkError) { | |
| if (session && !session.hasEnded && session.serverSession) { | |
| session.serverSession.isDirty = true; | |
| } | |
| // inActiveTransaction check handles commit and abort. | |
| if ( | |
| inActiveTransaction(session, cmd) && | |
| !error.hasErrorLabel(MongoErrorLabel.TransientTransactionError) | |
| ) { | |
| error.addErrorLabel(MongoErrorLabel.TransientTransactionError); | |
| } | |
| if ( | |
| (isRetryableWritesEnabled(this.topology) || isTransactionCommand(cmd)) && | |
| supportsRetryableWrites(this) && | |
| !inActiveTransaction(session, cmd) | |
| ) { | |
| error.addErrorLabel(MongoErrorLabel.RetryableWriteError); | |
| } | |
| } else { | |
| if ( | |
| (isRetryableWritesEnabled(this.topology) || isTransactionCommand(cmd)) && | |
| needsRetryableWriteLabel(error, maxWireVersion(this)) && | |
| !inActiveTransaction(session, cmd) | |
| ) { | |
| error.addErrorLabel(MongoErrorLabel.RetryableWriteError); | |
| } | |
| } | |
| if ( | |
| session && | |
| session.isPinned && | |
| error.hasErrorLabel(MongoErrorLabel.TransientTransactionError) | |
| ) { | |
| session.unpin({ force: true }); | |
| } | |
| this.handleError(error, connection); | |
| return error; | |
| } | |
| /** | |
| * Decrement the operation count, returning the new count. | |
| */ | |
| private decrementOperationCount(): number { | |
| return (this.s.operationCount -= 1); | |
| } | |
| /** | |
| * Increment the operation count, returning the new count. | |
| */ | |
| private incrementOperationCount(): number { | |
| return (this.s.operationCount += 1); | |
| } | |
| } | |
| function markServerUnknown(server: Server, error?: MongoError) { | |
| // Load balancer servers can never be marked unknown. | |
| if (server.loadBalanced) { | |
| return; | |
| } | |
| if (error instanceof MongoNetworkError && !(error instanceof MongoNetworkTimeoutError)) { | |
| server.monitor?.reset(); | |
| } | |
| server.emit( | |
| Server.DESCRIPTION_RECEIVED, | |
| new ServerDescription(server.description.hostAddress, undefined, { error }) | |
| ); | |
| } | |
| function isPinnableCommand(cmd: Document, session?: ClientSession): boolean { | |
| if (session) { | |
| return ( | |
| session.inTransaction() || | |
| (session.transaction.isCommitted && 'commitTransaction' in cmd) || | |
| 'aggregate' in cmd || | |
| 'find' in cmd || | |
| 'getMore' in cmd || | |
| 'listCollections' in cmd || | |
| 'listIndexes' in cmd | |
| ); | |
| } | |
| return false; | |
| } | |
| function connectionIsStale(pool: ConnectionPool, connection: Connection) { | |
| if (connection.serviceId) { | |
| return ( | |
| connection.generation !== pool.serviceGenerations.get(connection.serviceId.toHexString()) | |
| ); | |
| } | |
| return connection.generation !== pool.generation; | |
| } | |
| function shouldHandleStateChangeError(server: Server, err: MongoError) { | |
| const etv = err.topologyVersion; | |
| const stv = server.description.topologyVersion; | |
| return compareTopologyVersion(stv, etv) < 0; | |
| } | |
| function inActiveTransaction(session: ClientSession | undefined, cmd: Document) { | |
| return session && session.inTransaction() && !isTransactionCommand(cmd); | |
| } | |
| /** this checks the retryWrites option passed down from the client options, it | |
| * does not check if the server supports retryable writes */ | |
| function isRetryableWritesEnabled(topology: Topology) { | |
| return topology.s.options.retryWrites !== false; | |
| } | |