Add a pool of requests instead of making a request at each action (add
video/remove video) for performance in big networks
This commit is contained in:
parent
af82cae07d
commit
0b69752270
|
@ -18,10 +18,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
remote.remoteVideosAdd = function (req, res, next) {
|
remote.remoteVideosAdd = function (req, res, next) {
|
||||||
req.checkBody('data.name', 'Should have a name').isLength(1, 50)
|
req.checkBody('data').isArray()
|
||||||
req.checkBody('data.description', 'Should have a description').isLength(1, 250)
|
req.checkBody('data').eachIsRemoteVideosAddValid()
|
||||||
req.checkBody('data.magnetUri', 'Should have a magnetUri').notEmpty()
|
|
||||||
req.checkBody('data.podUrl', 'Should have a podUrl').isURL()
|
|
||||||
|
|
||||||
logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body })
|
logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
@ -29,7 +27,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
remote.remoteVideosRemove = function (req, res, next) {
|
remote.remoteVideosRemove = function (req, res, next) {
|
||||||
req.checkBody('data.magnetUri', 'Should have a magnetUri').notEmpty()
|
req.checkBody('data').isArray()
|
||||||
|
req.checkBody('data').eachIsRemoteVideosRemoveValid()
|
||||||
|
|
||||||
logger.debug('Checking remoteVideosRemove parameters', { parameters: req.body })
|
logger.debug('Checking remoteVideosRemove parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
"jquery": "^2.1.4",
|
"jquery": "^2.1.4",
|
||||||
"js-yaml": "^3.3.1",
|
"js-yaml": "^3.3.1",
|
||||||
"load-grunt-tasks": "^3.3.0",
|
"load-grunt-tasks": "^3.3.0",
|
||||||
|
"lodash-node": "3.10.1",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mongoose": "^4.0.5",
|
"mongoose": "^4.0.5",
|
||||||
"morgan": "^1.5.3",
|
"morgan": "^1.5.3",
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
"segfault-handler": "^0.2.4",
|
"segfault-handler": "^0.2.4",
|
||||||
"time-grunt": "^1.2.1",
|
"time-grunt": "^1.2.1",
|
||||||
"ursa": "^0.9.1",
|
"ursa": "^0.9.1",
|
||||||
|
"validator": "^4.3.0",
|
||||||
"webtorrent": "*",
|
"webtorrent": "*",
|
||||||
"winston": "^1.0.1",
|
"winston": "^1.0.1",
|
||||||
"ws": "^0.8.0"
|
"ws": "^0.8.0"
|
||||||
|
|
|
@ -3,21 +3,23 @@
|
||||||
|
|
||||||
var express = require('express')
|
var express = require('express')
|
||||||
var router = express.Router()
|
var router = express.Router()
|
||||||
|
var pluck = require('lodash-node/compat/collection/pluck')
|
||||||
|
|
||||||
var middleware = require('../../../middlewares')
|
var middleware = require('../../../middlewares')
|
||||||
var miscMiddleware = middleware.misc
|
var miscMiddleware = middleware.misc
|
||||||
var reqValidator = middleware.reqValidators.remote
|
var reqValidator = middleware.reqValidators.remote
|
||||||
var videos = require('../../../src/videos')
|
var videos = require('../../../src/videos')
|
||||||
|
|
||||||
function addRemoteVideos (req, res, next) {
|
function addRemoteVideos (req, res, next) {
|
||||||
videos.addRemote(req.body.data, function (err, video) {
|
videos.addRemotes(req.body.data, function (err, videos) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
||||||
res.json(video)
|
res.json(videos)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRemoteVideo (req, res, next) {
|
function removeRemoteVideo (req, res, next) {
|
||||||
videos.removeRemote(req.body.signature.url, req.body.data.magnetUri, function (err) {
|
videos.removeRemotes(req.body.signature.url, pluck(req.body.data, 'magnetUri'), function (err) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
||||||
res.status(204)
|
res.status(204)
|
||||||
|
|
|
@ -35,7 +35,9 @@
|
||||||
|
|
||||||
// ----------- PeerTube modules -----------
|
// ----------- PeerTube modules -----------
|
||||||
var config = require('config')
|
var config = require('config')
|
||||||
|
var customValidators = require('./src/customValidators')
|
||||||
var logger = require('./src/logger')
|
var logger = require('./src/logger')
|
||||||
|
var poolRequests = require('./src/poolRequests')
|
||||||
var routes = require('./routes')
|
var routes = require('./routes')
|
||||||
var videos = require('./src/videos')
|
var videos = require('./src/videos')
|
||||||
var webtorrent = require('./src/webTorrentNode')
|
var webtorrent = require('./src/webTorrentNode')
|
||||||
|
@ -56,7 +58,9 @@
|
||||||
app.use(multer({ dest: uploads }))
|
app.use(multer({ dest: uploads }))
|
||||||
app.use(bodyParser.urlencoded({ extended: false }))
|
app.use(bodyParser.urlencoded({ extended: false }))
|
||||||
// Validate some params for the API
|
// Validate some params for the API
|
||||||
app.use(expressValidator())
|
app.use(expressValidator({
|
||||||
|
customValidators: customValidators
|
||||||
|
}))
|
||||||
|
|
||||||
// ----------- Views, routes and static files -----------
|
// ----------- Views, routes and static files -----------
|
||||||
|
|
||||||
|
@ -154,6 +158,9 @@
|
||||||
|
|
||||||
// ----------- Make the server listening -----------
|
// ----------- Make the server listening -----------
|
||||||
server.listen(port, function () {
|
server.listen(port, function () {
|
||||||
|
// Activate the pool requests
|
||||||
|
poolRequests.activate()
|
||||||
|
|
||||||
videos.seedAll(function () {
|
videos.seedAll(function () {
|
||||||
logger.info('Seeded all the videos')
|
logger.info('Seeded all the videos')
|
||||||
logger.info('Server listening on port %d', port)
|
logger.info('Server listening on port %d', port)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
;(function () {
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
var validator = require('validator')
|
||||||
|
|
||||||
|
var customValidators = {}
|
||||||
|
|
||||||
|
customValidators.eachIsRemoteVideosAddValid = function (values) {
|
||||||
|
return values.every(function (val) {
|
||||||
|
return validator.isLength(val.name, 1, 50) &&
|
||||||
|
validator.isLength(val.description, 1, 50) &&
|
||||||
|
validator.isLength(val.magnetUri, 10) &&
|
||||||
|
validator.isURL(val.podUrl)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
customValidators.eachIsRemoteVideosRemoveValid = function (values) {
|
||||||
|
return values.every(function (val) {
|
||||||
|
return validator.isLength(val.magnetUri, 10)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
customValidators.isArray = function (value) {
|
||||||
|
return Array.isArray(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Export -----------
|
||||||
|
module.exports = customValidators
|
||||||
|
})()
|
|
@ -30,6 +30,15 @@
|
||||||
|
|
||||||
var PodsDB = mongoose.model('pods', podsSchema)
|
var PodsDB = mongoose.model('pods', podsSchema)
|
||||||
|
|
||||||
|
// ----------- PoolRequests -----------
|
||||||
|
var poolRequestsSchema = mongoose.Schema({
|
||||||
|
type: String,
|
||||||
|
id: String, // Special id to find duplicates (video created we want to remove...)
|
||||||
|
request: mongoose.Schema.Types.Mixed
|
||||||
|
})
|
||||||
|
|
||||||
|
var PoolRequestsDB = mongoose.model('poolRequests', poolRequestsSchema)
|
||||||
|
|
||||||
// ----------- Connection -----------
|
// ----------- Connection -----------
|
||||||
|
|
||||||
mongoose.connect('mongodb://' + host + ':' + port + '/' + dbname)
|
mongoose.connect('mongodb://' + host + ':' + port + '/' + dbname)
|
||||||
|
@ -45,6 +54,7 @@
|
||||||
// ----------- Export -----------
|
// ----------- Export -----------
|
||||||
module.exports = {
|
module.exports = {
|
||||||
VideosDB: VideosDB,
|
VideosDB: VideosDB,
|
||||||
PodsDB: PodsDB
|
PodsDB: PodsDB,
|
||||||
|
PoolRequestsDB: PoolRequestsDB
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
89
src/pods.js
89
src/pods.js
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
var logger = require('./logger')
|
var logger = require('./logger')
|
||||||
var PodsDB = require('./database').PodsDB
|
var PodsDB = require('./database').PodsDB
|
||||||
|
var poolRequests = require('./poolRequests')
|
||||||
var utils = require('./utils')
|
var utils = require('./utils')
|
||||||
|
|
||||||
var pods = {}
|
var pods = {}
|
||||||
|
@ -16,13 +17,6 @@
|
||||||
var host = config.get('webserver.host')
|
var host = config.get('webserver.host')
|
||||||
var port = config.get('webserver.port')
|
var port = config.get('webserver.port')
|
||||||
|
|
||||||
// ----------- Constants -----------
|
|
||||||
|
|
||||||
var PODS_SCORE = {
|
|
||||||
MALUS: -10,
|
|
||||||
BONUS: 10
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------- Private functions -----------
|
// ----------- Private functions -----------
|
||||||
|
|
||||||
function getForeignPodsList (url, callback) {
|
function getForeignPodsList (url, callback) {
|
||||||
|
@ -34,25 +28,6 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePodsScore (good_pods, bad_pods) {
|
|
||||||
logger.info('Updating %d good pods and %d bad pods scores.', good_pods.length, bad_pods.length)
|
|
||||||
|
|
||||||
PodsDB.update({ _id: { $in: good_pods } }, { $inc: { score: PODS_SCORE.BONUS } }, { multi: true }).exec()
|
|
||||||
PodsDB.update({ _id: { $in: bad_pods } }, { $inc: { score: PODS_SCORE.MALUS } }, { multi: true }, function (err) {
|
|
||||||
if (err) throw err
|
|
||||||
removeBadPods()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeBadPods () {
|
|
||||||
PodsDB.remove({ score: 0 }, function (err, result) {
|
|
||||||
if (err) throw err
|
|
||||||
|
|
||||||
var number_removed = result.result.n
|
|
||||||
if (number_removed !== 0) logger.info('Removed %d pod.', number_removed)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------- Public functions -----------
|
// ----------- Public functions -----------
|
||||||
|
|
||||||
pods.list = function (callback) {
|
pods.list = function (callback) {
|
||||||
|
@ -93,58 +68,16 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// { path, data }
|
pods.addVideoToFriends = function (video) {
|
||||||
pods.makeSecureRequest = function (data, callback) {
|
// To avoid duplicates
|
||||||
if (callback === undefined) callback = function () {}
|
var id = video.name + video.magnetUri
|
||||||
|
poolRequests.addToPoolRequests(id, 'add', video)
|
||||||
|
}
|
||||||
|
|
||||||
PodsDB.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err, pods) {
|
pods.removeVideoToFriends = function (video) {
|
||||||
if (err) {
|
// To avoid duplicates
|
||||||
logger.error('Cannot get the list of the pods.', { error: err })
|
var id = video.name + video.magnetUri
|
||||||
return callback(err)
|
poolRequests.addToPoolRequests(id, 'remove', video)
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug('Make multiple requests.')
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
encrypt: true,
|
|
||||||
sign: true,
|
|
||||||
method: data.method,
|
|
||||||
path: data.path,
|
|
||||||
data: data.data
|
|
||||||
}
|
|
||||||
|
|
||||||
var bad_pods = []
|
|
||||||
var good_pods = []
|
|
||||||
|
|
||||||
utils.makeMultipleRetryRequest(
|
|
||||||
params,
|
|
||||||
|
|
||||||
pods,
|
|
||||||
|
|
||||||
function callbackEachPodFinished (err, response, body, pod, callback_each_pod_finished) {
|
|
||||||
if (err || response.statusCode !== 200) {
|
|
||||||
bad_pods.push(pod._id)
|
|
||||||
logger.error('Error sending secure request to %s/%s pod.', pod.url, data.path, { error: err })
|
|
||||||
} else {
|
|
||||||
good_pods.push(pod._id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback_each_pod_finished()
|
|
||||||
},
|
|
||||||
|
|
||||||
function callbackAllPodsFinished (err) {
|
|
||||||
if (err) {
|
|
||||||
logger.error('There was some errors when sending the video meta data.', { error: err })
|
|
||||||
return callback(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug('Finished')
|
|
||||||
|
|
||||||
updatePodsScore(good_pods, bad_pods)
|
|
||||||
callback(null)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pods.makeFriends = function (callback) {
|
pods.makeFriends = function (callback) {
|
||||||
|
@ -214,7 +147,7 @@
|
||||||
|
|
||||||
pods_list,
|
pods_list,
|
||||||
|
|
||||||
function eachRequest (err, response, body, pod, callback_each_request) {
|
function eachRequest (err, response, body, url, pod, callback_each_request) {
|
||||||
// We add the pod if it responded correctly with its public certificate
|
// We add the pod if it responded correctly with its public certificate
|
||||||
if (!err && response.statusCode === 200) {
|
if (!err && response.statusCode === 200) {
|
||||||
pods.add({ url: pod.url, publicKey: body.cert, score: global.FRIEND_BASE_SCORE }, function (err) {
|
pods.add({ url: pod.url, publicKey: body.cert, score: global.FRIEND_BASE_SCORE }, function (err) {
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
;(function () {
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
var async = require('async')
|
||||||
|
|
||||||
|
var logger = require('./logger')
|
||||||
|
var database = require('./database')
|
||||||
|
var PoolRequestsDB = database.PoolRequestsDB
|
||||||
|
var PodsDB = database.PodsDB
|
||||||
|
var utils = require('./utils')
|
||||||
|
|
||||||
|
var poolRequests = {}
|
||||||
|
|
||||||
|
// ----------- Constants -----------
|
||||||
|
|
||||||
|
// Time to wait between requests to the friends
|
||||||
|
var INTERVAL = utils.isTestInstance() ? 10000 : 60000
|
||||||
|
var PODS_SCORE = {
|
||||||
|
MALUS: -10,
|
||||||
|
BONUS: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Private -----------
|
||||||
|
var timer = null
|
||||||
|
|
||||||
|
function makePoolRequests () {
|
||||||
|
logger.info('Making pool requests to friends.')
|
||||||
|
|
||||||
|
PoolRequestsDB.find({}, { type: 1, request: 1 }, function (err, pool_requests) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
var requests = {
|
||||||
|
add: [],
|
||||||
|
remove: []
|
||||||
|
}
|
||||||
|
|
||||||
|
async.each(pool_requests, function (pool_request, callback_each) {
|
||||||
|
if (pool_request.type === 'add') {
|
||||||
|
requests.add.push(pool_request.request)
|
||||||
|
} else if (pool_request.type === 'remove') {
|
||||||
|
requests.remove.push(pool_request.request)
|
||||||
|
} else {
|
||||||
|
throw new Error('Unkown pool request type.')
|
||||||
|
}
|
||||||
|
|
||||||
|
callback_each()
|
||||||
|
}, function () {
|
||||||
|
makePoolRequest('add', requests.add)
|
||||||
|
makePoolRequest('remove', requests.remove)
|
||||||
|
logger.info('Pool requests to friends sent.')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePodsScore (good_pods, bad_pods) {
|
||||||
|
logger.info('Updating %d good pods and %d bad pods scores.', good_pods.length, bad_pods.length)
|
||||||
|
|
||||||
|
PodsDB.update({ _id: { $in: good_pods } }, { $inc: { score: PODS_SCORE.BONUS } }, { multi: true }).exec()
|
||||||
|
PodsDB.update({ _id: { $in: bad_pods } }, { $inc: { score: PODS_SCORE.MALUS } }, { multi: true }, function (err) {
|
||||||
|
if (err) throw err
|
||||||
|
removeBadPods()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeBadPods () {
|
||||||
|
PodsDB.remove({ score: 0 }, function (err, result) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
var number_removed = result.result.n
|
||||||
|
if (number_removed !== 0) logger.info('Removed %d pod.', number_removed)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function makePoolRequest (type, requests) {
|
||||||
|
logger.debug('Make pool requests scheduled.')
|
||||||
|
PodsDB.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err, pods) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
encrypt: true,
|
||||||
|
sign: true,
|
||||||
|
method: 'POST',
|
||||||
|
path: null,
|
||||||
|
data: requests
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'add') {
|
||||||
|
params.path = '/api/' + global.API_VERSION + '/remotevideos/add'
|
||||||
|
} else if (type === 'remove') {
|
||||||
|
params.path = '/api/' + global.API_VERSION + '/remotevideos/remove'
|
||||||
|
} else {
|
||||||
|
throw new Error('Unkown pool request type.')
|
||||||
|
}
|
||||||
|
|
||||||
|
var bad_pods = []
|
||||||
|
var good_pods = []
|
||||||
|
|
||||||
|
utils.makeMultipleRetryRequest(params, pods, callbackEachPodFinished, callbackAllPodsFinished)
|
||||||
|
|
||||||
|
function callbackEachPodFinished (err, response, body, url, pod, callback_each_pod_finished) {
|
||||||
|
if (err || response.statusCode !== 200) {
|
||||||
|
bad_pods.push(pod._id)
|
||||||
|
logger.error('Error sending secure request to %s pod.', url, { error: err })
|
||||||
|
} else {
|
||||||
|
good_pods.push(pod._id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback_each_pod_finished()
|
||||||
|
}
|
||||||
|
|
||||||
|
function callbackAllPodsFinished (err) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('There was some errors when sending the video meta data.', { error: err })
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePodsScore(good_pods, bad_pods)
|
||||||
|
PoolRequestsDB.remove().exec()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Public -----------
|
||||||
|
poolRequests.activate = function () {
|
||||||
|
logger.info('Pool requests activated.')
|
||||||
|
timer = setInterval(makePoolRequests, INTERVAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
poolRequests.addToPoolRequests = function (id, type, request) {
|
||||||
|
logger.debug('Add request to the pool requests.', { id: id, type: type, request: request })
|
||||||
|
|
||||||
|
PoolRequestsDB.findOne({ id: id }, function (err, entity) {
|
||||||
|
if (err) logger.error(err)
|
||||||
|
|
||||||
|
if (entity) {
|
||||||
|
if (entity.type === type) {
|
||||||
|
logger.error(new Error('Cannot insert two same requests.'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the request of the other type
|
||||||
|
PoolRequestsDB.remove({ id: id }, function (err) {
|
||||||
|
if (err) logger.error(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
PoolRequestsDB.create({ id: id, type: type, request: request }, function (err) {
|
||||||
|
if (err) logger.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
poolRequests.deactivate = function () {
|
||||||
|
logger.info('Pool requests deactivated.')
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = poolRequests
|
||||||
|
})()
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
replay(
|
replay(
|
||||||
request.post(params, function (err, response, body) {
|
request.post(params, function (err, response, body) {
|
||||||
callbackEach(err, response, body, to_pod)
|
callbackEach(err, response, body, params.url, to_pod)
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
retries: retries,
|
retries: retries,
|
||||||
|
@ -71,8 +71,8 @@
|
||||||
|
|
||||||
// Make a request for each pod
|
// Make a request for each pod
|
||||||
async.each(pods, function (pod, callback_each_async) {
|
async.each(pods, function (pod, callback_each_async) {
|
||||||
function callbackEachRetryRequest (err, response, body, pod) {
|
function callbackEachRetryRequest (err, response, body, url, pod) {
|
||||||
callbackEach(err, response, body, pod, function () {
|
callbackEach(err, response, body, url, pod, function () {
|
||||||
callback_each_async()
|
callback_each_async()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
var async = require('async')
|
var async = require('async')
|
||||||
var config = require('config')
|
var config = require('config')
|
||||||
|
var dz = require('dezalgo')
|
||||||
var fs = require('fs')
|
var fs = require('fs')
|
||||||
var webtorrent = require('./webTorrentNode')
|
var webtorrent = require('./webTorrentNode')
|
||||||
|
|
||||||
|
@ -67,19 +68,10 @@
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we'll send the video's meta data
|
// Now we'll add the video's meta data to our friends
|
||||||
params.namePath = null
|
params.namePath = null
|
||||||
|
|
||||||
logger.info('Sending %s video to friends.', video_file.path)
|
pods.addVideoToFriends(params)
|
||||||
|
|
||||||
var data = {
|
|
||||||
path: '/api/' + global.API_VERSION + '/remotevideos/add',
|
|
||||||
method: 'POST',
|
|
||||||
data: params
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not wait the secure requests
|
|
||||||
pods.makeSecureRequest(data)
|
|
||||||
callback(null)
|
callback(null)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -124,16 +116,12 @@
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = {
|
var params = {
|
||||||
path: '/api/' + global.API_VERSION + '/remotevideos/remove',
|
name: video.name,
|
||||||
method: 'POST',
|
magnetUri: video.magnetUri
|
||||||
data: {
|
|
||||||
magnetUri: video.magnetUri
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yes this is a POST request because we add some informations in the body (signature, encrypt etc)
|
pods.removeVideoToFriends(params)
|
||||||
pods.makeSecureRequest(data)
|
|
||||||
callback(null)
|
callback(null)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -142,49 +130,65 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the magnet Uri because the _id field is not the same on different servers
|
// Use the magnet Uri because the _id field is not the same on different servers
|
||||||
videos.removeRemote = function (fromUrl, magnetUri, callback) {
|
videos.removeRemotes = function (fromUrl, magnetUris, callback) {
|
||||||
VideosDB.findOne({ magnetUri: magnetUri }, function (err, video) {
|
VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) {
|
||||||
if (err || !video) {
|
if (err || !videos) {
|
||||||
logger.error('Cannot find the torrent URI of this remote video.')
|
logger.error('Cannot find the torrent URI of these remote videos.')
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to reqValidators middleware ?
|
var to_remove = []
|
||||||
if (video.podUrl !== fromUrl) {
|
async.each(videos, function (video, callback_async) {
|
||||||
logger.error('The pod has not the rights on this video.')
|
callback_async = dz(callback_async)
|
||||||
return callback(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
VideosDB.findByIdAndRemove(video._id, function (err) {
|
if (video.podUrl !== fromUrl) {
|
||||||
if (err) {
|
logger.error('The pod %s has not the rights on the video of %s.', fromUrl, video.podUrl)
|
||||||
logger.error('Cannot remove the remote video.')
|
} else {
|
||||||
return callback(err)
|
to_remove.push(video._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null)
|
callback_async()
|
||||||
|
}, function () {
|
||||||
|
VideosDB.remove({ _id: { $in: to_remove } }, function (err) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Cannot remove the remote videos.')
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// { name, magnetUri, podUrl }
|
// { name, magnetUri, podUrl }
|
||||||
videos.addRemote = function (data, callback) {
|
videos.addRemotes = function (videos, callback) {
|
||||||
logger.debug('Add remote video from pod: %s', data.podUrl)
|
var to_add = []
|
||||||
|
|
||||||
var params = {
|
async.each(videos, function (video, callback_each) {
|
||||||
name: data.name,
|
callback_each = dz(callback_each)
|
||||||
namePath: null,
|
logger.debug('Add remote video from pod: %s', video.podUrl)
|
||||||
description: data.description,
|
|
||||||
magnetUri: data.magnetUri,
|
|
||||||
podUrl: data.podUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
VideosDB.create(params, function (err, video) {
|
var params = {
|
||||||
if (err) {
|
name: video.name,
|
||||||
logger.error('Cannot insert this remote video.', { error: err })
|
namePath: null,
|
||||||
return callback(err)
|
description: video.description,
|
||||||
|
magnetUri: video.magnetUri,
|
||||||
|
podUrl: video.podUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
return callback(null, video)
|
to_add.push(params)
|
||||||
|
|
||||||
|
callback_each()
|
||||||
|
}, function () {
|
||||||
|
VideosDB.create(to_add, function (err, videos) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Cannot insert this remote video.', { error: err })
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, videos)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,9 +103,9 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should make friends with the pods 1, 2, 3', function (done) {
|
it('Should make friends with the pods 1, 2, 3', function (done) {
|
||||||
this.timeout(100000)
|
this.timeout(150000)
|
||||||
|
|
||||||
// Pods 1, 2, 3 and 4 become friends
|
// Pods 1, 2, 3 and 4 become friends (yes this is beautiful)
|
||||||
makeFriend(2, function () {
|
makeFriend(2, function () {
|
||||||
makeFriend(1, function () {
|
makeFriend(1, function () {
|
||||||
makeFriend(4, function () {
|
makeFriend(4, function () {
|
||||||
|
@ -114,37 +114,45 @@
|
||||||
|
|
||||||
// Expulse pod 4 from pod 1 and 2
|
// Expulse pod 4 from pod 1 and 2
|
||||||
uploadVideo(1, function () {
|
uploadVideo(1, function () {
|
||||||
uploadVideo(1, function () {
|
setTimeout(function () {
|
||||||
uploadVideo(2, function () {
|
uploadVideo(1, function () {
|
||||||
uploadVideo(2, function () {
|
setTimeout(function () {
|
||||||
// Rerun server 4
|
uploadVideo(2, function () {
|
||||||
utils.runServer(4, function (app, url) {
|
setTimeout(function () {
|
||||||
apps[3] = app
|
uploadVideo(2, function () {
|
||||||
getFriendsList(4, function (err, res) {
|
setTimeout(function () {
|
||||||
if (err) throw err
|
// Rerun server 4
|
||||||
// Pod 4 didn't know pod 1 and 2 removed it
|
utils.runServer(4, function (app, url) {
|
||||||
expect(res.body.length).to.equal(3)
|
apps[3] = app
|
||||||
|
getFriendsList(4, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
// Pod 4 didn't know pod 1 and 2 removed it
|
||||||
|
expect(res.body.length).to.equal(3)
|
||||||
|
|
||||||
// Pod 6 ask pod 1, 2 and 3
|
// Pod 6 ask pod 1, 2 and 3
|
||||||
makeFriend(6, function () {
|
makeFriend(6, function () {
|
||||||
getFriendsList(6, function (err, res) {
|
getFriendsList(6, function (err, res) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
// Pod 4 should not be our friend
|
// Pod 4 should not be our friend
|
||||||
var result = res.body
|
var result = res.body
|
||||||
expect(result.length).to.equal(3)
|
expect(result.length).to.equal(3)
|
||||||
for (var pod of result) {
|
for (var pod of result) {
|
||||||
expect(pod.url).not.equal(urls[3])
|
expect(pod.url).not.equal(urls[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
var path = '/api/v1/videos'
|
var path = '/api/v1/videos'
|
||||||
var apps = []
|
var apps = []
|
||||||
var urls = []
|
var urls = []
|
||||||
var video_id = -1
|
var to_remove = []
|
||||||
|
|
||||||
function getVideosList (url, end) {
|
function getVideosList (url, end) {
|
||||||
request(url)
|
request(url)
|
||||||
|
@ -36,6 +36,14 @@
|
||||||
.end(end)
|
.end(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeVideo (url, id, end) {
|
||||||
|
request(url)
|
||||||
|
.delete(path + '/' + id)
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.expect(204)
|
||||||
|
.end(end)
|
||||||
|
}
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
this.timeout(30000)
|
this.timeout(30000)
|
||||||
var path_friends = '/api/v1/pods/makefriends'
|
var path_friends = '/api/v1/pods/makefriends'
|
||||||
|
@ -89,7 +97,7 @@
|
||||||
|
|
||||||
describe('Should upload the video and propagate on each pod', function () {
|
describe('Should upload the video and propagate on each pod', function () {
|
||||||
it('Should upload the video on pod 1 and propagate on each pod', function (done) {
|
it('Should upload the video on pod 1 and propagate on each pod', function (done) {
|
||||||
this.timeout(5000)
|
this.timeout(15000)
|
||||||
|
|
||||||
uploadVideo(urls[0], 'my super name for pod 1', 'my super description for pod 1', 'video_short1.webm', function (err) {
|
uploadVideo(urls[0], 'my super name for pod 1', 'my super description for pod 1', 'video_short1.webm', function (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
@ -125,12 +133,12 @@
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
}, 1000)
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should upload the video on pod 2 and propagate on each pod', function (done) {
|
it('Should upload the video on pod 2 and propagate on each pod', function (done) {
|
||||||
this.timeout(5000)
|
this.timeout(15000)
|
||||||
|
|
||||||
uploadVideo(urls[1], 'my super name for pod 2', 'my super description for pod 2', 'video_short2.webm', function (err) {
|
uploadVideo(urls[1], 'my super name for pod 2', 'my super description for pod 2', 'video_short2.webm', function (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
@ -166,47 +174,56 @@
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
}, 1000)
|
}, 11000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should upload the video on pod 3 and propagate on each pod', function (done) {
|
it('Should upload two videos on pod 3 and propagate on each pod', function (done) {
|
||||||
this.timeout(5000)
|
this.timeout(15000)
|
||||||
|
|
||||||
uploadVideo(urls[2], 'my super name for pod 3', 'my super description for pod 3', 'video_short3.webm', function (err) {
|
uploadVideo(urls[2], 'my super name for pod 3', 'my super description for pod 3', 'video_short3.webm', function (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
uploadVideo(urls[2], 'my super name for pod 3-2', 'my super description for pod 3-2', 'video_short.webm', function (err) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var base_magnet = null
|
var base_magnet = null
|
||||||
// All pods should have this video
|
// All pods should have this video
|
||||||
async.each(urls, function (url, callback) {
|
async.each(urls, function (url, callback) {
|
||||||
getVideosList(url, function (err, res) {
|
getVideosList(url, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
var videos = res.body
|
||||||
|
expect(videos).to.be.an('array')
|
||||||
|
expect(videos.length).to.equal(4)
|
||||||
|
var video = videos[2]
|
||||||
|
expect(video.name).to.equal('my super name for pod 3')
|
||||||
|
expect(video.description).to.equal('my super description for pod 3')
|
||||||
|
expect(video.podUrl).to.equal('http://localhost:9003')
|
||||||
|
expect(video.magnetUri).to.exist
|
||||||
|
|
||||||
|
video = videos[3]
|
||||||
|
expect(video.name).to.equal('my super name for pod 3-2')
|
||||||
|
expect(video.description).to.equal('my super description for pod 3-2')
|
||||||
|
expect(video.podUrl).to.equal('http://localhost:9003')
|
||||||
|
expect(video.magnetUri).to.exist
|
||||||
|
|
||||||
|
// All pods should have the same magnet Uri
|
||||||
|
if (base_magnet === null) {
|
||||||
|
base_magnet = video.magnetUri
|
||||||
|
} else {
|
||||||
|
expect(video.magnetUri).to.equal.magnetUri
|
||||||
|
}
|
||||||
|
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}, function (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
var videos = res.body
|
done()
|
||||||
expect(videos).to.be.an('array')
|
|
||||||
expect(videos.length).to.equal(3)
|
|
||||||
var video = videos[2]
|
|
||||||
expect(video.name).to.equal('my super name for pod 3')
|
|
||||||
expect(video.description).to.equal('my super description for pod 3')
|
|
||||||
expect(video.podUrl).to.equal('http://localhost:9003')
|
|
||||||
expect(video.magnetUri).to.exist
|
|
||||||
|
|
||||||
// All pods should have the same magnet Uri
|
|
||||||
if (base_magnet === null) {
|
|
||||||
base_magnet = video.magnetUri
|
|
||||||
} else {
|
|
||||||
expect(video.magnetUri).to.equal.magnetUri
|
|
||||||
}
|
|
||||||
|
|
||||||
callback()
|
|
||||||
})
|
})
|
||||||
}, function (err) {
|
}, 11000)
|
||||||
if (err) throw err
|
})
|
||||||
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
}, 1000)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -220,6 +237,9 @@
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
var video = res.body[0]
|
var video = res.body[0]
|
||||||
|
to_remove.push(res.body[2]._id)
|
||||||
|
to_remove.push(res.body[3]._id)
|
||||||
|
|
||||||
webtorrent.add(video.magnetUri, function (torrent) {
|
webtorrent.add(video.magnetUri, function (torrent) {
|
||||||
expect(torrent.files).to.exist
|
expect(torrent.files).to.exist
|
||||||
expect(torrent.files.length).to.equal(1)
|
expect(torrent.files.length).to.equal(1)
|
||||||
|
@ -257,7 +277,6 @@
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
var video = res.body[2]
|
var video = res.body[2]
|
||||||
video_id = res.body[1]._id
|
|
||||||
|
|
||||||
webtorrent.add(video.magnetUri, function (torrent) {
|
webtorrent.add(video.magnetUri, function (torrent) {
|
||||||
expect(torrent.files).to.exist
|
expect(torrent.files).to.exist
|
||||||
|
@ -269,19 +288,39 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should remove the file 2 by asking pod 2', function (done) {
|
it('Should add the file 3-2 by asking pod 1', function (done) {
|
||||||
request(urls[1])
|
// Yes, this could be long
|
||||||
.delete(path + '/' + video_id)
|
this.timeout(200000)
|
||||||
.set('Accept', 'application/json')
|
|
||||||
.expect(204)
|
getVideosList(urls[0], function (err, res) {
|
||||||
.end(function (err, res) {
|
if (err) throw err
|
||||||
|
|
||||||
|
var video = res.body[3]
|
||||||
|
|
||||||
|
webtorrent.add(video.magnetUri, function (torrent) {
|
||||||
|
expect(torrent.files).to.exist
|
||||||
|
expect(torrent.files.length).to.equal(1)
|
||||||
|
expect(torrent.files[0].path).to.exist.and.to.not.equal('')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should remove the file 3 and 3-2 by asking pod 3', function (done) {
|
||||||
|
this.timeout(15000)
|
||||||
|
|
||||||
|
removeVideo(urls[2], to_remove[0], function (err) {
|
||||||
|
if (err) throw err
|
||||||
|
removeVideo(urls[2], to_remove[1], function (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
// Wait the propagation to the other pods
|
// Wait the propagation to the other pods
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
done()
|
done()
|
||||||
}, 1000)
|
}, 11000)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should have videos 1 and 3 on each pod', function (done) {
|
it('Should have videos 1 and 3 on each pod', function (done) {
|
||||||
|
@ -293,8 +332,10 @@
|
||||||
expect(videos).to.be.an('array')
|
expect(videos).to.be.an('array')
|
||||||
expect(videos.length).to.equal(2)
|
expect(videos.length).to.equal(2)
|
||||||
expect(videos[0]._id).not.to.equal(videos[1]._id)
|
expect(videos[0]._id).not.to.equal(videos[1]._id)
|
||||||
expect(videos[0]._id).not.to.equal(video_id)
|
expect(videos[0]._id).not.to.equal(to_remove[0])
|
||||||
expect(videos[1]._id).not.to.equal(video_id)
|
expect(videos[1]._id).not.to.equal(to_remove[0])
|
||||||
|
expect(videos[0]._id).not.to.equal(to_remove[1])
|
||||||
|
expect(videos[1]._id).not.to.equal(to_remove[1])
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue