UNPKG

couchbase

Version:

The official Couchbase Node.js Client Library.

176 lines (175 loc) 7.14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAttributesForHttpOpType = exports.getAttributesForKeyValueOpType = exports.timeInputToHiResTime = exports.getCoreSpanEndTime = exports.getLatestTime = exports.millisToHiResTime = exports.getHiResTimeDelta = exports.hiResTimeToMicros = exports.getEpochHiResTime = void 0; const binding_1 = __importDefault(require("./binding")); const observabilitytypes_1 = require("./observabilitytypes"); // Define standard time constants const MILLIS_PER_SECOND = 1000; const NANOS_PER_SECOND = 1000000000; const MICROS_PER_SECOND = 1000000; const NANOS_PER_MILLI = 1000000; // Take a snapshot the moment the SDK loads const TIME_ORIGIN_MS = Date.now(); const HRTIME_ORIGIN = process.hrtime(); // Convert the absolute origin into [seconds, nanoseconds] const ORIGIN_SECONDS = Math.floor(TIME_ORIGIN_MS / MILLIS_PER_SECOND); const ORIGIN_NANOS = (TIME_ORIGIN_MS % MILLIS_PER_SECOND) * NANOS_PER_MILLI; /** * Generates an absolute Unix epoch time with nanosecond precision. * @internal */ function getEpochHiResTime() { // Get the current monotonic time const nowHrTime = process.hrtime(); // Calculate exactly how much time has passed since our anchor snapshot const [deltaSeconds, deltaNanos] = getHiResTimeDelta(HRTIME_ORIGIN, nowHrTime); // Add the high-res delta to our absolute epoch anchor let epochSeconds = ORIGIN_SECONDS + deltaSeconds; let epochNanos = ORIGIN_NANOS + deltaNanos; // Handle nanosecond overflow (if nanos exceed 1 second, carry it over) if (epochNanos >= NANOS_PER_SECOND) { epochSeconds += 1; epochNanos -= NANOS_PER_SECOND; } return [epochSeconds, epochNanos]; } exports.getEpochHiResTime = getEpochHiResTime; /** * @internal */ function hiResTimeToMicros(hrTime) { return hrTime[0] * MICROS_PER_SECOND + hrTime[1] / MILLIS_PER_SECOND; } exports.hiResTimeToMicros = hiResTimeToMicros; /** * @internal */ function getHiResTimeDelta(start, end) { let seconds = end[0] - start[0]; let nanoseconds = end[1] - start[1]; // Handle nanosecond underflow if (nanoseconds < 0) { seconds -= 1; nanoseconds += NANOS_PER_SECOND; } return [seconds, nanoseconds]; } exports.getHiResTimeDelta = getHiResTimeDelta; /** * @internal */ function millisToHiResTime(millis) { const seconds = Math.floor(millis / MILLIS_PER_SECOND); const remainingMillis = millis - seconds * MILLIS_PER_SECOND; const nanoseconds = remainingMillis * MICROS_PER_SECOND; return [seconds, nanoseconds]; } exports.millisToHiResTime = millisToHiResTime; /** * @internal */ function getLatestTime(timeA, timeB) { // first compare seconds if (timeA[0] > timeB[0]) { return timeA; } if (timeA[0] < timeB[0]) { return timeB; } // If seconds are exactly the same, compare the nanoseconds if (timeA[1] >= timeB[1]) { return timeA; } return timeB; } exports.getLatestTime = getLatestTime; /** * @internal */ function getCoreSpanEndTime(coreSpanEndTime) { // Mitigate Node.js vs C++ clock skew. A parent span must fully encapsulate // its children, so we ensure the parent ends at or after the core child's end time. const currentTime = timeInputToHiResTime(); return getLatestTime(currentTime, coreSpanEndTime); } exports.getCoreSpanEndTime = getCoreSpanEndTime; /** * @internal */ function timeInputToHiResTime(input) { if (typeof input === 'undefined') { return getEpochHiResTime(); } // If a Date object is provided, extract the epoch milliseconds if (input instanceof Date) { return millisToHiResTime(input.getTime()); } // If a number is provided, assume it is epoch milliseconds if (typeof input === 'number') { return millisToHiResTime(input); } return input; } exports.timeInputToHiResTime = timeInputToHiResTime; /** * @internal */ function getAttributesForKeyValueOpType(opType, cppDocId, durability) { const attributes = { [observabilitytypes_1.OpAttributeName.SystemName]: 'couchbase', [observabilitytypes_1.OpAttributeName.Service]: (0, observabilitytypes_1.serviceNameFromOpType)(opType), [observabilitytypes_1.OpAttributeName.OperationName]: opType, [observabilitytypes_1.OpAttributeName.BucketName]: cppDocId.bucket, [observabilitytypes_1.OpAttributeName.ScopeName]: cppDocId.scope, [observabilitytypes_1.OpAttributeName.CollectionName]: cppDocId.collection, }; if (durability && durability != binding_1.default.durability_level.none) { if (durability === binding_1.default.durability_level.majority) { attributes[observabilitytypes_1.OpAttributeName.DurabilityLevel] = 'majority'; } else if (durability === binding_1.default.durability_level.majority_and_persist_to_active) { attributes[observabilitytypes_1.OpAttributeName.DurabilityLevel] = 'majority_and_persist_to_active'; } else if (durability === binding_1.default.durability_level.persist_to_majority) { attributes[observabilitytypes_1.OpAttributeName.DurabilityLevel] = 'persist_to_majority'; } } return attributes; } exports.getAttributesForKeyValueOpType = getAttributesForKeyValueOpType; /** * @internal */ function getAttributesForHttpOpType(opType, options) { var _a; const attributes = { [observabilitytypes_1.OpAttributeName.SystemName]: 'couchbase', [observabilitytypes_1.OpAttributeName.Service]: (0, observabilitytypes_1.serviceNameFromOpType)(opType), [observabilitytypes_1.OpAttributeName.OperationName]: opType, }; if (((_a = options === null || options === void 0 ? void 0 : options.queryOptions) === null || _a === void 0 ? void 0 : _a.parameters) && options.statement) { attributes[observabilitytypes_1.OpAttributeName.QueryStatement] = options.statement; } if (options === null || options === void 0 ? void 0 : options.bucketName) { attributes[observabilitytypes_1.OpAttributeName.BucketName] = options.bucketName; } if (options === null || options === void 0 ? void 0 : options.scopeName) { attributes[observabilitytypes_1.OpAttributeName.ScopeName] = options.scopeName; } if (options === null || options === void 0 ? void 0 : options.collectionName) { attributes[observabilitytypes_1.OpAttributeName.CollectionName] = options.collectionName; } if (options === null || options === void 0 ? void 0 : options.queryContext) { const [bucketName, scopeName] = options.queryContext .split('.') .map((str) => str.replace(/`/g, '')); attributes[observabilitytypes_1.OpAttributeName.BucketName] = bucketName; attributes[observabilitytypes_1.OpAttributeName.ScopeName] = scopeName; } return attributes; } exports.getAttributesForHttpOpType = getAttributesForHttpOpType;