]>
git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/friends.js
6a2c37fd724b5f081ca43e9e8b81500e9eeacdee
3 const config
= require('config')
4 const each
= require('async/each')
5 const eachLimit
= require('async/eachLimit')
6 const eachSeries
= require('async/eachSeries')
7 const fs
= require('fs')
8 const mongoose
= require('mongoose')
9 const request
= require('request')
10 const waterfall
= require('async/waterfall')
12 const constants
= require('../initializers/constants')
13 const logger
= require('../helpers/logger')
14 const requests
= require('../helpers/requests')
16 const Pod
= mongoose
.model('Pod')
17 const Request
= mongoose
.model('Request')
18 const Video
= mongoose
.model('Video')
21 addVideoToFriends: addVideoToFriends
,
22 hasFriends: hasFriends
,
23 getMyCertificate: getMyCertificate
,
24 makeFriends: makeFriends
,
25 quitFriends: quitFriends
,
26 removeVideoToFriends: removeVideoToFriends
,
27 sendOwnedVideosToPod: sendOwnedVideosToPod
30 function addVideoToFriends (video
) {
31 createRequest('add', video
)
34 function hasFriends (callback
) {
35 Pod
.countAll(function (err
, count
) {
36 if (err
) return callback(err
)
38 const hasFriends
= (count
!== 0)
39 callback(null, hasFriends
)
43 function getMyCertificate (callback
) {
44 fs
.readFile(constants
.CONFIG
.STORAGE
.CERT_DIR
+ 'peertube.pub', 'utf8', callback
)
47 function makeFriends (callback
) {
50 logger
.info('Make friends!')
51 getMyCertificate(function (err
, cert
) {
53 logger
.error('Cannot read public cert.')
57 const urls
= config
.get('network.friends')
59 eachSeries(urls
, function (url
, callbackEach
) {
60 computeForeignPodsList(url
, podsScore
, callbackEach
)
62 if (err
) return callback(err
)
64 logger
.debug('Pods scores computed.', { podsScore: podsScore
})
65 const podsList
= computeWinningPods(urls
, podsScore
)
66 logger
.debug('Pods that we keep.', { podsToKeep: podsList
})
68 makeRequestsToWinningPods(cert
, podsList
, callback
)
73 function quitFriends (callback
) {
76 // Flush pool requests
80 function getPodsList (callbackAsync
) {
81 return Pod
.list(callbackAsync
)
84 function announceIQuitMyFriends (pods
, callbackAsync
) {
85 const requestParams
= {
87 path: '/api/' + constants
.API_VERSION
+ '/pods/remove',
91 // Announce we quit them
92 // We don't care if the request fails
93 // The other pod will exclude us automatically after a while
94 eachLimit(pods
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
95 requestParams
.toPod
= pod
96 requests
.makeSecureRequest(requestParams
, callbackEach
)
99 logger
.error('Some errors while quitting friends.', { err: err
})
100 // Don't stop the process
103 return callbackAsync()
107 function removePodsFromDB (callbackAsync
) {
108 Pod
.removeAll(function (err
) {
109 return callbackAsync(err
)
113 function listRemoteVideos (callbackAsync
) {
114 logger
.info('Broke friends, so sad :(')
116 Video
.listRemotes(callbackAsync
)
119 function removeTheRemoteVideos (videosList
, callbackAsync
) {
120 each(videosList
, function (video
, callbackEach
) {
121 video
.remove(callbackEach
)
125 // Don't forget to re activate the scheduler, even if there was an error
128 if (err
) return callback(err
)
130 logger
.info('Removed all remote videos.')
131 return callback(null)
135 function removeVideoToFriends (videoParams
) {
136 createRequest('remove', videoParams
)
139 function sendOwnedVideosToPod (podId
) {
140 Video
.listOwned(function (err
, videosList
) {
142 logger
.error('Cannot get the list of videos we own.')
146 videosList
.forEach(function (video
) {
147 video
.toRemoteJSON(function (err
, remoteVideo
) {
149 logger
.error('Cannot convert video to remote.', { error: err
})
150 // Don't break the process
154 createRequest('add', remoteVideo
, [ podId
])
160 // ---------------------------------------------------------------------------
162 module
.exports
= friends
164 // ---------------------------------------------------------------------------
166 function computeForeignPodsList (url
, podsScore
, callback
) {
167 getForeignPodsList(url
, function (err
, foreignPodsList
) {
168 if (err
) return callback(err
)
170 if (!foreignPodsList
) foreignPodsList
= []
172 // Let's give 1 point to the pod we ask the friends list
173 foreignPodsList
.push({ url: url
})
175 foreignPodsList
.forEach(function (foreignPod
) {
176 const foreignPodUrl
= foreignPod
.url
178 if (podsScore
[foreignPodUrl
]) podsScore
[foreignPodUrl
]++
179 else podsScore
[foreignPodUrl
] = 1
186 function computeWinningPods (urls
, podsScore
) {
187 // Build the list of pods to add
188 // Only add a pod if it exists in more than a half base pods
190 const baseScore
= urls
.length
/ 2
191 Object
.keys(podsScore
).forEach(function (pod
) {
192 if (podsScore
[pod
] > baseScore
) podsList
.push({ url: pod
})
198 function getForeignPodsList (url
, callback
) {
199 const path
= '/api/' + constants
.API_VERSION
+ '/pods'
201 request
.get(url
+ path
, function (err
, response
, body
) {
202 if (err
) return callback(err
)
204 callback(null, JSON
.parse(body
))
208 function makeRequestsToWinningPods (cert
, podsList
, callback
) {
209 // Stop pool requests
211 // Flush pool requests
214 eachLimit(podsList
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
216 url: pod
.url
+ '/api/' + constants
.API_VERSION
+ '/pods/',
219 url: constants
.CONFIG
.WEBSERVER
.URL
,
224 requests
.makeRetryRequest(params
, function (err
, res
, body
) {
226 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
227 // Don't break the process
228 return callbackEach()
231 if (res
.statusCode
=== 200) {
232 const podObj
= new Pod({ url: pod
.url
, publicKey: body
.cert
})
233 podObj
.save(function (err
, podCreated
) {
235 logger
.error('Cannot add friend %s pod.', pod
.url
, { error: err
})
236 return callbackEach()
239 // Add our videos to the request scheduler
240 sendOwnedVideosToPod(podCreated
._id
)
242 return callbackEach()
245 logger
.error('Status not 200 for %s pod.', pod
.url
)
246 return callbackEach()
249 }, function endRequests () {
250 // Final callback, we've ended all the requests
251 // Now we made new friends, we can re activate the pool of requests
254 logger
.debug('makeRequestsToWinningPods finished.')
259 function createRequest (type
, data
, to
) {
260 const req
= new Request({
271 req
.save(function (err
) {
272 if (err
) logger
.error('Cannot save the request.', { error: err
})