aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2015-11-24 08:33:59 +0100
committerChocobozzz <florian.bigard@gmail.com>2015-11-24 08:33:59 +0100
commit3bcb78b3aff565996ee0e2aa96bce7f1bdd6d66a (patch)
treeb202172a35956b252282105f614fc9646ca64ebb /src
parent2e3b5b0db652ae4787e359aadbd4f52e473b6af7 (diff)
downloadPeerTube-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.js3
-rw-r--r--src/pods.js64
-rw-r--r--src/utils.js30
-rw-r--r--src/videos.js21
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 })