diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2015-12-04 16:13:32 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2015-12-04 16:13:32 +0100 |
commit | 0b69752270f1ceea06a29872b3db23660a55d6d3 (patch) | |
tree | 42da726633f3e48f4fe592cfd2c1ca14346a159b /src/poolRequests.js | |
parent | af82cae07dc568e3cb10acd70113df56eb8b15a9 (diff) | |
download | PeerTube-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.js | 158 |
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 | })() | ||