]>
git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/friends.js
3 const async
= require('async')
4 const config
= require('config')
5 const fs
= require('fs')
6 const mongoose
= require('mongoose')
7 const request
= require('request')
9 const constants
= require('../initializers/constants')
10 const logger
= require('../helpers/logger')
11 const peertubeCrypto
= require('../helpers/peertubeCrypto')
12 const Pods
= require('../models/pods')
13 const requests
= require('../helpers/requests')
15 const http
= config
.get('webserver.https') ? 'https' : 'http'
16 const host
= config
.get('webserver.host')
17 const port
= config
.get('webserver.port')
18 const Request
= mongoose
.model('Request')
19 const Video
= mongoose
.model('Video')
22 addVideoToFriends: addVideoToFriends
,
23 hasFriends: hasFriends
,
24 getMyCertificate: getMyCertificate
,
25 makeFriends: makeFriends
,
26 quitFriends: quitFriends
,
27 removeVideoToFriends: removeVideoToFriends
,
28 sendOwnedVideosToPod: sendOwnedVideosToPod
31 function addVideoToFriends (video
) {
32 createRequest('add', video
)
35 function hasFriends (callback
) {
36 Pods
.count(function (err
, count
) {
37 if (err
) return callback(err
)
39 const hasFriends
= (count
!== 0)
40 callback(null, hasFriends
)
44 function getMyCertificate (callback
) {
45 fs
.readFile(peertubeCrypto
.getCertDir() + 'peertube.pub', 'utf8', callback
)
48 function makeFriends (callback
) {
51 logger
.info('Make friends!')
52 getMyCertificate(function (err
, cert
) {
54 logger
.error('Cannot read public cert.')
58 const urls
= config
.get('network.friends')
60 async
.eachSeries(urls
, function (url
, callbackEach
) {
61 computeForeignPodsList(url
, podsScore
, callbackEach
)
63 if (err
) return callback(err
)
65 logger
.debug('Pods scores computed.', { podsScore: podsScore
})
66 const podsList
= computeWinningPods(urls
, podsScore
)
67 logger
.debug('Pods that we keep.', { podsToKeep: podsList
})
69 makeRequestsToWinningPods(cert
, podsList
, callback
)
74 function quitFriends (callback
) {
77 // Flush pool requests
81 function getPodsList (callbackAsync
) {
82 return Pods
.list(callbackAsync
)
85 function announceIQuitMyFriends (pods
, callbackAsync
) {
86 const requestParams
= {
88 path: '/api/' + constants
.API_VERSION
+ '/pods/remove',
92 // Announce we quit them
93 // We don't care if the request fails
94 // The other pod will exclude us automatically after a while
95 async
.eachLimit(pods
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
96 requestParams
.toPod
= pod
97 requests
.makeSecureRequest(requestParams
, callbackEach
)
100 logger
.error('Some errors while quitting friends.', { err: err
})
101 // Don't stop the process
104 return callbackAsync()
108 function removePodsFromDB (callbackAsync
) {
109 Pods
.removeAll(function (err
) {
110 return callbackAsync(err
)
114 function listRemoteVideos (callbackAsync
) {
115 logger
.info('Broke friends, so sad :(')
117 Video
.listRemotes(callbackAsync
)
120 function removeTheRemoteVideos (videosList
, callbackAsync
) {
121 async
.each(videosList
, function (video
, callbackEach
) {
122 video
.remove(callbackEach
)
126 // Don't forget to re activate the scheduler, even if there was an error
129 if (err
) return callback(err
)
131 logger
.info('Removed all remote videos.')
132 return callback(null)
136 function removeVideoToFriends (videoParams
) {
137 createRequest('remove', videoParams
)
140 function sendOwnedVideosToPod (podId
) {
141 Video
.listOwned(function (err
, videosList
) {
143 logger
.error('Cannot get the list of videos we own.')
147 videosList
.forEach(function (video
) {
148 video
.toRemoteJSON(function (err
, remoteVideo
) {
150 logger
.error('Cannot convert video to remote.', { error: err
})
151 // Don't break the process
155 createRequest('add', remoteVideo
, [ podId
])
161 // ---------------------------------------------------------------------------
163 module
.exports
= pods
165 // ---------------------------------------------------------------------------
167 function computeForeignPodsList (url
, podsScore
, callback
) {
168 getForeignPodsList(url
, function (err
, foreignPodsList
) {
169 if (err
) return callback(err
)
171 if (!foreignPodsList
) foreignPodsList
= []
173 // Let's give 1 point to the pod we ask the friends list
174 foreignPodsList
.push({ url: url
})
176 foreignPodsList
.forEach(function (foreignPod
) {
177 const foreignPodUrl
= foreignPod
.url
179 if (podsScore
[foreignPodUrl
]) podsScore
[foreignPodUrl
]++
180 else podsScore
[foreignPodUrl
] = 1
187 function computeWinningPods (urls
, podsScore
) {
188 // Build the list of pods to add
189 // Only add a pod if it exists in more than a half base pods
191 const baseScore
= urls
.length
/ 2
192 Object
.keys(podsScore
).forEach(function (pod
) {
193 if (podsScore
[pod
] > baseScore
) podsList
.push({ url: pod
})
199 function getForeignPodsList (url
, callback
) {
200 const path
= '/api/' + constants
.API_VERSION
+ '/pods'
202 request
.get(url
+ path
, function (err
, response
, body
) {
203 if (err
) return callback(err
)
205 callback(null, JSON
.parse(body
))
209 function makeRequestsToWinningPods (cert
, podsList
, callback
) {
210 // Stop pool requests
212 // Flush pool requests
215 async
.eachLimit(podsList
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
217 url: pod
.url
+ '/api/' + constants
.API_VERSION
+ '/pods/',
220 url: http
+ '://' + host
+ ':' + port
,
225 requests
.makeRetryRequest(params
, function (err
, res
, body
) {
227 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
228 // Don't break the process
229 return callbackEach()
232 if (res
.statusCode
=== 200) {
233 Pods
.add({ url: pod
.url
, publicKey: body
.cert
, score: constants
.FRIEND_BASE_SCORE
}, function (err
, podCreated
) {
234 if (err
) logger
.error('Cannot add friend %s pod.', pod
.url
)
236 // Add our videos to the request scheduler
237 sendOwnedVideosToPod(podCreated
._id
)
239 return callbackEach()
242 logger
.error('Status not 200 for %s pod.', pod
.url
)
243 return callbackEach()
246 }, function endRequests () {
247 // Final callback, we've ended all the requests
248 // Now we made new friends, we can re activate the pool of requests
251 logger
.debug('makeRequestsToWinningPods finished.')
256 function createRequest (type
, data
, to
) {
257 const req
= new Request({
268 req
.save(function (err
) {
269 if (err
) logger
.error('Cannot save the request.', { error: err
})