aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-02-27 21:56:55 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-02-27 21:56:55 +0100
commit99fdec464802e5d720fe08ead06b63368b115baf (patch)
treed3129ec4e37894036fc8e83ee17a953873f41e12
parent05a9feaa48cea560abd9561434a3479ab1021643 (diff)
downloadPeerTube-99fdec464802e5d720fe08ead06b63368b115baf.tar.gz
PeerTube-99fdec464802e5d720fe08ead06b63368b115baf.tar.zst
PeerTube-99fdec464802e5d720fe08ead06b63368b115baf.zip
Fix request schedulers stats
-rw-r--r--client/src/app/+admin/requests/request-stats/request-stats.component.html50
-rw-r--r--client/src/app/+admin/requests/request-stats/request-stats.component.scss4
-rw-r--r--client/src/app/+admin/requests/request-stats/request-stats.component.ts60
-rw-r--r--client/src/app/+admin/requests/shared/request.service.ts14
-rw-r--r--client/src/app/shared/shared.module.ts3
-rw-r--r--server/controllers/api/requests.js37
-rw-r--r--server/lib/base-request-scheduler.js7
-rw-r--r--server/lib/friends.js31
8 files changed, 146 insertions, 60 deletions
diff --git a/client/src/app/+admin/requests/request-stats/request-stats.component.html b/client/src/app/+admin/requests/request-stats/request-stats.component.html
index 9dbed1739..ca531258c 100644
--- a/client/src/app/+admin/requests/request-stats/request-stats.component.html
+++ b/client/src/app/+admin/requests/request-stats/request-stats.component.html
@@ -1,33 +1,37 @@
1<h3>Requests stats</h3> 1<h3>Requests stats</h3>
2 2
3<div *ngIf="stats !== null"> 3<div *ngFor="let requestSchedulerName of statsTitles | keys">
4 <div class="requests-general"> 4 <div class="block" *ngIf="stats[requestSchedulerName] !== null">
5 <div> 5 <h4>{{ statsTitles[requestSchedulerName] }}</h4>
6 <span class="label-description">Remaining requests:</span>
7 {{ stats.totalRequests }}
8 </div>
9 6
10 <div> 7 <div class="requests-general">
11 <span class="label-description">Interval seconds between requests:</span> 8 <div>
12 {{ stats.secondsInterval }} 9 <span class="label-description">Remaining requests:</span>
13 </div> 10 {{ stats[requestSchedulerName].totalRequests }}
11 </div>
14 12
15 <div> 13 <div>
16 <span class="label-description">Remaining time before the scheduled request:</span> 14 <span class="label-description">Interval seconds between requests:</span>
17 {{ stats.remainingSeconds }} 15 {{ stats[requestSchedulerName].secondsInterval }}
18 </div> 16 </div>
19 </div>
20 17
21 <div class="requests-limit"> 18 <div>
22 <div> 19 <span class="label-description">Remaining time before the scheduled request:</span>
23 <span class="label-description">Maximum number of different pods for a scheduled request:</span> 20 {{ stats[requestSchedulerName].remainingSeconds }}
24 {{ stats.requestsLimitPods }} 21 </div>
25 </div> 22 </div>
26 23
27 <div> 24 <div class="requests-limit">
28 <span class="label-description">Maximum number of requests per pod for a scheduled request:</span> 25 <div>
29 {{ stats.requestsLimitPerPod }} 26 <span class="label-description">Maximum number of different pods for a scheduled request:</span>
27 {{ stats[requestSchedulerName].requestsLimitPods }}
28 </div>
29
30 <div>
31 <span class="label-description">Maximum number of requests per pod for a scheduled request:</span>
32 {{ stats[requestSchedulerName].requestsLimitPerPod }}
33 </div>
30 </div> 34 </div>
31 </div>
32 35
36 </div>
33</div> 37</div>
diff --git a/client/src/app/+admin/requests/request-stats/request-stats.component.scss b/client/src/app/+admin/requests/request-stats/request-stats.component.scss
index 9c68fba99..c9f724604 100644
--- a/client/src/app/+admin/requests/request-stats/request-stats.component.scss
+++ b/client/src/app/+admin/requests/request-stats/request-stats.component.scss
@@ -1,3 +1,7 @@
1.block {
2 margin-bottom: 40px;
3}
4
1.label-description { 5.label-description {
2 display: inline-block; 6 display: inline-block;
3 font-weight: bold; 7 font-weight: bold;
diff --git a/client/src/app/+admin/requests/request-stats/request-stats.component.ts b/client/src/app/+admin/requests/request-stats/request-stats.component.ts
index 18855a5f8..85dd7e492 100644
--- a/client/src/app/+admin/requests/request-stats/request-stats.component.ts
+++ b/client/src/app/+admin/requests/request-stats/request-stats.component.ts
@@ -10,10 +10,30 @@ import { RequestService, RequestStats } from '../shared';
10 styleUrls: [ './request-stats.component.scss' ] 10 styleUrls: [ './request-stats.component.scss' ]
11}) 11})
12export class RequestStatsComponent implements OnInit, OnDestroy { 12export class RequestStatsComponent implements OnInit, OnDestroy {
13 stats: RequestStats = null; 13 statsTitles = {
14 requestScheduler: 'Basic request scheduler',
15 requestVideoEventScheduler: 'Video events request scheduler',
16 requestVideoQaduScheduler: 'Quick and dirty video updates request scheduler'
17 };
18
19 stats: { [ id: string ]: RequestStats } = {
20 requestScheduler: null,
21 requestVideoEventScheduler: null,
22 requestVideoQaduScheduler: null
23 };
24
25 private intervals: { [ id: string ]: number } = {
26 requestScheduler: null,
27 requestVideoEventScheduler: null,
28 requestVideoQaduScheduler: null
29 };
30
31 private timeouts: { [ id: string ]: number } = {
32 requestScheduler: null,
33 requestVideoEventScheduler: null,
34 requestVideoQaduScheduler: null
35 };
14 36
15 private interval: number = null;
16 private timeout: number = null;
17 37
18 constructor( 38 constructor(
19 private notificationsService: NotificationsService, 39 private notificationsService: NotificationsService,
@@ -22,17 +42,19 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
22 42
23 ngOnInit() { 43 ngOnInit() {
24 this.getStats(); 44 this.getStats();
25 this.runInterval(); 45 this.runIntervals();
26 } 46 }
27 47
28 ngOnDestroy() { 48 ngOnDestroy() {
29 if (this.interval !== null) { 49 Object.keys(this.stats).forEach(requestSchedulerName => {
30 window.clearInterval(this.interval); 50 if (this.intervals[requestSchedulerName] !== null) {
31 } 51 window.clearInterval(this.intervals[requestSchedulerName]);
52 }
32 53
33 if (this.timeout !== null) { 54 if (this.timeouts[requestSchedulerName] !== null) {
34 window.clearTimeout(this.timeout); 55 window.clearTimeout(this.timeouts[requestSchedulerName]);
35 } 56 }
57 });
36 } 58 }
37 59
38 getStats() { 60 getStats() {
@@ -43,14 +65,18 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
43 ); 65 );
44 } 66 }
45 67
46 private runInterval() { 68 private runIntervals() {
47 this.interval = window.setInterval(() => { 69 Object.keys(this.intervals).forEach(requestSchedulerName => {
48 this.stats.remainingMilliSeconds -= 1000; 70 this.intervals[requestSchedulerName] = window.setInterval(() => {
71 const stats = this.stats[requestSchedulerName];
49 72
50 if (this.stats.remainingMilliSeconds <= 0) { 73 stats.remainingMilliSeconds -= 1000;
51 this.timeout = window.setTimeout(() => this.getStats(), this.stats.remainingMilliSeconds + 100); 74
52 } 75 if (stats.remainingMilliSeconds <= 0) {
53 }, 1000); 76 this.timeouts[requestSchedulerName] = window.setTimeout(() => this.getStats(), stats.remainingMilliSeconds + 100);
77 }
78 }, 1000);
79 });
54 } 80 }
55 81
56 82
diff --git a/client/src/app/+admin/requests/shared/request.service.ts b/client/src/app/+admin/requests/shared/request.service.ts
index 55b28bcfc..915d192a6 100644
--- a/client/src/app/+admin/requests/shared/request.service.ts
+++ b/client/src/app/+admin/requests/shared/request.service.ts
@@ -15,10 +15,20 @@ export class RequestService {
15 private restExtractor: RestExtractor 15 private restExtractor: RestExtractor
16 ) {} 16 ) {}
17 17
18 getStats(): Observable<RequestStats> { 18 getStats(): Observable<{ [ id: string ]: RequestStats }> {
19 return this.authHttp.get(RequestService.BASE_REQUEST_URL + 'stats') 19 return this.authHttp.get(RequestService.BASE_REQUEST_URL + 'stats')
20 .map(this.restExtractor.extractDataGet) 20 .map(this.restExtractor.extractDataGet)
21 .map((data) => new RequestStats(data)) 21 .map(this.buildRequestObjects)
22 .catch((res) => this.restExtractor.handleError(res)); 22 .catch((res) => this.restExtractor.handleError(res));
23 } 23 }
24
25 private buildRequestObjects(data: any) {
26 const requestSchedulers = {};
27
28 Object.keys(data).forEach(requestSchedulerName => {
29 requestSchedulers[requestSchedulerName] = new RequestStats(data[requestSchedulerName]);
30 });
31
32 return requestSchedulers;
33 }
24} 34}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index 99893c8b1..0f57ef078 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -5,6 +5,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5import { RouterModule } from '@angular/router'; 5import { RouterModule } from '@angular/router';
6 6
7import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe'; 7import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe';
8import { KeysPipe } from 'angular-pipes/src/object/keys.pipe';
8import { DropdownModule } from 'ng2-bootstrap/dropdown'; 9import { DropdownModule } from 'ng2-bootstrap/dropdown';
9import { ProgressbarModule } from 'ng2-bootstrap/progressbar'; 10import { ProgressbarModule } from 'ng2-bootstrap/progressbar';
10import { PaginationModule } from 'ng2-bootstrap/pagination'; 11import { PaginationModule } from 'ng2-bootstrap/pagination';
@@ -36,6 +37,7 @@ import { VideoAbuseService } from './video-abuse';
36 37
37 declarations: [ 38 declarations: [
38 BytesPipe, 39 BytesPipe,
40 KeysPipe,
39 SearchComponent 41 SearchComponent
40 ], 42 ],
41 43
@@ -53,6 +55,7 @@ import { VideoAbuseService } from './video-abuse';
53 ProgressbarModule, 55 ProgressbarModule,
54 Ng2SmartTableModule, 56 Ng2SmartTableModule,
55 BytesPipe, 57 BytesPipe,
58 KeysPipe,
56 59
57 SearchComponent 60 SearchComponent
58 ], 61 ],
diff --git a/server/controllers/api/requests.js b/server/controllers/api/requests.js
index 3e0d246d1..be352113e 100644
--- a/server/controllers/api/requests.js
+++ b/server/controllers/api/requests.js
@@ -1,9 +1,10 @@
1'use strict' 1'use strict'
2 2
3const express = require('express') 3const express = require('express')
4const parallel = require('async/parallel')
4 5
5const constants = require('../../initializers/constants') 6const constants = require('../../initializers/constants')
6const db = require('../../initializers/database') 7const friends = require('../../lib/friends')
7const middlewares = require('../../middlewares') 8const middlewares = require('../../middlewares')
8const admin = middlewares.admin 9const admin = middlewares.admin
9const oAuth = middlewares.oauth 10const oAuth = middlewares.oauth
@@ -23,15 +24,33 @@ module.exports = router
23// --------------------------------------------------------------------------- 24// ---------------------------------------------------------------------------
24 25
25function getStatsRequests (req, res, next) { 26function getStatsRequests (req, res, next) {
26 db.Request.countTotalRequests(function (err, totalRequests) { 27 parallel({
28 requestScheduler: buildRequestSchedulerFunction(friends.getRequestScheduler()),
29 requestVideoQaduScheduler: buildRequestSchedulerFunction(friends.getRequestVideoQaduScheduler()),
30 requestVideoEventScheduler: buildRequestSchedulerFunction(friends.getRequestVideoEventScheduler())
31 }, function (err, result) {
27 if (err) return next(err) 32 if (err) return next(err)
28 33
29 return res.json({ 34 return res.json(result)
30 totalRequests: totalRequests,
31 requestsLimitPods: constants.REQUESTS_LIMIT_PODS,
32 requestsLimitPerPod: constants.REQUESTS_LIMIT_PER_POD,
33 remainingMilliSeconds: db.Request.remainingMilliSeconds(),
34 milliSecondsInterval: constants.REQUESTS_INTERVAL
35 })
36 }) 35 })
37} 36}
37
38// ---------------------------------------------------------------------------
39
40function buildRequestSchedulerFunction (requestScheduler) {
41 return function (callback) {
42 requestScheduler.remainingRequestsCount(function (err, count) {
43 if (err) return callback(err)
44
45 const result = {
46 totalRequests: count,
47 requestsLimitPods: requestScheduler.limitPods,
48 requestsLimitPerPod: requestScheduler.limitPerPod,
49 remainingMilliSeconds: requestScheduler.remainingMilliSeconds(),
50 milliSecondsInterval: requestScheduler.requestInterval
51 }
52
53 return callback(null, result)
54 })
55 }
56}
diff --git a/server/lib/base-request-scheduler.js b/server/lib/base-request-scheduler.js
index 309c1a261..1c6b78297 100644
--- a/server/lib/base-request-scheduler.js
+++ b/server/lib/base-request-scheduler.js
@@ -12,6 +12,7 @@ module.exports = class BaseRequestScheduler {
12 constructor (options) { 12 constructor (options) {
13 this.lastRequestTimestamp = 0 13 this.lastRequestTimestamp = 0
14 this.timer = null 14 this.timer = null
15 this.requestInterval = constants.REQUESTS_INTERVAL
15 } 16 }
16 17
17 activate () { 18 activate () {
@@ -21,7 +22,7 @@ module.exports = class BaseRequestScheduler {
21 this.timer = setInterval(() => { 22 this.timer = setInterval(() => {
22 this.lastRequestTimestamp = Date.now() 23 this.lastRequestTimestamp = Date.now()
23 this.makeRequests() 24 this.makeRequests()
24 }, constants.REQUESTS_INTERVAL) 25 }, this.requestInterval)
25 } 26 }
26 27
27 deactivate () { 28 deactivate () {
@@ -41,6 +42,10 @@ module.exports = class BaseRequestScheduler {
41 return constants.REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp) 42 return constants.REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
42 } 43 }
43 44
45 remainingRequestsCount (callback) {
46 return this.getRequestModel().countTotalRequests(callback)
47 }
48
44 // --------------------------------------------------------------------------- 49 // ---------------------------------------------------------------------------
45 50
46 // Make a requests to friends of a certain type 51 // Make a requests to friends of a certain type
diff --git a/server/lib/friends.js b/server/lib/friends.js
index 203f0e52c..7bd087d8c 100644
--- a/server/lib/friends.js
+++ b/server/lib/friends.js
@@ -19,8 +19,8 @@ const RequestVideoEventScheduler = require('./request-video-event-scheduler')
19const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] 19const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
20 20
21const requestScheduler = new RequestScheduler() 21const requestScheduler = new RequestScheduler()
22const requestSchedulerVideoQadu = new RequestVideoQaduScheduler() 22const requestVideoQaduScheduler = new RequestVideoQaduScheduler()
23const requestSchedulerVideoEvent = new RequestVideoEventScheduler() 23const requestVideoEventScheduler = new RequestVideoEventScheduler()
24 24
25const friends = { 25const friends = {
26 activate, 26 activate,
@@ -33,13 +33,16 @@ const friends = {
33 makeFriends, 33 makeFriends,
34 quitFriends, 34 quitFriends,
35 removeVideoToFriends, 35 removeVideoToFriends,
36 sendOwnedVideosToPod 36 sendOwnedVideosToPod,
37 getRequestScheduler,
38 getRequestVideoQaduScheduler,
39 getRequestVideoEventScheduler
37} 40}
38 41
39function activate () { 42function activate () {
40 requestScheduler.activate() 43 requestScheduler.activate()
41 requestSchedulerVideoQadu.activate() 44 requestVideoQaduScheduler.activate()
42 requestSchedulerVideoEvent.activate() 45 requestVideoEventScheduler.activate()
43} 46}
44 47
45function addVideoToFriends (videoData, transaction, callback) { 48function addVideoToFriends (videoData, transaction, callback) {
@@ -142,7 +145,7 @@ function quitFriends (callback) {
142 }, 145 },
143 146
144 function flushVideoQaduRequests (callbackAsync) { 147 function flushVideoQaduRequests (callbackAsync) {
145 requestSchedulerVideoQadu.flush(err => callbackAsync(err)) 148 requestVideoQaduScheduler.flush(err => callbackAsync(err))
146 }, 149 },
147 150
148 function getPodsList (callbackAsync) { 151 function getPodsList (callbackAsync) {
@@ -215,6 +218,18 @@ function sendOwnedVideosToPod (podId) {
215 }) 218 })
216} 219}
217 220
221function getRequestScheduler () {
222 return requestScheduler
223}
224
225function getRequestVideoQaduScheduler () {
226 return requestVideoQaduScheduler
227}
228
229function getRequestVideoEventScheduler () {
230 return requestVideoEventScheduler
231}
232
218// --------------------------------------------------------------------------- 233// ---------------------------------------------------------------------------
219 234
220module.exports = friends 235module.exports = friends
@@ -345,13 +360,13 @@ function createRequest (options, callback) {
345function createVideoQaduRequest (options, callback) { 360function createVideoQaduRequest (options, callback) {
346 if (!callback) callback = utils.createEmptyCallback() 361 if (!callback) callback = utils.createEmptyCallback()
347 362
348 requestSchedulerVideoQadu.createRequest(options, callback) 363 requestVideoQaduScheduler.createRequest(options, callback)
349} 364}
350 365
351function createVideoEventRequest (options, callback) { 366function createVideoEventRequest (options, callback) {
352 if (!callback) callback = utils.createEmptyCallback() 367 if (!callback) callback = utils.createEmptyCallback()
353 368
354 requestSchedulerVideoEvent.createRequest(options, callback) 369 requestVideoEventScheduler.createRequest(options, callback)
355} 370}
356 371
357function isMe (host) { 372function isMe (host) {