All files / packages/telemetry/src/state session-pool.ts

86.95% Statements 20/23
100% Branches 2/2
84.61% Functions 11/13
86.95% Lines 20/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                              5x                               34x     20x       1x           5x               1x       1x 1x       4x       3x 3x       1x                 3x       1x 1x       14x 14x 2x 2x   14x      
import type { DriverIdentity } from '@ydbjs/core'
 
export type SessionPoolState = {
	/** Sessions registered with the pool (idle + busy). */
	total: number
	/** Sessions currently held by a `SessionLease`. */
	acquired: number
	/** In-flight `Session.open` calls. */
	creating: number
	/** Length of the wait queue. */
	waiters: number
	maxSize: number
	minSize: number
}
 
let EMPTY: SessionPoolState = {
	total: 0,
	acquired: 0,
	creating: 0,
	waiters: 0,
	maxSize: 0,
	minSize: 0,
}
 
/**
 * Per-driver state of the query session pool, rebuilt from
 * `ydb:query.session.*` events. A future table-service session pool gets
 * its own registry rather than sharing this one — the two pools have
 * independent lifecycles. Keyed by `DriverIdentity` reference.
 */
export class SessionPoolRegistry {
	#sessions = new Map<DriverIdentity, SessionPoolState>()
 
	sessions(): ReadonlyMap<DriverIdentity, SessionPoolState> {
		return this.#sessions
	}
 
	driverClosed(driver: DriverIdentity): void {
		this.#sessions.delete(driver)
	}
 
	// `pool.opened` carries the authoritative max/min snapshot, so we replace
	// any state from a prior pool generation on the same driver.
	poolOpened(driver: DriverIdentity, maxSize: number, minSize: number): void {
		this.#sessions.set(driver, { ...EMPTY, maxSize, minSize })
	}
 
	poolClosed(driver: DriverIdentity): void {
		this.#sessions.delete(driver)
	}
 
	createStarted(driver: DriverIdentity): void {
		this.#get(driver).creating += 1
	}
 
	createEnded(driver: DriverIdentity): void {
		let s = this.#get(driver)
		s.creating = Math.max(0, s.creating - 1)
	}
 
	created(driver: DriverIdentity): void {
		this.#get(driver).total += 1
	}
 
	closed(driver: DriverIdentity): void {
		let s = this.#get(driver)
		s.total = Math.max(0, s.total - 1)
	}
 
	acquired(driver: DriverIdentity): void {
		this.#get(driver).acquired += 1
	}
 
	released(driver: DriverIdentity): void {
		let s = this.#get(driver)
		s.acquired = Math.max(0, s.acquired - 1)
	}
 
	waiterEnqueued(driver: DriverIdentity): void {
		this.#get(driver).waiters += 1
	}
 
	waiterDequeued(driver: DriverIdentity): void {
		let s = this.#get(driver)
		s.waiters = Math.max(0, s.waiters - 1)
	}
 
	#get(driver: DriverIdentity): SessionPoolState {
		let s = this.#sessions.get(driver)
		if (!s) {
			s = { ...EMPTY }
			this.#sessions.set(driver, s)
		}
		return s
	}
}