couchbase
Version:
The official Couchbase Node.js Client Library.
176 lines (175 loc) • 7.14 kB
JavaScript
;
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;