3 const each = require('async/each')
4 const waterfall = require('async/waterfall')
5 const values = require('lodash/values')
7 const constants = require('../initializers/constants')
8 const logger = require('../helpers/logger')
10 // ---------------------------------------------------------------------------
12 module.exports = function (sequelize, DataTypes) {
13 const Request = sequelize.define('Request',
20 type: DataTypes.ENUM(values(constants.REQUEST_ENDPOINTS)),
28 listWithLimitAndRandom,
42 // ------------------------------ STATICS ------------------------------
44 function associate (models) {
45 this.belongsToMany(models.Pod, {
50 through: models.RequestToPod,
55 function countTotalRequests (callback) {
57 include: [ this.sequelize.models.Pod ]
60 return this.count(query).asCallback(callback)
63 // Remove pods with a score of 0 (too many requests where they were unreachable)
64 function removeBadPods () {
68 function findBadPods (callback) {
69 self.sequelize.models.Pod.listBadPods(function (err, pods) {
71 logger.error('Cannot find bad pods.', { error: err })
75 return callback(null, pods)
79 function removeTheseBadPods (pods, callback) {
80 each(pods, function (pod, callbackEach) {
81 pod.destroy().asCallback(callbackEach)
83 return callback(err, pods.length)
86 ], function (err, numberOfPodsRemoved) {
88 logger.error('Cannot remove bad pods.', { error: err })
89 } else if (numberOfPodsRemoved) {
90 logger.info('Removed %d pods.', numberOfPodsRemoved)
92 logger.info('No need to remove bad pods.')
97 function updatePodsScore (goodPods, badPods) {
99 const Pod = this.sequelize.models.Pod
101 logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
103 if (goodPods.length !== 0) {
104 Pod.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) {
105 if (err) logger.error('Cannot increment scores of good pods.', { error: err })
109 if (badPods.length !== 0) {
110 Pod.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) {
111 if (err) logger.error('Cannot decrement scores of bad pods.', { error: err })
112 removeBadPods.call(self)
117 function listWithLimitAndRandom (limitPods, limitRequestsPerPod, callback) {
119 const Pod = this.sequelize.models.Pod
121 Pod.listRandomPodIdsWithRequest(limitPods, function (err, podIds) {
122 if (err) return callback(err)
124 // We don't have friends that have requests
125 if (podIds.length === 0) return callback(null, [])
127 // The the first x requests of these pods
128 // It is very important to sort by id ASC to keep the requests order!
135 model: self.sequelize.models.Pod,
145 self.findAll(query).asCallback(function (err, requests) {
146 if (err) return callback(err)
148 const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
149 return callback(err, requestsGrouped)
154 function removeAll (callback) {
155 // Delete all requests
156 this.truncate({ cascade: true }).asCallback(callback)
159 function removeWithEmptyTo (callback) {
160 if (!callback) callback = function () {}
166 this.sequelize.literal('SELECT "requestId" FROM "RequestToPods"')
172 this.destroy(query).asCallback(callback)
175 // ---------------------------------------------------------------------------
177 function groupAndTruncateRequests (requests, limitRequestsPerPod) {
178 const requestsGrouped = {}
180 requests.forEach(function (request) {
181 request.Pods.forEach(function (pod) {
182 if (!requestsGrouped[pod.id]) requestsGrouped[pod.id] = []
184 if (requestsGrouped[pod.id].length < limitRequestsPerPod) {
185 requestsGrouped[pod.id].push({
193 return requestsGrouped