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
12 changed files with 403 additions and 210 deletions
|
@ -18,10 +18,8 @@
|
|||
}
|
||||
|
||||
remote.remoteVideosAdd = function (req, res, next) {
|
||||
req.checkBody('data.name', 'Should have a name').isLength(1, 50)
|
||||
req.checkBody('data.description', 'Should have a description').isLength(1, 250)
|
||||
req.checkBody('data.magnetUri', 'Should have a magnetUri').notEmpty()
|
||||
req.checkBody('data.podUrl', 'Should have a podUrl').isURL()
|
||||
req.checkBody('data').isArray()
|
||||
req.checkBody('data').eachIsRemoteVideosAddValid()
|
||||
|
||||
logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body })
|
||||
|
||||
|
@ -29,7 +27,8 @@
|
|||
}
|
||||
|
||||
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 })
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
"jquery": "^2.1.4",
|
||||
"js-yaml": "^3.3.1",
|
||||
"load-grunt-tasks": "^3.3.0",
|
||||
"lodash-node": "3.10.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mongoose": "^4.0.5",
|
||||
"morgan": "^1.5.3",
|
||||
|
@ -57,6 +58,7 @@
|
|||
"segfault-handler": "^0.2.4",
|
||||
"time-grunt": "^1.2.1",
|
||||
"ursa": "^0.9.1",
|
||||
"validator": "^4.3.0",
|
||||
"webtorrent": "*",
|
||||
"winston": "^1.0.1",
|
||||
"ws": "^0.8.0"
|
||||
|
|
|
@ -3,21 +3,23 @@
|
|||
|
||||
var express = require('express')
|
||||
var router = express.Router()
|
||||
var pluck = require('lodash-node/compat/collection/pluck')
|
||||
|
||||
var middleware = require('../../../middlewares')
|
||||
var miscMiddleware = middleware.misc
|
||||
var reqValidator = middleware.reqValidators.remote
|
||||
var videos = require('../../../src/videos')
|
||||
|
||||
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)
|
||||
|
||||
res.json(video)
|
||||
res.json(videos)
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
res.status(204)
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
|
||||
// ----------- PeerTube modules -----------
|
||||
var config = require('config')
|
||||
var customValidators = require('./src/customValidators')
|
||||
var logger = require('./src/logger')
|
||||
var poolRequests = require('./src/poolRequests')
|
||||
var routes = require('./routes')
|
||||
var videos = require('./src/videos')
|
||||
var webtorrent = require('./src/webTorrentNode')
|
||||
|
@ -56,7 +58,9 @@
|
|||
app.use(multer({ dest: uploads }))
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
// Validate some params for the API
|
||||
app.use(expressValidator())
|
||||
app.use(expressValidator({
|
||||
customValidators: customValidators
|
||||
}))
|
||||
|
||||
// ----------- Views, routes and static files -----------
|
||||
|
||||
|
@ -154,6 +158,9 @@
|
|||
|
||||
// ----------- Make the server listening -----------
|
||||
server.listen(port, function () {
|
||||
// Activate the pool requests
|
||||
poolRequests.activate()
|
||||
|
||||
videos.seedAll(function () {
|
||||
logger.info('Seeded all the videos')
|
||||
logger.info('Server listening on port %d', port)
|
||||
|
|
29
src/customValidators.js
Normal file
29
src/customValidators.js
Normal file
|
@ -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)
|
||||
|
||||
// ----------- 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 -----------
|
||||
|
||||
mongoose.connect('mongodb://' + host + ':' + port + '/' + dbname)
|
||||
|
@ -45,6 +54,7 @@
|
|||
// ----------- Export -----------
|
||||
module.exports = {
|
||||
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 PodsDB = require('./database').PodsDB
|
||||
var poolRequests = require('./poolRequests')
|
||||
var utils = require('./utils')
|
||||
|
||||
var pods = {}
|
||||
|
@ -16,13 +17,6 @@
|
|||
var host = config.get('webserver.host')
|
||||
var port = config.get('webserver.port')
|
||||
|
||||
// ----------- Constants -----------
|
||||
|
||||
var PODS_SCORE = {
|
||||
MALUS: -10,
|
||||
BONUS: 10
|
||||
}
|
||||
|
||||
// ----------- Private functions -----------
|
||||
|
||||
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 -----------
|
||||
|
||||
pods.list = function (callback) {
|
||||
|
@ -93,58 +68,16 @@
|
|||
})
|
||||
}
|
||||
|
||||
// { path, data }
|
||||
pods.makeSecureRequest = function (data, callback) {
|
||||
if (callback === undefined) callback = function () {}
|
||||
pods.addVideoToFriends = function (video) {
|
||||
// To avoid duplicates
|
||||
var id = video.name + video.magnetUri
|
||||
poolRequests.addToPoolRequests(id, 'add', video)
|
||||
}
|
||||
|
||||
PodsDB.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err, pods) {
|
||||
if (err) {
|
||||
logger.error('Cannot get the list of the pods.', { error: err })
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
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.removeVideoToFriends = function (video) {
|
||||
// To avoid duplicates
|
||||
var id = video.name + video.magnetUri
|
||||
poolRequests.addToPoolRequests(id, 'remove', video)
|
||||
}
|
||||
|
||||
pods.makeFriends = function (callback) {
|
||||
|
@ -214,7 +147,7 @@
|
|||
|
||||
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
|
||||
if (!err && response.statusCode === 200) {
|
||||
pods.add({ url: pod.url, publicKey: body.cert, score: global.FRIEND_BASE_SCORE }, function (err) {
|
||||
|
|
158
src/poolRequests.js
Normal file
158
src/poolRequests.js
Normal file
|
@ -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(
|
||||
request.post(params, function (err, response, body) {
|
||||
callbackEach(err, response, body, to_pod)
|
||||
callbackEach(err, response, body, params.url, to_pod)
|
||||
}),
|
||||
{
|
||||
retries: retries,
|
||||
|
@ -71,8 +71,8 @@
|
|||
|
||||
// Make a request for each pod
|
||||
async.each(pods, function (pod, callback_each_async) {
|
||||
function callbackEachRetryRequest (err, response, body, pod) {
|
||||
callbackEach(err, response, body, pod, function () {
|
||||
function callbackEachRetryRequest (err, response, body, url, pod) {
|
||||
callbackEach(err, response, body, url, pod, function () {
|
||||
callback_each_async()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
var async = require('async')
|
||||
var config = require('config')
|
||||
var dz = require('dezalgo')
|
||||
var fs = require('fs')
|
||||
var webtorrent = require('./webTorrentNode')
|
||||
|
||||
|
@ -67,19 +68,10 @@
|
|||
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
|
||||
|
||||
logger.info('Sending %s video to friends.', video_file.path)
|
||||
|
||||
var data = {
|
||||
path: '/api/' + global.API_VERSION + '/remotevideos/add',
|
||||
method: 'POST',
|
||||
data: params
|
||||
}
|
||||
|
||||
// Do not wait the secure requests
|
||||
pods.makeSecureRequest(data)
|
||||
pods.addVideoToFriends(params)
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
|
@ -124,16 +116,12 @@
|
|||
return callback(err)
|
||||
}
|
||||
|
||||
var data = {
|
||||
path: '/api/' + global.API_VERSION + '/remotevideos/remove',
|
||||
method: 'POST',
|
||||
data: {
|
||||
magnetUri: video.magnetUri
|
||||
}
|
||||
var params = {
|
||||
name: video.name,
|
||||
magnetUri: video.magnetUri
|
||||
}
|
||||
|
||||
// Yes this is a POST request because we add some informations in the body (signature, encrypt etc)
|
||||
pods.makeSecureRequest(data)
|
||||
pods.removeVideoToFriends(params)
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
|
@ -142,49 +130,65 @@
|
|||
}
|
||||
|
||||
// Use the magnet Uri because the _id field is not the same on different servers
|
||||
videos.removeRemote = function (fromUrl, magnetUri, callback) {
|
||||
VideosDB.findOne({ magnetUri: magnetUri }, function (err, video) {
|
||||
if (err || !video) {
|
||||
logger.error('Cannot find the torrent URI of this remote video.')
|
||||
videos.removeRemotes = function (fromUrl, magnetUris, callback) {
|
||||
VideosDB.find({ magnetUri: { $in: magnetUris } }, function (err, videos) {
|
||||
if (err || !videos) {
|
||||
logger.error('Cannot find the torrent URI of these remote videos.')
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
// TODO: move to reqValidators middleware ?
|
||||
if (video.podUrl !== fromUrl) {
|
||||
logger.error('The pod has not the rights on this video.')
|
||||
return callback(err)
|
||||
}
|
||||
var to_remove = []
|
||||
async.each(videos, function (video, callback_async) {
|
||||
callback_async = dz(callback_async)
|
||||
|
||||
VideosDB.findByIdAndRemove(video._id, function (err) {
|
||||
if (err) {
|
||||
logger.error('Cannot remove the remote video.')
|
||||
return callback(err)
|
||||
if (video.podUrl !== fromUrl) {
|
||||
logger.error('The pod %s has not the rights on the video of %s.', fromUrl, video.podUrl)
|
||||
} else {
|
||||
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 }
|
||||
videos.addRemote = function (data, callback) {
|
||||
logger.debug('Add remote video from pod: %s', data.podUrl)
|
||||
videos.addRemotes = function (videos, callback) {
|
||||
var to_add = []
|
||||
|
||||
var params = {
|
||||
name: data.name,
|
||||
namePath: null,
|
||||
description: data.description,
|
||||
magnetUri: data.magnetUri,
|
||||
podUrl: data.podUrl
|
||||
}
|
||||
async.each(videos, function (video, callback_each) {
|
||||
callback_each = dz(callback_each)
|
||||
logger.debug('Add remote video from pod: %s', video.podUrl)
|
||||
|
||||
VideosDB.create(params, function (err, video) {
|
||||
if (err) {
|
||||
logger.error('Cannot insert this remote video.', { error: err })
|
||||
return callback(err)
|
||||
var params = {
|
||||
name: video.name,
|
||||
namePath: null,
|
||||
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) {
|
||||
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(1, function () {
|
||||
makeFriend(4, function () {
|
||||
|
@ -114,37 +114,45 @@
|
|||
|
||||
// Expulse pod 4 from pod 1 and 2
|
||||
uploadVideo(1, function () {
|
||||
uploadVideo(1, function () {
|
||||
uploadVideo(2, function () {
|
||||
uploadVideo(2, function () {
|
||||
// Rerun server 4
|
||||
utils.runServer(4, function (app, url) {
|
||||
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)
|
||||
setTimeout(function () {
|
||||
uploadVideo(1, function () {
|
||||
setTimeout(function () {
|
||||
uploadVideo(2, function () {
|
||||
setTimeout(function () {
|
||||
uploadVideo(2, function () {
|
||||
setTimeout(function () {
|
||||
// Rerun server 4
|
||||
utils.runServer(4, function (app, url) {
|
||||
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
|
||||
makeFriend(6, function () {
|
||||
getFriendsList(6, function (err, res) {
|
||||
if (err) throw err
|
||||
// Pod 6 ask pod 1, 2 and 3
|
||||
makeFriend(6, function () {
|
||||
getFriendsList(6, function (err, res) {
|
||||
if (err) throw err
|
||||
|
||||
// Pod 4 should not be our friend
|
||||
var result = res.body
|
||||
expect(result.length).to.equal(3)
|
||||
for (var pod of result) {
|
||||
expect(pod.url).not.equal(urls[3])
|
||||
}
|
||||
// Pod 4 should not be our friend
|
||||
var result = res.body
|
||||
expect(result.length).to.equal(3)
|
||||
for (var pod of result) {
|
||||
expect(pod.url).not.equal(urls[3])
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
var path = '/api/v1/videos'
|
||||
var apps = []
|
||||
var urls = []
|
||||
var video_id = -1
|
||||
var to_remove = []
|
||||
|
||||
function getVideosList (url, end) {
|
||||
request(url)
|
||||
|
@ -36,6 +36,14 @@
|
|||
.end(end)
|
||||
}
|
||||
|
||||
function removeVideo (url, id, end) {
|
||||
request(url)
|
||||
.delete(path + '/' + id)
|
||||
.set('Accept', 'application/json')
|
||||
.expect(204)
|
||||
.end(end)
|
||||
}
|
||||
|
||||
before(function (done) {
|
||||
this.timeout(30000)
|
||||
var path_friends = '/api/v1/pods/makefriends'
|
||||
|
@ -89,7 +97,7 @@
|
|||
|
||||
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) {
|
||||
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) {
|
||||
if (err) throw err
|
||||
|
@ -125,12 +133,12 @@
|
|||
|
||||
done()
|
||||
})
|
||||
}, 1000)
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
|
||||
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) {
|
||||
if (err) throw err
|
||||
|
@ -166,47 +174,56 @@
|
|||
|
||||
done()
|
||||
})
|
||||
}, 1000)
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
|
||||
it('Should upload the video on pod 3 and propagate on each pod', function (done) {
|
||||
this.timeout(5000)
|
||||
it('Should upload two videos on pod 3 and propagate on each pod', function (done) {
|
||||
this.timeout(15000)
|
||||
|
||||
uploadVideo(urls[2], 'my super name for pod 3', 'my super description for pod 3', 'video_short3.webm', function (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 () {
|
||||
var base_magnet = null
|
||||
// All pods should have this video
|
||||
async.each(urls, function (url, callback) {
|
||||
getVideosList(url, function (err, res) {
|
||||
setTimeout(function () {
|
||||
var base_magnet = null
|
||||
// All pods should have this video
|
||||
async.each(urls, function (url, callback) {
|
||||
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
|
||||
|
||||
var videos = res.body
|
||||
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()
|
||||
done()
|
||||
})
|
||||
}, function (err) {
|
||||
if (err) throw err
|
||||
|
||||
done()
|
||||
})
|
||||
}, 1000)
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -220,6 +237,9 @@
|
|||
if (err) throw err
|
||||
|
||||
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) {
|
||||
expect(torrent.files).to.exist
|
||||
expect(torrent.files.length).to.equal(1)
|
||||
|
@ -257,7 +277,6 @@
|
|||
if (err) throw err
|
||||
|
||||
var video = res.body[2]
|
||||
video_id = res.body[1]._id
|
||||
|
||||
webtorrent.add(video.magnetUri, function (torrent) {
|
||||
expect(torrent.files).to.exist
|
||||
|
@ -269,19 +288,39 @@
|
|||
})
|
||||
})
|
||||
|
||||
it('Should remove the file 2 by asking pod 2', function (done) {
|
||||
request(urls[1])
|
||||
.delete(path + '/' + video_id)
|
||||
.set('Accept', 'application/json')
|
||||
.expect(204)
|
||||
.end(function (err, res) {
|
||||
it('Should add the file 3-2 by asking pod 1', function (done) {
|
||||
// Yes, this could be long
|
||||
this.timeout(200000)
|
||||
|
||||
getVideosList(urls[0], 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
|
||||
|
||||
// Wait the propagation to the other pods
|
||||
setTimeout(function () {
|
||||
done()
|
||||
}, 1000)
|
||||
}, 11000)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Should have videos 1 and 3 on each pod', function (done) {
|
||||
|
@ -293,8 +332,10 @@
|
|||
expect(videos).to.be.an('array')
|
||||
expect(videos.length).to.equal(2)
|
||||
expect(videos[0]._id).not.to.equal(videos[1]._id)
|
||||
expect(videos[0]._id).not.to.equal(video_id)
|
||||
expect(videos[1]._id).not.to.equal(video_id)
|
||||
expect(videos[0]._id).not.to.equal(to_remove[0])
|
||||
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()
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue