| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Module dependencies | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | // Core
 | 
					
						
							|  |  |  | const util = require('util'); | 
					
						
							| 
									
										
										
										
											2018-05-04 18:27:39 +02:00
										 |  |  | /* eslint-disable prefer-template */ | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Public node modules.
 | 
					
						
							|  |  |  | const _ = require('lodash'); | 
					
						
							|  |  |  | const Redis = require('ioredis'); | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  | const stackTrace = require('stack-trace'); | 
					
						
							| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Redis hook | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  | module.exports = function(strapi) { | 
					
						
							| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  |   const hook = { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Default options | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |     defaults: { | 
					
						
							|  |  |  |       port: 6379, | 
					
						
							|  |  |  |       host: 'localhost', | 
					
						
							| 
									
										
										
										
											2017-07-27 16:40:39 +02:00
										 |  |  |       options: { | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         db: 0, | 
					
						
							| 
									
										
										
										
											2017-07-27 16:40:39 +02:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |       showFriendlyErrorStack: process.env.NODE_ENV !== 'production', | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Initialize the hook | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |     initialize: () => { | 
					
						
							|  |  |  |       if ( | 
					
						
							|  |  |  |         _.isEmpty(strapi.models) || | 
					
						
							|  |  |  |         !_.pickBy(strapi.config.connections, { | 
					
						
							|  |  |  |           connector: 'strapi-hook-redis', | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       ) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2017-09-21 14:46:50 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |       const connections = _.pickBy(strapi.config.connections, { | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         connector: 'strapi-hook-redis', | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |       if (_.size(connections) === 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2017-07-25 17:12:18 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |       const done = _.after(_.size(connections), () => { | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // For each connection in the config register a new Knex connection.
 | 
					
						
							|  |  |  |       _.forEach(connections, (connection, name) => { | 
					
						
							|  |  |  |         // Apply defaults
 | 
					
						
							| 
									
										
										
										
											2017-07-31 12:12:51 +02:00
										 |  |  |         _.defaults(connection.settings, strapi.config.hook.settings.redis); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         const redis = new Redis( | 
					
						
							|  |  |  |           _.defaultsDeep( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               port: _.get(connection.settings, 'port'), | 
					
						
							|  |  |  |               host: _.get(connection.settings, 'host'), | 
					
						
							|  |  |  |               options: { | 
					
						
							|  |  |  |                 db: _.get(connection.options, 'database') || 0, | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             strapi.config.hook.settings.redis | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         redis.on('error', err => { | 
					
						
							|  |  |  |           strapi.log.error(err); | 
					
						
							|  |  |  |           process.exit(0); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Utils function.
 | 
					
						
							|  |  |  |         // Behavior: Try to retrieve data from Redis, if null
 | 
					
						
							|  |  |  |         // execute callback and set the value in Redis for this serial key.
 | 
					
						
							|  |  |  |         redis.cache = async ({ expired = 60 * 60, serial }, cb, type) => { | 
					
						
							|  |  |  |           if (_.isEmpty(serial)) { | 
					
						
							|  |  |  |             strapi.log.warn( | 
					
						
							|  |  |  |               `Be careful, you're using cache() function of strapi-redis without serial` | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const traces = stackTrace.get(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             strapi.log.warn( | 
					
						
							|  |  |  |               `> [${traces[1].getLineNumber()}] ${traces[1] | 
					
						
							|  |  |  |                 .getFileName() | 
					
						
							|  |  |  |                 .replace(strapi.config.appPath, '')}`
 | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return await cb(); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-07-24 19:58:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |           let cache = await redis.get(serial); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (!cache) { | 
					
						
							|  |  |  |             cache = await cb(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ( | 
					
						
							|  |  |  |               cache && | 
					
						
							|  |  |  |               _.get(connection, 'options.disabledCaching') !== true | 
					
						
							|  |  |  |             ) { | 
					
						
							|  |  |  |               switch (type) { | 
					
						
							|  |  |  |                 case 'json': | 
					
						
							|  |  |  |                   redis.set(serial, JSON.stringify(cache), 'ex', expired); | 
					
						
							|  |  |  |                   break; | 
					
						
							|  |  |  |                 case 'int': | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                   redis.set(serial, cache, 'ex', expired); | 
					
						
							|  |  |  |                   break; | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |           switch (type) { | 
					
						
							|  |  |  |             case 'int': | 
					
						
							|  |  |  |               return parseInt(cache); | 
					
						
							|  |  |  |             case 'float': | 
					
						
							|  |  |  |               return _.toNumber(cache); | 
					
						
							|  |  |  |             case 'json': | 
					
						
							|  |  |  |               try { | 
					
						
							|  |  |  |                 return _.isObject(cache) ? cache : JSON.parse(cache); | 
					
						
							|  |  |  |               } catch (e) { | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  |                 return cache; | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |               } | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |               return cache; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         // Define as new connection.
 | 
					
						
							|  |  |  |         strapi.connections[name] = redis; | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         // Expose global
 | 
					
						
							|  |  |  |         if (_.get(connection, 'options.global') !== false) { | 
					
						
							|  |  |  |           global[_.get(connection, 'options.globalName') || 'redis'] = redis; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |         if (_.get(connection, 'options.debug') === true) { | 
					
						
							|  |  |  |           redis.monitor((err, monitor) => { | 
					
						
							|  |  |  |             // Entering monitoring mode.
 | 
					
						
							|  |  |  |             monitor.on('monitor', (time, args) => { | 
					
						
							|  |  |  |               console.log(time + ': ' + util.inspect(args)); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2017-02-14 14:34:01 +01:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         redis.on('ready', () => { | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-08-14 14:15:45 +02:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return hook; | 
					
						
							|  |  |  | }; |