diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2015-11-24 08:33:59 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2015-11-24 08:33:59 +0100 |
commit | 3bcb78b3aff565996ee0e2aa96bce7f1bdd6d66a (patch) | |
tree | b202172a35956b252282105f614fc9646ca64ebb /src | |
parent | 2e3b5b0db652ae4787e359aadbd4f52e473b6af7 (diff) | |
download | PeerTube-3bcb78b3aff565996ee0e2aa96bce7f1bdd6d66a.tar.gz PeerTube-3bcb78b3aff565996ee0e2aa96bce7f1bdd6d66a.tar.zst PeerTube-3bcb78b3aff565996ee0e2aa96bce7f1bdd6d66a.zip |
Make the network auto sufficient (eject bad pods with scores)
Diffstat (limited to 'src')
-rw-r--r-- | src/database.js | 3 | ||||
-rw-r--r-- | src/pods.js | 64 | ||||
-rw-r--r-- | src/utils.js | 30 | ||||
-rw-r--r-- | src/videos.js | 21 |
4 files changed, 80 insertions, 38 deletions
diff --git a/src/database.js b/src/database.js index 020bfd961..740e89fa4 100644 --- a/src/database.js +++ b/src/database.js | |||
@@ -24,7 +24,8 @@ | |||
24 | // ----------- Pods ----------- | 24 | // ----------- Pods ----------- |
25 | var podsSchema = mongoose.Schema({ | 25 | var podsSchema = mongoose.Schema({ |
26 | url: String, | 26 | url: String, |
27 | publicKey: String | 27 | publicKey: String, |
28 | score: { type: Number, max: global.FRIEND_BASE_SCORE } | ||
28 | }) | 29 | }) |
29 | 30 | ||
30 | var PodsDB = mongoose.model('pods', podsSchema) | 31 | var PodsDB = mongoose.model('pods', podsSchema) |
diff --git a/src/pods.js b/src/pods.js index b4325ebcf..e26b3f0ae 100644 --- a/src/pods.js +++ b/src/pods.js | |||
@@ -16,6 +16,13 @@ | |||
16 | var host = config.get('webserver.host') | 16 | var host = config.get('webserver.host') |
17 | var port = config.get('webserver.port') | 17 | var port = config.get('webserver.port') |
18 | 18 | ||
19 | // ----------- Constants ----------- | ||
20 | |||
21 | var PODS_SCORE = { | ||
22 | MALUS: -10, | ||
23 | BONUS: 10 | ||
24 | } | ||
25 | |||
19 | // ----------- Private functions ----------- | 26 | // ----------- Private functions ----------- |
20 | 27 | ||
21 | function getForeignPodsList (url, callback) { | 28 | function getForeignPodsList (url, callback) { |
@@ -27,6 +34,25 @@ | |||
27 | }) | 34 | }) |
28 | } | 35 | } |
29 | 36 | ||
37 | function updatePodsScore (good_pods, bad_pods) { | ||
38 | logger.info('Updating %d good pods and %d bad pods scores.', good_pods.length, bad_pods.length) | ||
39 | |||
40 | PodsDB.update({ _id: { $in: good_pods } }, { $inc: { score: PODS_SCORE.BONUS } }, { multi: true }).exec() | ||
41 | PodsDB.update({ _id: { $in: bad_pods } }, { $inc: { score: PODS_SCORE.MALUS } }, { multi: true }, function (err) { | ||
42 | if (err) throw err | ||
43 | removeBadPods() | ||
44 | }) | ||
45 | } | ||
46 | |||
47 | function removeBadPods () { | ||
48 | PodsDB.remove({ score: 0 }, function (err, result) { | ||
49 | if (err) throw err | ||
50 | |||
51 | var number_removed = result.result.n | ||
52 | if (number_removed !== 0) logger.info('Removed %d pod.', number_removed) | ||
53 | }) | ||
54 | } | ||
55 | |||
30 | // ----------- Public functions ----------- | 56 | // ----------- Public functions ----------- |
31 | 57 | ||
32 | pods.list = function (callback) { | 58 | pods.list = function (callback) { |
@@ -46,7 +72,8 @@ | |||
46 | 72 | ||
47 | var params = { | 73 | var params = { |
48 | url: data.url, | 74 | url: data.url, |
49 | publicKey: data.publicKey | 75 | publicKey: data.publicKey, |
76 | score: global.FRIEND_BASE_SCORE | ||
50 | } | 77 | } |
51 | 78 | ||
52 | PodsDB.create(params, function (err, pod) { | 79 | PodsDB.create(params, function (err, pod) { |
@@ -68,7 +95,9 @@ | |||
68 | 95 | ||
69 | // { path, data } | 96 | // { path, data } |
70 | pods.makeSecureRequest = function (data, callback) { | 97 | pods.makeSecureRequest = function (data, callback) { |
71 | PodsDB.find({}, { url: 1, publicKey: 1 }).exec(function (err, urls) { | 98 | if (callback === undefined) callback = function () {} |
99 | |||
100 | PodsDB.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err, pods) { | ||
72 | if (err) { | 101 | if (err) { |
73 | logger.error('Cannot get the list of the pods.', { error: err }) | 102 | logger.error('Cannot get the list of the pods.', { error: err }) |
74 | return callback(err) | 103 | return callback(err) |
@@ -84,15 +113,23 @@ | |||
84 | data: data.data | 113 | data: data.data |
85 | } | 114 | } |
86 | 115 | ||
116 | var bad_pods = [] | ||
117 | var good_pods = [] | ||
118 | |||
87 | utils.makeMultipleRetryRequest( | 119 | utils.makeMultipleRetryRequest( |
88 | params, | 120 | params, |
89 | 121 | ||
90 | urls, | 122 | pods, |
91 | 123 | ||
92 | function callbackEachPodFinished (err, response, body, url) { | 124 | function callbackEachPodFinished (err, response, body, pod, callback_each_pod_finished) { |
93 | if (err || response.statusCode !== 200) { | 125 | if (err || response.statusCode !== 200) { |
94 | logger.error('Error sending secure request to %s/%s pod.', url, data.path, { error: err }) | 126 | bad_pods.push(pod._id) |
127 | logger.error('Error sending secure request to %s/%s pod.', pod.url, data.path, { error: err }) | ||
128 | } else { | ||
129 | good_pods.push(pod._id) | ||
95 | } | 130 | } |
131 | |||
132 | return callback_each_pod_finished() | ||
96 | }, | 133 | }, |
97 | 134 | ||
98 | function callbackAllPodsFinished (err) { | 135 | function callbackAllPodsFinished (err) { |
@@ -102,6 +139,8 @@ | |||
102 | } | 139 | } |
103 | 140 | ||
104 | logger.debug('Finished') | 141 | logger.debug('Finished') |
142 | |||
143 | updatePodsScore(good_pods, bad_pods) | ||
105 | callback(null) | 144 | callback(null) |
106 | } | 145 | } |
107 | ) | 146 | ) |
@@ -133,8 +172,8 @@ | |||
133 | // ----------------------------------------------------------------------- | 172 | // ----------------------------------------------------------------------- |
134 | 173 | ||
135 | function computeForeignPodsList (url, callback) { | 174 | function computeForeignPodsList (url, callback) { |
136 | // Always add a trust pod | 175 | // Let's give 1 point to the pod we ask the friends list |
137 | pods_score[url] = Infinity | 176 | pods_score[url] = 1 |
138 | 177 | ||
139 | getForeignPodsList(url, function (foreign_pods_list) { | 178 | getForeignPodsList(url, function (foreign_pods_list) { |
140 | if (foreign_pods_list.length === 0) return callback() | 179 | if (foreign_pods_list.length === 0) return callback() |
@@ -175,16 +214,19 @@ | |||
175 | 214 | ||
176 | pods_list, | 215 | pods_list, |
177 | 216 | ||
178 | function eachRequest (err, response, body, url) { | 217 | function eachRequest (err, response, body, pod, callback_each_request) { |
179 | // We add the pod if it responded correctly with its public certificate | 218 | // We add the pod if it responded correctly with its public certificate |
180 | if (!err && response.statusCode === 200) { | 219 | if (!err && response.statusCode === 200) { |
181 | pods.add({ url: url, publicKey: body.cert }, function (err) { | 220 | pods.add({ url: pod.url, publicKey: body.cert, score: global.FRIEND_BASE_SCORE }, function (err) { |
182 | if (err) { | 221 | if (err) { |
183 | logger.error('Error with adding %s pod.', url, { error: err }) | 222 | logger.error('Error with adding %s pod.', pod.url, { error: err }) |
184 | } | 223 | } |
224 | |||
225 | return callback_each_request() | ||
185 | }) | 226 | }) |
186 | } else { | 227 | } else { |
187 | logger.error('Error with adding %s pod.', url, { error: err || new Error('Status not 200') }) | 228 | logger.error('Error with adding %s pod.', pod.url, { error: err || new Error('Status not 200') }) |
229 | return callback_each_request() | ||
188 | } | 230 | } |
189 | }, | 231 | }, |
190 | 232 | ||
diff --git a/src/utils.js b/src/utils.js index d6b26db4b..dda6c7a0a 100644 --- a/src/utils.js +++ b/src/utils.js | |||
@@ -1,6 +1,7 @@ | |||
1 | ;(function () { | 1 | ;(function () { |
2 | 'use strict' | 2 | 'use strict' |
3 | 3 | ||
4 | var async = require('async') | ||
4 | var config = require('config') | 5 | var config = require('config') |
5 | var crypto = require('crypto') | 6 | var crypto = require('crypto') |
6 | var fs = require('fs') | 7 | var fs = require('fs') |
@@ -30,14 +31,15 @@ | |||
30 | } | 31 | } |
31 | 32 | ||
32 | logger.debug('Sending informations to %s.', to_pod.url, { params: params }) | 33 | logger.debug('Sending informations to %s.', to_pod.url, { params: params }) |
34 | // Default 10 but in tests we want to be faster | ||
35 | var retries = utils.isTestInstance() ? 2 : 10 | ||
33 | 36 | ||
34 | // Replay 15 times, with factor 3 | ||
35 | replay( | 37 | replay( |
36 | request.post(params, function (err, response, body) { | 38 | request.post(params, function (err, response, body) { |
37 | callbackEach(err, response, body, to_pod.url) | 39 | callbackEach(err, response, body, to_pod) |
38 | }), | 40 | }), |
39 | { | 41 | { |
40 | retries: 10, | 42 | retries: retries, |
41 | factor: 3, | 43 | factor: 3, |
42 | maxTimeout: Infinity, | 44 | maxTimeout: Infinity, |
43 | errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ] | 45 | errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ] |
@@ -68,7 +70,13 @@ | |||
68 | } | 70 | } |
69 | 71 | ||
70 | // Make a request for each pod | 72 | // Make a request for each pod |
71 | for (var pod of pods) { | 73 | async.each(pods, function (pod, callback_each_async) { |
74 | function callbackEachRetryRequest (err, response, body, pod) { | ||
75 | callbackEach(err, response, body, pod, function () { | ||
76 | callback_each_async() | ||
77 | }) | ||
78 | } | ||
79 | |||
72 | var params = { | 80 | var params = { |
73 | url: pod.url + all_data.path, | 81 | url: pod.url + all_data.path, |
74 | method: all_data.method | 82 | method: all_data.method |
@@ -93,20 +101,18 @@ | |||
93 | key: passwordEncrypted | 101 | key: passwordEncrypted |
94 | } | 102 | } |
95 | 103 | ||
96 | makeRetryRequest(copy_params, copy_url, copy_pod, copy_signature, callbackEach) | 104 | makeRetryRequest(copy_params, copy_url, copy_pod, copy_signature, callbackEachRetryRequest) |
97 | }) | 105 | }) |
98 | })(crt, params, url, pod, signature) | 106 | })(crt, params, url, pod, signature) |
99 | } else { | 107 | } else { |
100 | params.json = { data: all_data.data } | 108 | params.json = { data: all_data.data } |
101 | makeRetryRequest(params, url, pod, signature, callbackEach) | 109 | makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest) |
102 | } | 110 | } |
103 | } else { | 111 | } else { |
104 | logger.debug('Make a GET/DELETE request') | 112 | logger.debug('Make a GET/DELETE request') |
105 | makeRetryRequest(params, url, pod, signature, callbackEach) | 113 | makeRetryRequest(params, url, pod, signature, callbackEachRetryRequest) |
106 | } | 114 | } |
107 | } | 115 | }, callback) |
108 | |||
109 | return callback() | ||
110 | } | 116 | } |
111 | 117 | ||
112 | utils.certsExist = function (callback) { | 118 | utils.certsExist = function (callback) { |
@@ -192,5 +198,9 @@ | |||
192 | process.kill(-webtorrent_process.pid) | 198 | process.kill(-webtorrent_process.pid) |
193 | } | 199 | } |
194 | 200 | ||
201 | utils.isTestInstance = function () { | ||
202 | return (process.env.NODE_ENV === 'test') | ||
203 | } | ||
204 | |||
195 | module.exports = utils | 205 | module.exports = utils |
196 | })() | 206 | })() |
diff --git a/src/videos.js b/src/videos.js index b95219c39..8c44cad95 100644 --- a/src/videos.js +++ b/src/videos.js | |||
@@ -78,14 +78,9 @@ | |||
78 | data: params | 78 | data: params |
79 | } | 79 | } |
80 | 80 | ||
81 | pods.makeSecureRequest(data, function (err) { | 81 | // Do not wait the secure requests |
82 | if (err) { | 82 | pods.makeSecureRequest(data) |
83 | logger.error('Somes issues when sending this video to friends.', { error: err }) | 83 | callback(null) |
84 | return callback(err) | ||
85 | } | ||
86 | |||
87 | return callback(null) | ||
88 | }) | ||
89 | }) | 84 | }) |
90 | }) | 85 | }) |
91 | } | 86 | } |
@@ -138,14 +133,8 @@ | |||
138 | } | 133 | } |
139 | 134 | ||
140 | // Yes this is a POST request because we add some informations in the body (signature, encrypt etc) | 135 | // Yes this is a POST request because we add some informations in the body (signature, encrypt etc) |
141 | pods.makeSecureRequest(data, function (err) { | 136 | pods.makeSecureRequest(data) |
142 | if (err) { | 137 | callback(null) |
143 | logger.error('Somes issues when sending we want to remove the video to friends.', { error: err }) | ||
144 | return callback(err) | ||
145 | } | ||
146 | |||
147 | callback(null) | ||
148 | }) | ||
149 | }) | 138 | }) |
150 | }) | 139 | }) |
151 | }) | 140 | }) |