UNPKG

@aimee-blue/ab-service-kit

Version:
95 lines (77 loc) 2.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.reInitializeTime = reInitializeTime; exports.localNow = localNow; exports.time = void 0; var _serverTime = require("./serverTime"); var _registerError = require("../registerError"); var _logging = require("../logging"); // in the docs is mentioned that `hrtime` is more stable // that the Date.now and doesn't drift, so we use it to // determine current local time, also it gives us nanosecond precision let initialNow = Date.now(); let initialHr = process.hrtime(); let initialDiff = Date.now() - quickNowWithMicroseconds(); // microsecond precision, as there is simply no room for nanos in JavaScript number function quickNowWithMicroseconds() { const [seconds, nanoseconds] = process.hrtime(initialHr); const result = initialNow + seconds * 1e3 + nanoseconds / 1e6; return result; } // it is possible that the VM sleeps (typically on local dev desktop) // so we need to reinitialize the time function reInitializeTime() { const oldDiff = initialDiff; initialNow = Date.now(); initialHr = process.hrtime(); initialDiff = Date.now() - quickNowWithMicroseconds(); const logger = (0, _logging.defaultBasicLogger)(); logger.log('💡 Re-initializing time', { oldDiff, newDiff: initialDiff }); } function localNow() { const result = quickNowWithMicroseconds(); // reinitialize after clock synchronizations and hibernation's const diff = Math.abs(Date.now() - result - initialDiff); if (diff > 10) { reInitializeTime(); return quickNowWithMicroseconds(); } return result; } const defaultDeps = { determineTime: _serverTime.serverTime }; let serverTimeInfo = null; let promise = null; const time = (deps = defaultDeps) => { if (!process.env.TIME_URL) { return Promise.resolve(localNow()); } if (serverTimeInfo !== null) { return Promise.resolve(localNow() - serverTimeInfo.offset); } const logger = (0, _logging.defaultBasicLogger)(); return promise || (promise = deps.determineTime().then(() => { const start = localNow(); return deps.determineTime().then(result => { const stop = localNow(); const took = stop - start; // the right time is somewhere in between serverTimeInfo = { offset: localNow() - result, took }; promise = null; logger.log('⏰ Time synchronized, it took', took, 'offset is', serverTimeInfo.offset); return localNow() - serverTimeInfo.offset; }); }).catch(err => { (0, _registerError.registerError)(err); promise = null; logger.error('💥 Error when synchronizing time', err); return localNow(); })); }; exports.time = time; //# sourceMappingURL=index.js.map