UNPKG

ydb-sdk

Version:

Node.js bindings for working with YDB API over gRPC

115 lines (114 loc) 5.14 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryClient = void 0; const events_1 = __importDefault(require("events")); const table_1 = require("../table"); const query_session_pool_1 = require("./query-session-pool"); const symbols_1 = require("./symbols"); const errors_1 = require("../errors"); const context_1 = require("../context"); const symbols_2 = require("../retries/symbols"); /** * YDB Query Service client. * * # Experimental * * Notice: This API is EXPERIMENTAL and may be changed or removed in a later release. */ class QueryClient extends events_1.default { constructor(settings) { super(); this.retrier = settings.retrier; this.pool = new query_session_pool_1.QuerySessionPool(settings); this.logger = settings.logger; } async destroy() { await this.pool.destroy(); } async do(opts) { return opts.ctx.wrap({ timeout: opts.timeout }, async (ctx) => { return this.retrier.retry(ctx, async (_ctx) => { var _a; const session = await this.pool.acquire(); session[symbols_1.ctxSymbol] = ctx; if (opts.hasOwnProperty('idempotent')) { session[symbols_1.isIdempotentDoLevelSymbol] = true; session[symbols_1.isIdempotentSymbol] = opts.idempotent; } if (opts.hasOwnProperty('onTrailer')) { session[symbols_1.sessionTrailerCallbackSymbol] = opts.onTrailer; } let error; try { if (opts.txSettings) session[symbols_1.sessionTxSettingsSymbol] = opts.txSettings; let res; try { res = await opts.fn(session); } catch (err) { if (err instanceof errors_1.YdbError) { delete session[symbols_1.sessionTxIdSymbol]; } throw err; } if (session[symbols_1.sessionTxIdSymbol]) { // there is an open transaction within session if (opts.txSettings) { // likely doTx was called and user expects have the transaction being commited await session[symbols_1.sessionCommitTransactionSymbol](); } else { // likely do() was called and user intentionally haven't closed transaction await session[symbols_1.sessionRollbackTransactionSymbol](); } } return { result: res }; } catch (err) { error = err; return { err: error, idempotent: session[symbols_1.isIdempotentSymbol] }; } finally { delete session[symbols_1.ctxSymbol]; delete session[symbols_1.sessionTxSettingsSymbol]; delete session[symbols_1.sessionCurrentOperationSymbol]; delete session[symbols_1.isIdempotentDoLevelSymbol]; delete session[symbols_1.isIdempotentSymbol]; delete session[symbols_1.sessionTrailerCallbackSymbol]; // @ts-ignore if (error && ((_a = error[symbols_2.RetryPolicySymbol]) === null || _a === void 0 ? void 0 : _a.deleteSession)) { this.logger.debug('Encountered bad or busy session, re-creating the session'); session.emit(query_session_pool_1.SessionEvent.SESSION_BROKEN); } else { session[symbols_1.sessionReleaseSymbol](); } } }); }); } doTx(opts) { if (!opts.txSettings) { opts = Object.assign(Object.assign({}, opts), { txSettings: table_1.AUTO_TX.beginTx }); } return this.do(opts); } } exports.QueryClient = QueryClient; __decorate([ (0, context_1.ensureContext)() ], QueryClient.prototype, "do", null); __decorate([ (0, context_1.ensureContext)() ], QueryClient.prototype, "doTx", null);