| 
									
										
										
										
											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'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: { | 
					
						
							|  |  |  |         db: 0 | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +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 | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialize: cb => { | 
					
						
							| 
									
										
										
										
											2017-09-21 14:46:50 +02:00
										 |  |  |       if (_.isEmpty(strapi.models) || !_.pickBy(strapi.config.connections, { | 
					
						
							|  |  |  |         connector: 'strapi-redis' | 
					
						
							|  |  |  |       })) { | 
					
						
							|  |  |  |         return cb(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |       const connections = _.pickBy(strapi.config.connections, { | 
					
						
							|  |  |  |         connector: 'strapi-redis' | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-25 17:12:18 +02:00
										 |  |  |       if(_.size(connections) === 0) { | 
					
						
							|  |  |  |         cb(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |       const done = _.after(_.size(connections), () => { | 
					
						
							|  |  |  |         cb(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // 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
										 |  |  | 
 | 
					
						
							|  |  |  |         try { | 
					
						
							| 
									
										
										
										
											2017-07-27 16:40:39 +02:00
										 |  |  |           const redis = new Redis(_.defaultsDeep({ | 
					
						
							|  |  |  |             port: _.get(connection.settings, 'port'), | 
					
						
							| 
									
										
										
										
											2017-07-28 15:31:11 +02:00
										 |  |  |             host: _.get(connection.settings, 'host'), | 
					
						
							|  |  |  |             options: { | 
					
						
							| 
									
										
										
										
											2017-07-27 16:40:39 +02:00
										 |  |  |               db: _.get(connection.options, 'database') || 0 | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-07-28 15:31:11 +02:00
										 |  |  |           }, strapi.config.hook.settings.redis)); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |           redis.on('error', err => { | 
					
						
							| 
									
										
										
										
											2017-02-14 14:34:01 +01:00
										 |  |  |             strapi.log.error(err); | 
					
						
							|  |  |  |             process.exit(0); | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  |           // Utils function.
 | 
					
						
							|  |  |  |           // Behavior: Try to retrieve data from Redis, if null
 | 
					
						
							|  |  |  |           // execute callback and set the value in Redis for this serial key.
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |           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-02-01 17:17:06 +01:00
										 |  |  |             let cache = await redis.get(serial); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!cache) { | 
					
						
							|  |  |  |               cache = await cb(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 15:49:41 +02:00
										 |  |  |               if ( | 
					
						
							|  |  |  |                 cache && | 
					
						
							|  |  |  |                 _.get(connection, 'options.disabledCaching') !== true | 
					
						
							|  |  |  |               ) { | 
					
						
							| 
									
										
										
										
											2017-07-24 19:58:03 +02:00
										 |  |  |                 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
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             switch (type) { | 
					
						
							|  |  |  |               case 'int': | 
					
						
							|  |  |  |                 return parseInt(cache); | 
					
						
							| 
									
										
										
										
											2017-07-24 19:58:03 +02:00
										 |  |  |               case 'float': | 
					
						
							|  |  |  |                 return _.toNumber(cache); | 
					
						
							|  |  |  |               case 'json': | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                   return _.isObject(cache) ? cache : JSON.parse(cache); | 
					
						
							|  |  |  |                 } catch (e) { | 
					
						
							|  |  |  |                   return cache; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2017-02-01 17:17:06 +01:00
										 |  |  |               default: | 
					
						
							|  |  |  |                 return cache; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |           // Define as new connection.
 | 
					
						
							|  |  |  |           strapi.connections[name] = redis; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // Expose global
 | 
					
						
							|  |  |  |           if (_.get(connection, 'options.global') !== false) { | 
					
						
							|  |  |  |             global[_.get(connection, 'options.globalName') || 'redis'] = redis; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           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-02-14 14:34:01 +01:00
										 |  |  |           redis.on('ready', () => { | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2017-01-30 16:31:28 +01:00
										 |  |  |         } catch (e) { | 
					
						
							|  |  |  |           cb(e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-01-30 15:44:47 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return hook; | 
					
						
							|  |  |  | }; |