]>
git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/friends.js
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 peertubeCrypto
= require('../helpers/peertube-crypto')
15 const requests
= require('../helpers/requests')
17 const http
= config
.get('webserver.https') ? 'https' : 'http'
18 const host
= config
.get('webserver.host')
19 const port
= config
.get('webserver.port')
20 const Pod
= mongoose
.model('Pod')
21 const Request
= mongoose
.model('Request')
22 const Video
= mongoose
.model('Video')
25 addVideoToFriends: addVideoToFriends
,
26 hasFriends: hasFriends
,
27 getMyCertificate: getMyCertificate
,
28 makeFriends: makeFriends
,
29 quitFriends: quitFriends
,
30 removeVideoToFriends: removeVideoToFriends
,
31 sendOwnedVideosToPod: sendOwnedVideosToPod
34 function addVideoToFriends (video
) {
35 createRequest('add', video
)
38 function hasFriends (callback
) {
39 Pod
.countAll(function (err
, count
) {
40 if (err
) return callback(err
)
42 const hasFriends
= (count
!== 0)
43 callback(null, hasFriends
)
47 function getMyCertificate (callback
) {
48 fs
.readFile(peertubeCrypto
.getCertDir() + 'peertube.pub', 'utf8', callback
)
51 function makeFriends (callback
) {
54 logger
.info('Make friends!')
55 getMyCertificate(function (err
, cert
) {
57 logger
.error('Cannot read public cert.')
61 const urls
= config
.get('network.friends')
63 eachSeries(urls
, function (url
, callbackEach
) {
64 computeForeignPodsList(url
, podsScore
, callbackEach
)
66 if (err
) return callback(err
)
68 logger
.debug('Pods scores computed.', { podsScore: podsScore
})
69 const podsList
= computeWinningPods(urls
, podsScore
)
70 logger
.debug('Pods that we keep.', { podsToKeep: podsList
})
72 makeRequestsToWinningPods(cert
, podsList
, callback
)
77 function quitFriends (callback
) {
80 // Flush pool requests
84 function getPodsList (callbackAsync
) {
85 return Pod
.list(callbackAsync
)
88 function announceIQuitMyFriends (pods
, callbackAsync
) {
89 const requestParams
= {
91 path: '/api/' + constants
.API_VERSION
+ '/pods/remove',
95 // Announce we quit them
96 // We don't care if the request fails
97 // The other pod will exclude us automatically after a while
98 eachLimit(pods
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
99 requestParams
.toPod
= pod
100 requests
.makeSecureRequest(requestParams
, callbackEach
)
103 logger
.error('Some errors while quitting friends.', { err: err
})
104 // Don't stop the process
107 return callbackAsync()
111 function removePodsFromDB (callbackAsync
) {
112 Pod
.removeAll(function (err
) {
113 return callbackAsync(err
)
117 function listRemoteVideos (callbackAsync
) {
118 logger
.info('Broke friends, so sad :(')
120 Video
.listRemotes(callbackAsync
)
123 function removeTheRemoteVideos (videosList
, callbackAsync
) {
124 each(videosList
, function (video
, callbackEach
) {
125 video
.remove(callbackEach
)
129 // Don't forget to re activate the scheduler, even if there was an error
132 if (err
) return callback(err
)
134 logger
.info('Removed all remote videos.')
135 return callback(null)
139 function removeVideoToFriends (videoParams
) {
140 createRequest('remove', videoParams
)
143 function sendOwnedVideosToPod (podId
) {
144 Video
.listOwned(function (err
, videosList
) {
146 logger
.error('Cannot get the list of videos we own.')
150 videosList
.forEach(function (video
) {
151 video
.toRemoteJSON(function (err
, remoteVideo
) {
153 logger
.error('Cannot convert video to remote.', { error: err
})
154 // Don't break the process
158 createRequest('add', remoteVideo
, [ podId
])
164 // ---------------------------------------------------------------------------
166 module
.exports
= friends
168 // ---------------------------------------------------------------------------
170 function computeForeignPodsList (url
, podsScore
, callback
) {
171 getForeignPodsList(url
, function (err
, foreignPodsList
) {
172 if (err
) return callback(err
)
174 if (!foreignPodsList
) foreignPodsList
= []
176 // Let's give 1 point to the pod we ask the friends list
177 foreignPodsList
.push({ url: url
})
179 foreignPodsList
.forEach(function (foreignPod
) {
180 const foreignPodUrl
= foreignPod
.url
182 if (podsScore
[foreignPodUrl
]) podsScore
[foreignPodUrl
]++
183 else podsScore
[foreignPodUrl
] = 1
190 function computeWinningPods (urls
, podsScore
) {
191 // Build the list of pods to add
192 // Only add a pod if it exists in more than a half base pods
194 const baseScore
= urls
.length
/ 2
195 Object
.keys(podsScore
).forEach(function (pod
) {
196 if (podsScore
[pod
] > baseScore
) podsList
.push({ url: pod
})
202 function getForeignPodsList (url
, callback
) {
203 const path
= '/api/' + constants
.API_VERSION
+ '/pods'
205 request
.get(url
+ path
, function (err
, response
, body
) {
206 if (err
) return callback(err
)
208 callback(null, JSON
.parse(body
))
212 function makeRequestsToWinningPods (cert
, podsList
, callback
) {
213 // Stop pool requests
215 // Flush pool requests
218 eachLimit(podsList
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
220 url: pod
.url
+ '/api/' + constants
.API_VERSION
+ '/pods/',
223 url: http
+ '://' + host
+ ':' + port
,
228 requests
.makeRetryRequest(params
, function (err
, res
, body
) {
230 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
231 // Don't break the process
232 return callbackEach()
235 if (res
.statusCode
=== 200) {
236 const podObj
= new Pod({ url: pod
.url
, publicKey: body
.cert
})
237 podObj
.save(function (err
, podCreated
) {
239 logger
.error('Cannot add friend %s pod.', pod
.url
, { error: err
})
240 return callbackEach()
243 // Add our videos to the request scheduler
244 sendOwnedVideosToPod(podCreated
._id
)
246 return callbackEach()
249 logger
.error('Status not 200 for %s pod.', pod
.url
)
250 return callbackEach()
253 }, function endRequests () {
254 // Final callback, we've ended all the requests
255 // Now we made new friends, we can re activate the pool of requests
258 logger
.debug('makeRequestsToWinningPods finished.')
263 function createRequest (type
, data
, to
) {
264 const req
= new Request({
275 req
.save(function (err
) {
276 if (err
) logger
.error('Cannot save the request.', { error: err
})