]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/pod.js
Use yarn instead of npm install
[github/Chocobozzz/PeerTube.git] / server / models / pod.js
index 84f78f2007ac00f38edea0bd68c413f67e2db0de..8e2d488e109dd4036287e839adbfee6a2f699324 100644 (file)
@@ -1,8 +1,11 @@
 'use strict'
 
+const each = require('async/each')
 const map = require('lodash/map')
+const waterfall = require('async/waterfall')
 
 const constants = require('../initializers/constants')
+const logger = require('../helpers/logger')
 const customPodsValidators = require('../helpers/custom-validators').pods
 
 // ---------------------------------------------------------------------------
@@ -32,9 +35,25 @@ module.exports = function (sequelize, DataTypes) {
           isInt: true,
           max: constants.FRIEND_SCORE.MAX
         }
+      },
+      email: {
+        type: DataTypes.STRING(400),
+        allowNull: false,
+        validate: {
+          isEmail: true
+        }
       }
     },
     {
+      indexes: [
+        {
+          fields: [ 'host' ],
+          unique: true
+        },
+        {
+          fields: [ 'score' ]
+        }
+      ],
       classMethods: {
         associate,
 
@@ -42,9 +61,11 @@ module.exports = function (sequelize, DataTypes) {
         incrementScores,
         list,
         listAllIds,
+        listRandomPodIdsWithRequest,
         listBadPods,
         load,
         loadByHost,
+        updatePodsScore,
         removeAll
       },
       instanceMethods: {
@@ -62,6 +83,7 @@ function toFormatedJSON () {
   const json = {
     id: this.id,
     host: this.host,
+    email: this.email,
     score: this.score,
     createdAt: this.createdAt
   }
@@ -107,11 +129,18 @@ function list (callback) {
   return this.findAll().asCallback(callback)
 }
 
-function listAllIds (callback) {
+function listAllIds (transaction, callback) {
+  if (!callback) {
+    callback = transaction
+    transaction = null
+  }
+
   const query = {
     attributes: [ 'id' ]
   }
 
+  if (transaction) query.transaction = transaction
+
   return this.findAll(query).asCallback(function (err, pods) {
     if (err) return callback(err)
 
@@ -119,6 +148,47 @@ function listAllIds (callback) {
   })
 }
 
+function listRandomPodIdsWithRequest (limit, tableWithPods, tableWithPodsJoins, callback) {
+  if (!callback) {
+    callback = tableWithPodsJoins
+    tableWithPodsJoins = ''
+  }
+
+  const self = this
+
+  self.count().asCallback(function (err, count) {
+    if (err) return callback(err)
+
+    // Optimization...
+    if (count === 0) return callback(null, [])
+
+    let start = Math.floor(Math.random() * count) - limit
+    if (start < 0) start = 0
+
+    const query = {
+      attributes: [ 'id' ],
+      order: [
+        [ 'id', 'ASC' ]
+      ],
+      offset: start,
+      limit: limit,
+      where: {
+        id: {
+          $in: [
+            this.sequelize.literal(`SELECT DISTINCT "${tableWithPods}"."podId" FROM "${tableWithPods}" ${tableWithPodsJoins}`)
+          ]
+        }
+      }
+    }
+
+    return this.findAll(query).asCallback(function (err, pods) {
+      if (err) return callback(err)
+
+      return callback(null, map(pods, 'id'))
+    })
+  })
+}
+
 function listBadPods (callback) {
   const query = {
     where: {
@@ -146,3 +216,58 @@ function loadByHost (host, callback) {
 function removeAll (callback) {
   return this.destroy().asCallback(callback)
 }
+
+function updatePodsScore (goodPods, badPods) {
+  const self = this
+
+  logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
+
+  if (goodPods.length !== 0) {
+    this.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) {
+      if (err) logger.error('Cannot increment scores of good pods.', { error: err })
+    })
+  }
+
+  if (badPods.length !== 0) {
+    this.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) {
+      if (err) logger.error('Cannot decrement scores of bad pods.', { error: err })
+      removeBadPods.call(self)
+    })
+  }
+}
+
+// ---------------------------------------------------------------------------
+
+// Remove pods with a score of 0 (too many requests where they were unreachable)
+function removeBadPods () {
+  const self = this
+
+  waterfall([
+    function findBadPods (callback) {
+      self.sequelize.models.Pod.listBadPods(function (err, pods) {
+        if (err) {
+          logger.error('Cannot find bad pods.', { error: err })
+          return callback(err)
+        }
+
+        return callback(null, pods)
+      })
+    },
+
+    function removeTheseBadPods (pods, callback) {
+      each(pods, function (pod, callbackEach) {
+        pod.destroy().asCallback(callbackEach)
+      }, function (err) {
+        return callback(err, pods.length)
+      })
+    }
+  ], function (err, numberOfPodsRemoved) {
+    if (err) {
+      logger.error('Cannot remove bad pods.', { error: err })
+    } else if (numberOfPodsRemoved) {
+      logger.info('Removed %d pods.', numberOfPodsRemoved)
+    } else {
+      logger.info('No need to remove bad pods.')
+    }
+  })
+}