UNPKG

@63pokupki/nodejs-common

Version:
117 lines 5.02 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AvgCacheSys = void 0; const knex_1 = __importDefault(require("knex")); const lodash_1 = __importDefault(require("lodash")); /** * агрегированное кеширование * кеширует данные в денормализованном виде * для их быстрой выборки * предполагается что кешируемые данные живу */ class AvgCacheSys { /** init */ constructor(conf) { // TODO - реализовать пул БД для кеширования с распределением данных по ним - на основе деления на остаток /** задержка */ this.iLatency = 0; if (conf) { this.dbCache = (0, knex_1.default)(conf); } else { console.log('AvgCacheSys - Не указана БД для агрегационного кеширования'); } } /** Конфигурация кеширования */ fConf(param) { if (param) { if (param.latency) { this.iLatency = param.latency; } } } /** Сбросить агрегационные данные */ async avgReset(sTable, aidRecord) { if (this.dbCache) { try { await this.dbCache({ t: sTable }) .whereIn('t.id', aidRecord) .where('v', '=', 0) .update({ v: 1 }); } catch (e) { console.log('AvgCacheSys.avgReset - ', e); } } } /** * Агрегационное кеширование * необходимо передавть фунцию для создания агрегации */ async avgCache(sTable, aidRecord, callback) { let ixCacheIgnore = {}; // Словарь для ингорирования кеша, в случае если стоит задержка latency let aidRecordDiff = []; // Разница для выборки новых данных let aDataCache = []; // Закешированые данные if (this.dbCache) { const [aCache, aidCacheIgnore] = await Promise.all([ this.dbCache({ t: sTable }) .whereIn('t.id', aidRecord) .where('t.v', '=', 0) .select(), this.dbCache({ t: sTable }) .whereIn('t.id', aidRecord) .where('t.v', '>', 0) .whereRaw(`NOW() < t.updated_at + INTERVAL ${this.iLatency} SECOND `) .pluck('t.id') ]); ixCacheIgnore = lodash_1.default.keyBy(aidCacheIgnore); // Декодируем данные из кеша const aidRecordCache = aCache.map(el => el.id); aDataCache = aCache.map((el) => JSON.parse(el.data)); // Вычисляем разницу в данных aidRecordDiff = lodash_1.default.difference(aidRecord, aidRecordCache); } const aDataNew = await callback(aidRecordDiff); // console.log('[DATA_NEW]>>', 'new:', aDataNew.length, 'dif:', aidRecordDiff.length, 'ign:', aidCacheIgnore.length); const aItemCacheNew = []; for (let i = 0; i < aDataNew.length; i++) { const vDataNew = aDataNew[i]; if (vDataNew) { const idRecord = vDataNew.id; aDataCache.push(vDataNew); if (!ixCacheIgnore[idRecord]) { aItemCacheNew.push({ id: idRecord, v: 0, data: JSON.stringify(vDataNew) }); } } } if (this.dbCache && aItemCacheNew.length) { // Дописываем данные в кеш try { // const insertResult = await mgItemCache.insertMany(aItemCacheNew); let sql = (this.dbCache(sTable).insert(aItemCacheNew)) .toString(); sql = sql.replace(/^insert/i, 'replace'); // console.log(sql); await this.dbCache.raw(sql); } catch (e) { console.log('AvgCacheSys.avgCache - ', e); } } // Сортировка const ixDataCache = lodash_1.default.keyBy(aDataCache, 'id'); const aDataCacheSort = []; for (let i = 0; i < aidRecord.length; i++) { const idRecord = aidRecord[i]; const vDataCache = ixDataCache[idRecord]; if (vDataCache) { aDataCacheSort.push(vDataCache); } } return aDataCacheSort; } } exports.AvgCacheSys = AvgCacheSys; //# sourceMappingURL=AvgCacheSys.js.map