aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/poolRequests.js
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2015-12-04 16:13:32 +0100
committerChocobozzz <florian.bigard@gmail.com>2015-12-04 16:13:32 +0100
commit0b69752270f1ceea06a29872b3db23660a55d6d3 (patch)
tree42da726633f3e48f4fe592cfd2c1ca14346a159b /src/poolRequests.js
parentaf82cae07dc568e3cb10acd70113df56eb8b15a9 (diff)
downloadPeerTube-0b69752270f1ceea06a29872b3db23660a55d6d3.tar.gz
PeerTube-0b69752270f1ceea06a29872b3db23660a55d6d3.tar.zst
PeerTube-0b69752270f1ceea06a29872b3db23660a55d6d3.zip
Add a pool of requests instead of making a request at each action (add
video/remove video) for performance in big networks
Diffstat (limited to 'src/poolRequests.js')
-rw-r--r--src/poolRequests.js158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/poolRequests.js b/src/poolRequests.js
new file mode 100644
index 000000000..b117c9923
--- /dev/null
+++ b/src/poolRequests.js
@@ -0,0 +1,158 @@
1;(function () {
2 'use strict'
3
4 var async = require('async')
5
6 var logger = require('./logger')
7 var database = require('./database')
8 var PoolRequestsDB = database.PoolRequestsDB
9 var PodsDB = database.PodsDB
10 var utils = require('./utils')
11
12 var poolRequests = {}
13
14 // ----------- Constants -----------
15
16 // Time to wait between requests to the friends
17 var INTERVAL = utils.isTestInstance() ? 10000 : 60000
18 var PODS_SCORE = {
19 MALUS: -10,
20 BONUS: 10
21 }
22
23 // ----------- Private -----------
24 var timer = null
25
26 function makePoolRequests () {
27 logger.info('Making pool requests to friends.')
28
29 PoolRequestsDB.find({}, { type: 1, request: 1 }, function (err, pool_requests) {
30 if (err) throw err
31
32 var requests = {
33 add: [],
34 remove: []
35 }
36
37 async.each(pool_requests, function (pool_request, callback_each) {
38 if (pool_request.type === 'add') {
39 requests.add.push(pool_request.request)
40 } else if (pool_request.type === 'remove') {
41 requests.remove.push(pool_request.request)
42 } else {
43 throw new Error('Unkown pool request type.')
44 }
45
46 callback_each()
47 }, function () {
48 makePoolRequest('add', requests.add)
49 makePoolRequest('remove', requests.remove)
50 logger.info('Pool requests to friends sent.')
51 })
52 })
53 }
54
55 function updatePodsScore (good_pods, bad_pods) {
56 logger.info('Updating %d good pods and %d bad pods scores.', good_pods.length, bad_pods.length)
57
58 PodsDB.update({ _id: { $in: good_pods } }, { $inc: { score: PODS_SCORE.BONUS } }, { multi: true }).exec()
59 PodsDB.update({ _id: { $in: bad_pods } }, { $inc: { score: PODS_SCORE.MALUS } }, { multi: true }, function (err) {
60 if (err) throw err
61 removeBadPods()
62 })
63 }
64
65 function removeBadPods () {
66 PodsDB.remove({ score: 0 }, function (err, result) {
67 if (err) throw err
68
69 var number_removed = result.result.n
70 if (number_removed !== 0) logger.info('Removed %d pod.', number_removed)
71 })
72 }
73
74 function makePoolRequest (type, requests) {
75 logger.debug('Make pool requests scheduled.')
76 PodsDB.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err, pods) {
77 if (err) throw err
78
79 var params = {
80 encrypt: true,
81 sign: true,
82 method: 'POST',
83 path: null,
84 data: requests
85 }
86
87 if (type === 'add') {
88 params.path = '/api/' + global.API_VERSION + '/remotevideos/add'
89 } else if (type === 'remove') {
90 params.path = '/api/' + global.API_VERSION + '/remotevideos/remove'
91 } else {
92 throw new Error('Unkown pool request type.')
93 }
94
95 var bad_pods = []
96 var good_pods = []
97
98 utils.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished)
99
100 function callbackEachPodFinished (err, response, body, url, pod, callback_each_pod_finished) {
101 if (err || response.statusCode !== 200) {
102 bad_pods.push(pod._id)
103 logger.error('Error sending secure request to %s pod.', url, { error: err })
104 } else {
105 good_pods.push(pod._id)
106 }
107
108 return callback_each_pod_finished()
109 }
110
111 function callbackAllPodsFinished (err) {
112 if (err) {
113 logger.error('There was some errors when sending the video meta data.', { error: err })
114 }
115
116 updatePodsScore(good_pods, bad_pods)
117 PoolRequestsDB.remove().exec()
118 }
119 })
120 }
121
122 // ----------- Public -----------
123 poolRequests.activate = function () {
124 logger.info('Pool requests activated.')
125 timer = setInterval(makePoolRequests, INTERVAL)
126 }
127
128 poolRequests.addToPoolRequests = function (id, type, request) {
129 logger.debug('Add request to the pool requests.', { id: id, type: type, request: request })
130
131 PoolRequestsDB.findOne({ id: id }, function (err, entity) {
132 if (err) logger.error(err)
133
134 if (entity) {
135 if (entity.type === type) {
136 logger.error(new Error('Cannot insert two same requests.'))
137 return
138 }
139
140 // Remove the request of the other type
141 PoolRequestsDB.remove({ id: id }, function (err) {
142 if (err) logger.error(err)
143 })
144 } else {
145 PoolRequestsDB.create({ id: id, type: type, request: request }, function (err) {
146 if (err) logger.error(err)
147 })
148 }
149 })
150 }
151
152 poolRequests.deactivate = function () {
153 logger.info('Pool requests deactivated.')
154 clearInterval(timer)
155 }
156
157 module.exports = poolRequests
158})()