| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | 
							- const CoreClass = require("../../core.js");
 
- const redis = require("redis");
 
- const config = require("config");
 
- const mongoose = require("mongoose");
 
- // Lightweight / convenience wrapper around redis module for our needs
 
- const pubs = {},
 
-     subs = {};
 
- class CacheModule extends CoreClass {
 
-     constructor() {
 
-         super("cache");
 
-     }
 
-     initialize() {
 
-         return new Promise((resolve, reject) => {
 
-             this.schemas = {
 
-                 session: require("./schemas/session"),
 
-                 station: require("./schemas/station"),
 
-                 playlist: require("./schemas/playlist"),
 
-                 officialPlaylist: require("./schemas/officialPlaylist"),
 
-                 song: require("./schemas/song"),
 
-                 punishment: require("./schemas/punishment"),
 
-             };
 
-             this.url = config.get("redis").url;
 
-             this.password = config.get("redis").password;
 
-             this.log("INFO", "Connecting...");
 
-             this.client = redis.createClient({
 
-                 url: this.url,
 
-                 password: this.password,
 
-                 retry_strategy: (options) => {
 
-                     if (this.getStatus() === "LOCKDOWN") return;
 
-                     if (this.getStatus() !== "RECONNECTING")
 
-                         this.setStatus("RECONNECTING");
 
-                     this.log("INFO", `Attempting to reconnect.`);
 
-                     if (options.attempt >= 10) {
 
-                         this.log("ERROR", `Stopped trying to reconnect.`);
 
-                         this.setStatus("FAILED");
 
-                         // this.failed = true;
 
-                         // this._lockdown();
 
-                         return undefined;
 
-                     }
 
-                     return 3000;
 
-                 },
 
-             });
 
-             this.client.on("error", (err) => {
 
-                 if (this.getStatus() === "INITIALIZING") reject(err);
 
-                 if (this.getStatus() === "LOCKDOWN") return;
 
-                 this.log("ERROR", `Error ${err.message}.`);
 
-             });
 
-             this.client.on("connect", () => {
 
-                 this.log("INFO", "Connected succesfully.");
 
-                 if (this.getStatus() === "INITIALIZING") resolve();
 
-                 else if (
 
-                     this.getStatus() === "FAILED" ||
 
-                     this.getStatus() === "RECONNECTING"
 
-                 )
 
-                     this.setStatus("READY");
 
-             });
 
-         });
 
-     }
 
-     /**
 
-      * Gracefully closes all the Redis client connections
 
-      */
 
-     QUIT(payload) {
 
-         return new Promise((resolve, reject) => {
 
-             if (this.client.connected) {
 
-                 this.client.quit();
 
-                 Object.keys(pubs).forEach((channel) => pubs[channel].quit());
 
-                 Object.keys(subs).forEach((channel) =>
 
-                     subs[channel].client.quit()
 
-                 );
 
-             }
 
-             resolve();
 
-         });
 
-     }
 
-     /**
 
-      * Sets a single value in a table
 
-      *
 
-      * @param {String} table - name of the table we want to set a key of (table === redis hash)
 
-      * @param {String} key -  name of the key to set
 
-      * @param {*} value - the value we want to set
 
-      * @param {Function} cb - gets called when the value has been set in Redis
 
-      * @param {Boolean} [stringifyJson=true] - stringify 'value' if it's an Object or Array
 
-      */
 
-     HSET(payload) {
 
-         //table, key, value, cb, stringifyJson = true
 
-         return new Promise((resolve, reject) => {
 
-             let key = payload.key;
 
-             let value = payload.value;
 
-             if (mongoose.Types.ObjectId.isValid(key)) key = key.toString();
 
-             // automatically stringify objects and arrays into JSON
 
-             if (["object", "array"].includes(typeof value))
 
-                 value = JSON.stringify(value);
 
-             this.client.hset(payload.table, key, value, (err) => {
 
-                 if (err) return reject(new Error(err));
 
-                 else resolve(JSON.parse(value));
 
-             });
 
-         });
 
-     }
 
-     /**
 
-      * Gets a single value from a table
 
-      *
 
-      * @param {String} table - name of the table to get the value from (table === redis hash)
 
-      * @param {String} key - name of the key to fetch
 
-      * @param {Function} cb - gets called when the value is returned from Redis
 
-      * @param {Boolean} [parseJson=true] - attempt to parse returned data as JSON
 
-      */
 
-     HGET(payload) {
 
-         //table, key, cb, parseJson = true
 
-         return new Promise((resolve, reject) => {
 
-             // if (!key || !table)
 
-             // return typeof cb === "function" ? cb(null, null) : null;
 
-             let key = payload.key;
 
-             if (mongoose.Types.ObjectId.isValid(key)) key = key.toString();
 
-             this.client.hget(payload.table, key, (err, value) => {
 
-                 if (err) return reject(new Error(err));
 
-                 try {
 
-                     value = JSON.parse(value);
 
-                 } catch (e) {}
 
-                 resolve(value);
 
-             });
 
-         });
 
-     }
 
-     /**
 
-      * Deletes a single value from a table
 
-      *
 
-      * @param {String} table - name of the table to delete the value from (table === redis hash)
 
-      * @param {String} key - name of the key to delete
 
-      * @param {Function} cb - gets called when the value has been deleted from Redis or when it returned an error
 
-      */
 
-     HDEL(payload) {
 
-         //table, key, cb
 
-         return new Promise((resolve, reject) => {
 
-             // if (!payload.key || !table || typeof key !== "string")
 
-             // return cb(null, null);
 
-             let key = payload.key;
 
-             if (mongoose.Types.ObjectId.isValid(key)) key = key.toString();
 
-             this.client.hdel(payload.table, key, (err) => {
 
-                 if (err) return reject(new Error(err));
 
-                 else return resolve();
 
-             });
 
-         });
 
-     }
 
-     /**
 
-      * Returns all the keys for a table
 
-      *
 
-      * @param {String} table - name of the table to get the values from (table === redis hash)
 
-      * @param {Function} cb - gets called when the values are returned from Redis
 
-      * @param {Boolean} [parseJson=true] - attempts to parse all values as JSON by default
 
-      */
 
-     HGETALL(payload) {
 
-         //table, cb, parseJson = true
 
-         return new Promise((resolve, reject) => {
 
-             this.client.hgetall(payload.table, (err, obj) => {
 
-                 if (err) return reject(new Error(err));
 
-                 if (obj)
 
-                     Object.keys(obj).forEach((key) => {
 
-                         try {
 
-                             obj[key] = JSON.parse(obj[key]);
 
-                         } catch (e) {}
 
-                     });
 
-                 else if (!obj) obj = [];
 
-                 resolve(obj);
 
-             });
 
-         });
 
-     }
 
-     /**
 
-      * Publish a message to a channel, caches the redis client connection
 
-      *
 
-      * @param {String} channel - the name of the channel we want to publish a message to
 
-      * @param {*} value - the value we want to send
 
-      * @param {Boolean} [stringifyJson=true] - stringify 'value' if it's an Object or Array
 
-      */
 
-     PUB(payload) {
 
-         //channel, value, stringifyJson = true
 
-         return new Promise((resolve, reject) => {
 
-             /*if (pubs[channel] === undefined) {
 
-             pubs[channel] = redis.createClient({ url: this.url });
 
-             pubs[channel].on('error', (err) => console.error);
 
-             }*/
 
-             let value = payload.value;
 
-             if (["object", "array"].includes(typeof value))
 
-                 value = JSON.stringify(value);
 
-             //pubs[channel].publish(channel, value);
 
-             this.client.publish(payload.channel, value);
 
-             resolve();
 
-         });
 
-     }
 
-     /**
 
-      * Subscribe to a channel, caches the redis client connection
 
-      *
 
-      * @param {String} channel - name of the channel to subscribe to
 
-      * @param {Function} cb - gets called when a message is received
 
-      * @param {Boolean} [parseJson=true] - parse the message as JSON
 
-      */
 
-     SUB(payload) {
 
-         //channel, cb, parseJson = true
 
-         return new Promise((resolve, reject) => {
 
-             if (subs[payload.channel] === undefined) {
 
-                 subs[payload.channel] = {
 
-                     client: redis.createClient({
 
-                         url: this.url,
 
-                         password: this.password,
 
-                     }),
 
-                     cbs: [],
 
-                 };
 
-                 subs[payload.channel].client.on(
 
-                     "message",
 
-                     (channel, message) => {
 
-                         try {
 
-                             message = JSON.parse(message);
 
-                         } catch (e) {}
 
-                         subs[channel].cbs.forEach((cb) => cb(message));
 
-                     }
 
-                 );
 
-                 subs[payload.channel].client.subscribe(payload.channel);
 
-             }
 
-             subs[payload.channel].cbs.push(payload.cb);
 
-             resolve();
 
-         });
 
-     }
 
-     GET_SCHEMA(payload) {
 
-         return new Promise((resolve, reject) => {
 
-             resolve(this.schemas[payload.schemaName]);
 
-         });
 
-     }
 
- }
 
- module.exports = new CacheModule();
 
 
  |