]>
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 request
= require('request')
8 const constants
= require('../initializers/constants')
9 const logger
= require('../helpers/logger')
10 const peertubeCrypto
= require('../helpers/peertubeCrypto')
11 const Pods
= require('../models/pods')
12 const requestsScheduler
= require('../lib/requestsScheduler')
13 const requests
= require('../helpers/requests')
14 const videos
= require('../lib/videos')
15 const Videos
= require('../models/videos')
17 const http
= config
.get('webserver.https') ? 'https' : 'http'
18 const host
= config
.get('webserver.host')
19 const port
= config
.get('webserver.port')
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 // ensure namePath is null
35 requestsScheduler
.addRequest('add', video
)
38 function hasFriends (callback
) {
39 Pods
.count(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 async
.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
) {
79 requestsScheduler
.deactivate()
80 // Flush pool requests
81 requestsScheduler
.flush()
84 function getPodsList (callbackAsync
) {
85 return Pods
.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 async
.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 Pods
.removeAll(function (err
) {
113 return callbackAsync(err
)
117 function listRemoteVideos (callbackAsync
) {
118 logger
.info('Broke friends, so sad :(')
120 Videos
.listFromRemotes(callbackAsync
)
123 function removeTheRemoteVideos (videosList
, callbackAsync
) {
124 videos
.removeRemoteVideos(videosList
, function (err
) {
126 logger
.error('Cannot remove remote videos.', { error: err
})
127 return callbackAsync(err
)
130 return callbackAsync(null)
134 // Don't forget to re activate the scheduler, even if there was an error
135 requestsScheduler
.activate()
137 if (err
) return callback(err
)
139 logger
.info('Removed all remote videos.')
140 return callback(null)
144 function removeVideoToFriends (video
) {
145 requestsScheduler
.addRequest('remove', video
)
148 function sendOwnedVideosToPod (podId
) {
149 Videos
.listOwned(function (err
, videosList
) {
151 logger
.error('Cannot get the list of videos we own.')
155 videosList
.forEach(function (video
) {
156 videos
.convertVideoToRemote(video
, function (err
, remoteVideo
) {
158 logger
.error('Cannot convert video to remote.', { error: err
})
159 // Don't break the process
163 requestsScheduler
.addRequestTo([ podId
], 'add', remoteVideo
)
169 // ---------------------------------------------------------------------------
171 module
.exports
= pods
173 // ---------------------------------------------------------------------------
175 function computeForeignPodsList (url
, podsScore
, callback
) {
176 getForeignPodsList(url
, function (err
, foreignPodsList
) {
177 if (err
) return callback(err
)
179 if (!foreignPodsList
) foreignPodsList
= []
181 // Let's give 1 point to the pod we ask the friends list
182 foreignPodsList
.push({ url: url
})
184 foreignPodsList
.forEach(function (foreignPod
) {
185 const foreignPodUrl
= foreignPod
.url
187 if (podsScore
[foreignPodUrl
]) podsScore
[foreignPodUrl
]++
188 else podsScore
[foreignPodUrl
] = 1
195 function computeWinningPods (urls
, podsScore
) {
196 // Build the list of pods to add
197 // Only add a pod if it exists in more than a half base pods
199 const baseScore
= urls
.length
/ 2
200 Object
.keys(podsScore
).forEach(function (pod
) {
201 if (podsScore
[pod
] > baseScore
) podsList
.push({ url: pod
})
207 function getForeignPodsList (url
, callback
) {
208 const path
= '/api/' + constants
.API_VERSION
+ '/pods'
210 request
.get(url
+ path
, function (err
, response
, body
) {
211 if (err
) return callback(err
)
213 callback(null, JSON
.parse(body
))
217 function makeRequestsToWinningPods (cert
, podsList
, callback
) {
218 // Stop pool requests
219 requestsScheduler
.deactivate()
220 // Flush pool requests
221 requestsScheduler
.forceSend()
223 async
.eachLimit(podsList
, constants
.REQUESTS_IN_PARALLEL
, function (pod
, callbackEach
) {
225 url: pod
.url
+ '/api/' + constants
.API_VERSION
+ '/pods/',
228 url: http
+ '://' + host
+ ':' + port
,
233 requests
.makeRetryRequest(params
, function (err
, res
, body
) {
235 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
236 // Don't break the process
237 return callbackEach()
240 if (res
.statusCode
=== 200) {
241 Pods
.add({ url: pod
.url
, publicKey: body
.cert
, score: constants
.FRIEND_BASE_SCORE
}, function (err
, podCreated
) {
242 if (err
) logger
.error('Cannot add friend %s pod.', pod
.url
)
244 // Add our videos to the request scheduler
245 sendOwnedVideosToPod(podCreated
._id
)
247 return callbackEach()
250 logger
.error('Status not 200 for %s pod.', pod
.url
)
251 return callbackEach()
254 }, function endRequests () {
255 // Final callback, we've ended all the requests
256 // Now we made new friends, we can re activate the pool of requests
257 requestsScheduler
.activate()
259 logger
.debug('makeRequestsToWinningPods finished.')