UNPKG

@quell/server

Version:

Quell is an open-source NPM package providing a light-weight caching layer implementation and cache invalidation for GraphQL responses on both the client- and server-side. Use Quell to prevent redundant client-side API requests and to minimize costly serv

425 lines (424 loc) 20.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStatsFromRedis = exports.getRedisValues = exports.getRedisKeys = exports.getRedisInfo = exports.getFromRedis = void 0; const redisConnection_1 = require("./redisConnection"); //connection to Redis server const redisCache = redisConnection_1.redisCacheMain; /** * Reads from Redis cache and returns a promise (Redis v4 natively returns a promise). * @param {string} key - The key for Redis lookup. * @returns {Promise} A promise representing the value from the redis cache with the provided key. */ const getFromRedis = (key, redisCache) => __awaiter(void 0, void 0, void 0, function* () { try { if (typeof key !== "string" || key === undefined) return; const lowerKey = key.toLowerCase(); const redisResult = yield redisCache.get(lowerKey); return redisResult; } catch (error) { const err = { log: `Error in QuellCache trying to getFromRedis, ${error}`, status: 400, message: { err: "Error in getFromRedis. Check server log for more details.", }, }; console.log("err in getFromRedis: ", err); } }); exports.getFromRedis = getFromRedis; /** * Returns a chain of middleware based on what information (if any) the user would * like to request from the specified redisCache. It requires an appropriately * configured Express route and saves the specified stats to res.locals, for instance: * @example * app.use('/redis', getRedisInfo({ * getStats: true, * getKeys: true, * getValues: true * })); * @param {Object} options - Three properties with boolean values: getStats, getKeys, getValues * @returns {Array} An array of middleware functions that retrieves specified Redis info. */ const getRedisInfo = (options = { getStats: true, getKeys: true, getValues: true, }) => { // console.log("Getting Redis Info"); const middleware = []; /** * Helper function within the getRedisInfo function that returns * what redis data should be retrieved based on the passed in options. * @param {Object} opts - Options object containing a boolean value for getStats, getKeys, and getValues. * @returns {string} String that indicates which data should be retrieved from Redis instance. */ const getOptions = (opts) => { const { getStats, getKeys, getValues } = opts; if (!getStats && getKeys && getValues) return "dontGetStats"; else if (getStats && getKeys && !getValues) return "dontGetValues"; else if (!getStats && getKeys && !getValues) return "getKeysOnly"; else if (getStats && !getKeys && !getValues) return "getStatsOnly"; else return "getAll"; }; switch (getOptions(options)) { case "dontGetStats": middleware.push(exports.getRedisKeys, exports.getRedisValues); break; case "dontGetValues": middleware.push(exports.getStatsFromRedis, exports.getRedisKeys); break; case "getKeysOnly": middleware.push(exports.getRedisKeys); break; case "getStatsOnly": middleware.push(exports.getStatsFromRedis); break; case "getAll": middleware.push(exports.getStatsFromRedis, exports.getRedisKeys, exports.getRedisValues); break; } return middleware; }; exports.getRedisInfo = getRedisInfo; /** * Gets the key names from the Redis cache and adds them to the response. * @param {Object} req - Express request object. * @param {Object} res - Express response object. * @param {Function} next - Express next middleware function. */ const getRedisKeys = (req, res, next) => { redisCache .keys("*") .then((response) => { res.locals.redisKeys = response; return next(); }) .catch((error) => { const err = { log: `Error inside catch block of getRedisKeys, keys potentially undefined, ${error}`, status: 400, message: { err: "Error in redis - getRedisKeys. Check server log for more details.", }, }; return next(err); }); }; exports.getRedisKeys = getRedisKeys; /** * Gets the values associated with the Redis cache keys and adds them to the response. * @param {Object} req - Express request object. * @param {Object} res - Express response object. * @param {Function} next - Express next middleware function. */ const getRedisValues = (req, res, next) => { if (res.locals.redisKeys && res.locals.redisKeys.length !== 0) { redisCache .mGet(res.locals.redisKeys) .then((response) => { res.locals.redisValues = response; return next(); }) .catch((error) => { const err = { log: `Error inside catch block of getRedisValues, ${error}`, status: 400, message: { err: "Error in redis - getRedisValues. Check server log for more details.", }, }; return next(err); }); } else { res.locals.redisValues = []; return next(); } }; exports.getRedisValues = getRedisValues; /** * Gets information and statistics about the server and adds them to the response. * @param {Object} req - Express request object. * @param {Object} res - Express response object. * @param {Function} next - Express next middleware function. */ const getStatsFromRedis = (req, res, next) => { try { const getStats = () => { // redisCache.info returns information and statistics about the server as an array of field:value. redisCache .info() .then((response) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1; const dataLines = response.split("\r\n"); const output = { // SERVER server: [ // Redis version { name: "Redis version", value: (_a = dataLines .find((line) => line.match(/redis_version/))) === null || _a === void 0 ? void 0 : _a.split(":")[1], }, // Redis build id { name: "Redis build id", value: (_b = dataLines .find((line) => line.match(/redis_build_id/))) === null || _b === void 0 ? void 0 : _b.split(":")[1], }, // Redis mode { name: "Redis mode", value: (_c = dataLines .find((line) => line.match(/redis_mode/))) === null || _c === void 0 ? void 0 : _c.split(":")[1], }, // OS hosting Redis system { name: "Host operating system", value: (_d = dataLines .find((line) => line.match(/os/))) === null || _d === void 0 ? void 0 : _d.split(":")[1], }, // TCP/IP listen port { name: "TCP/IP port", value: (_e = dataLines .find((line) => line.match(/tcp_port/))) === null || _e === void 0 ? void 0 : _e.split(":")[1], }, // Server time { name: "System time", value: (_f = dataLines .find((line) => line.match(/server_time_in_usec/))) === null || _f === void 0 ? void 0 : _f.split(":")[1], }, // Number of seconds since Redis server start { name: "Server uptime (seconds)", value: (_g = dataLines .find((line) => line.match(/uptime_in_seconds/))) === null || _g === void 0 ? void 0 : _g.split(":")[1], }, // Number of days since Redis server start { name: "Server uptime (days)", value: (_h = dataLines .find((line) => line.match(/uptime_in_days/))) === null || _h === void 0 ? void 0 : _h.split(":")[1], }, // Path to server's executable { name: "Path to executable", value: (_j = dataLines .find((line) => line.match(/executable/))) === null || _j === void 0 ? void 0 : _j.split(":")[1], }, // Path to server's configuration file { name: "Path to configuration file", value: (_k = dataLines .find((line) => line.match(/config_file/))) === null || _k === void 0 ? void 0 : _k.split(":")[1], }, ], // CLIENT client: [ // Number of connected clients { name: "Connected clients", value: (_l = dataLines .find((line) => line.match(/connected_clients/))) === null || _l === void 0 ? void 0 : _l.split(":")[1], }, // Number of sockets used by cluster bus { name: "Cluster connections", value: (_m = dataLines .find((line) => line.match(/cluster_connections/))) === null || _m === void 0 ? void 0 : _m.split(":")[1], }, // Max clients { name: "Max clients", value: (_o = dataLines .find((line) => line.match(/maxclients/))) === null || _o === void 0 ? void 0 : _o.split(":")[1], }, // Number of clients being tracked { name: "Tracked clients", value: (_p = dataLines .find((line) => line.match(/tracking_clients/))) === null || _p === void 0 ? void 0 : _p.split(":")[1], }, // Blocked clients { name: "Blocked clients", value: (_q = dataLines .find((line) => line.match(/blocked_clients/))) === null || _q === void 0 ? void 0 : _q.split(":")[1], }, ], // MEMORY memory: [ // Total allocated memory { name: "Total allocated memory", value: (_r = dataLines .find((line) => line.match(/used_memory_human/))) === null || _r === void 0 ? void 0 : _r.split(":")[1], }, // Peak memory consumed { name: "Peak memory consumed", value: (_s = dataLines .find((line) => line.match(/used_memory_peak_human/))) === null || _s === void 0 ? void 0 : _s.split(":")[1], }, // % of peak out of total { name: "Peak memory used % total", value: (_t = dataLines .find((line) => line.match(/used_memory_peak_perc/))) === null || _t === void 0 ? void 0 : _t.split(":")[1], }, // Initial amount of memory consumed at startup { name: "Memory consumed at startup", value: (_u = dataLines .find((line) => line.match(/used_memory_startup/))) === null || _u === void 0 ? void 0 : _u.split(":")[1], }, // Size of dataset // { // name: 'Dataset size (bytes)', // value: dataLines // .find((line) => line.match(/used_memory_dataset/)) // .split(':')[1], // }, // Percent of data out of net memory usage // { // name: 'Dataset memory % total', // value: dataLines // .find((line) => line.match(/used_memory_dataset_perc/)) // .split(':')[1], // }, // Total system memory // { // name: 'Total system memory', // value: dataLines // .find((line) => line.match(/total_system_memory_human/)) // .split(':')[1], // }, ], // STATS stats: [ // Total number of connections accepted by server { name: "Total connections", value: (_v = dataLines .find((line) => line.match(/total_connections_received/))) === null || _v === void 0 ? void 0 : _v.split(":")[1], }, // Total number of commands processed by server { name: "Total commands", value: (_w = dataLines .find((line) => line.match(/total_commands_processed/))) === null || _w === void 0 ? void 0 : _w.split(":")[1], }, // Number of commands processed per second { name: "Commands processed per second", value: (_x = dataLines .find((line) => line.match(/instantaneous_ops_per_sec/))) === null || _x === void 0 ? void 0 : _x.split(":")[1], }, // Total number of keys being tracked // { // name: 'Tracked keys', // value: dataLines // .find((line) => line.match(/tracking_total_keys/)) // .split(':')[1], // }, // Total number of items being tracked(sum of clients number for each key) // { // name: 'Tracked items', // value: dataLines // .find((line) => line.match(/tracking_total_items/)) // .split(':')[1], // }, // Total number of read events processed // { // name: 'Reads processed', // value: dataLines // .find((line) => line.match(/total_reads_processed/)) // .split(':')[1], // }, // Total number of write events processed // { // name: 'Writes processed', // value: dataLines // .find((line) => line.match(/total_writes_processed/)) // .split(':')[1], // }, // Total number of error replies { name: "Error replies", value: (_y = dataLines .find((line) => line.match(/total_error_replies/))) === null || _y === void 0 ? void 0 : _y.split(":")[1], }, // Total number of bytes read from network { name: "Bytes read from network", value: (_z = dataLines .find((line) => line.match(/total_net_input_bytes/))) === null || _z === void 0 ? void 0 : _z.split(":")[1], }, // Networks read rate per second { name: "Network read rate (Kb/s)", value: (_0 = dataLines .find((line) => line.match(/instantaneous_input_kbps/))) === null || _0 === void 0 ? void 0 : _0.split(":")[1], }, // Total number of bytes written to network // { // name: 'Bytes written to network', // value: dataLines // .find((line) => line.match(/total_net_output_bytes/)) // .split(':')[1], // }, // Networks write rate per second { name: "Network write rate (Kb/s)", value: (_1 = dataLines .find((line) => line.match(/instantaneous_output_kbps/))) === null || _1 === void 0 ? void 0 : _1.split(":")[1], }, ], }; res.locals.redisStats = output; return next(); }) .catch((error) => { const err = { log: `Error inside catch block of getting info within getStatsFromRedis, ${error}`, status: 400, message: { err: "Error in redis - getStatsFromRedis. Check server log for more details.", }, }; return next(err); }); }; getStats(); } catch (error) { const err = { log: `Error inside catch block of getStatsFromRedis, ${error}`, status: 400, message: { err: "Error in redis - getStatsFromRedis. Check server log for more details.", }, }; return next(err); } }; exports.getStatsFromRedis = getStatsFromRedis;