Fix request schedulers stats
authorChocobozzz <florian.bigard@gmail.com>
Mon, 27 Feb 2017 20:56:55 +0000 (21:56 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 27 Feb 2017 20:56:55 +0000 (21:56 +0100)
client/src/app/+admin/requests/request-stats/request-stats.component.html
client/src/app/+admin/requests/request-stats/request-stats.component.scss
client/src/app/+admin/requests/request-stats/request-stats.component.ts
client/src/app/+admin/requests/shared/request.service.ts
client/src/app/shared/shared.module.ts
server/controllers/api/requests.js
server/lib/base-request-scheduler.js
server/lib/friends.js

index 9dbed17391ff4b71e3ec2aeb0ef9025ce0d5884c..ca531258c3131abe4866717a720a4485d2d7ee58 100644 (file)
@@ -1,33 +1,37 @@
 <h3>Requests stats</h3>
 
-<div *ngIf="stats !== null">
-  <div class="requests-general">
-    <div>
-      <span class="label-description">Remaining requests:</span>
-      {{ stats.totalRequests }}
-    </div>
+<div *ngFor="let requestSchedulerName of statsTitles | keys">
+  <div class="block" *ngIf="stats[requestSchedulerName] !== null">
+    <h4>{{ statsTitles[requestSchedulerName] }}</h4>
 
-    <div>
-      <span class="label-description">Interval seconds between requests:</span>
-      {{ stats.secondsInterval }}
-    </div>
+    <div class="requests-general">
+      <div>
+        <span class="label-description">Remaining requests:</span>
+        {{ stats[requestSchedulerName].totalRequests }}
+      </div>
 
-    <div>
-      <span class="label-description">Remaining time before the scheduled request:</span>
-      {{ stats.remainingSeconds }}
-    </div>
-  </div>
+      <div>
+        <span class="label-description">Interval seconds between requests:</span>
+        {{ stats[requestSchedulerName].secondsInterval }}
+      </div>
 
-  <div class="requests-limit">
-    <div>
-      <span class="label-description">Maximum number of different pods for a scheduled request:</span>
-      {{ stats.requestsLimitPods }}
+      <div>
+        <span class="label-description">Remaining time before the scheduled request:</span>
+        {{ stats[requestSchedulerName].remainingSeconds }}
+      </div>
     </div>
 
-    <div>
-      <span class="label-description">Maximum number of requests per pod for a scheduled request:</span>
-      {{ stats.requestsLimitPerPod }}
+    <div class="requests-limit">
+      <div>
+        <span class="label-description">Maximum number of different pods for a scheduled request:</span>
+        {{ stats[requestSchedulerName].requestsLimitPods }}
+      </div>
+
+      <div>
+        <span class="label-description">Maximum number of requests per pod for a scheduled request:</span>
+        {{ stats[requestSchedulerName].requestsLimitPerPod }}
+      </div>
     </div>
-  </div>
 
+  </div>
 </div>
index 9c68fba9900487d65866d2b138058c4bfbd5f230..c9f724604943d1f554ca29fd51af9812a83e9dc0 100644 (file)
@@ -1,3 +1,7 @@
+.block {
+  margin-bottom: 40px;
+}
+
 .label-description {
   display: inline-block;
   font-weight: bold;
index 18855a5f8e0469871a1c5db4e4a3ca38695abe79..85dd7e492918d733d8cc4d18af75dc8cf4e33485 100644 (file)
@@ -10,10 +10,30 @@ import { RequestService, RequestStats } from '../shared';
   styleUrls: [ './request-stats.component.scss' ]
 })
 export class RequestStatsComponent implements OnInit, OnDestroy {
-  stats: RequestStats = null;
+  statsTitles = {
+    requestScheduler: 'Basic request scheduler',
+    requestVideoEventScheduler: 'Video events request scheduler',
+    requestVideoQaduScheduler: 'Quick and dirty video updates request scheduler'
+  };
+
+  stats: { [ id: string ]: RequestStats } = {
+    requestScheduler: null,
+    requestVideoEventScheduler: null,
+    requestVideoQaduScheduler: null
+  };
+
+  private intervals: { [ id: string ]: number } = {
+    requestScheduler: null,
+    requestVideoEventScheduler: null,
+    requestVideoQaduScheduler: null
+  };
+
+  private timeouts: { [ id: string ]: number } = {
+    requestScheduler: null,
+    requestVideoEventScheduler: null,
+    requestVideoQaduScheduler: null
+  };
 
-  private interval: number = null;
-  private timeout: number = null;
 
   constructor(
     private notificationsService: NotificationsService,
@@ -22,17 +42,19 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
 
   ngOnInit() {
     this.getStats();
-    this.runInterval();
+    this.runIntervals();
   }
 
   ngOnDestroy() {
-    if (this.interval !== null) {
-      window.clearInterval(this.interval);
-    }
+    Object.keys(this.stats).forEach(requestSchedulerName => {
+      if (this.intervals[requestSchedulerName] !== null) {
+        window.clearInterval(this.intervals[requestSchedulerName]);
+      }
 
-    if (this.timeout !== null) {
-      window.clearTimeout(this.timeout);
-    }
+      if (this.timeouts[requestSchedulerName] !== null) {
+        window.clearTimeout(this.timeouts[requestSchedulerName]);
+      }
+    });
   }
 
   getStats() {
@@ -43,14 +65,18 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
     );
   }
 
-  private runInterval() {
-    this.interval = window.setInterval(() => {
-      this.stats.remainingMilliSeconds -= 1000;
+  private runIntervals() {
+    Object.keys(this.intervals).forEach(requestSchedulerName => {
+      this.intervals[requestSchedulerName] = window.setInterval(() => {
+        const stats = this.stats[requestSchedulerName];
 
-      if (this.stats.remainingMilliSeconds <= 0) {
-        this.timeout = window.setTimeout(() => this.getStats(), this.stats.remainingMilliSeconds + 100);
-      }
-    }, 1000);
+        stats.remainingMilliSeconds -= 1000;
+
+        if (stats.remainingMilliSeconds <= 0) {
+          this.timeouts[requestSchedulerName] = window.setTimeout(() => this.getStats(), stats.remainingMilliSeconds + 100);
+        }
+      }, 1000);
+    });
   }
 
 
index 55b28bcfc3cefc0c377f72b1a0b9d5d8df8f8883..915d192a69dc9264e47765e2cc3e1f7c0e7e9387 100644 (file)
@@ -15,10 +15,20 @@ export class RequestService {
     private restExtractor: RestExtractor
   ) {}
 
-  getStats(): Observable<RequestStats> {
+  getStats(): Observable<{ [ id: string ]: RequestStats }> {
     return this.authHttp.get(RequestService.BASE_REQUEST_URL + 'stats')
                         .map(this.restExtractor.extractDataGet)
-                        .map((data) => new RequestStats(data))
+                        .map(this.buildRequestObjects)
                         .catch((res) => this.restExtractor.handleError(res));
   }
+
+  private buildRequestObjects(data: any) {
+    const requestSchedulers = {};
+
+    Object.keys(data).forEach(requestSchedulerName => {
+      requestSchedulers[requestSchedulerName] = new RequestStats(data[requestSchedulerName]);
+    });
+
+    return requestSchedulers;
+  }
 }
index 99893c8b1335fae6e2c6480eb16c05eea27d70f6..0f57ef078b18243840f7ebf925da31a2108aeb82 100644 (file)
@@ -5,6 +5,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { RouterModule } from '@angular/router';
 
 import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe';
+import { KeysPipe } from 'angular-pipes/src/object/keys.pipe';
 import { DropdownModule } from 'ng2-bootstrap/dropdown';
 import { ProgressbarModule } from 'ng2-bootstrap/progressbar';
 import { PaginationModule } from 'ng2-bootstrap/pagination';
@@ -36,6 +37,7 @@ import { VideoAbuseService } from './video-abuse';
 
   declarations: [
     BytesPipe,
+    KeysPipe,
     SearchComponent
   ],
 
@@ -53,6 +55,7 @@ import { VideoAbuseService } from './video-abuse';
     ProgressbarModule,
     Ng2SmartTableModule,
     BytesPipe,
+    KeysPipe,
 
     SearchComponent
   ],
index 3e0d246d1ef882102d000f8250bd47719f5fdb6e..be352113e27a0f306d190d69f7ee33242e50400a 100644 (file)
@@ -1,9 +1,10 @@
 'use strict'
 
 const express = require('express')
+const parallel = require('async/parallel')
 
 const constants = require('../../initializers/constants')
-const db = require('../../initializers/database')
+const friends = require('../../lib/friends')
 const middlewares = require('../../middlewares')
 const admin = middlewares.admin
 const oAuth = middlewares.oauth
@@ -23,15 +24,33 @@ module.exports = router
 // ---------------------------------------------------------------------------
 
 function getStatsRequests (req, res, next) {
-  db.Request.countTotalRequests(function (err, totalRequests) {
+  parallel({
+    requestScheduler: buildRequestSchedulerFunction(friends.getRequestScheduler()),
+    requestVideoQaduScheduler: buildRequestSchedulerFunction(friends.getRequestVideoQaduScheduler()),
+    requestVideoEventScheduler: buildRequestSchedulerFunction(friends.getRequestVideoEventScheduler())
+  }, function (err, result) {
     if (err) return next(err)
 
-    return res.json({
-      totalRequests: totalRequests,
-      requestsLimitPods: constants.REQUESTS_LIMIT_PODS,
-      requestsLimitPerPod: constants.REQUESTS_LIMIT_PER_POD,
-      remainingMilliSeconds: db.Request.remainingMilliSeconds(),
-      milliSecondsInterval: constants.REQUESTS_INTERVAL
-    })
+    return res.json(result)
   })
 }
+
+// ---------------------------------------------------------------------------
+
+function buildRequestSchedulerFunction (requestScheduler) {
+  return function (callback) {
+    requestScheduler.remainingRequestsCount(function (err, count) {
+      if (err) return callback(err)
+
+      const result = {
+        totalRequests: count,
+        requestsLimitPods: requestScheduler.limitPods,
+        requestsLimitPerPod: requestScheduler.limitPerPod,
+        remainingMilliSeconds: requestScheduler.remainingMilliSeconds(),
+        milliSecondsInterval: requestScheduler.requestInterval
+      }
+
+      return callback(null, result)
+    })
+  }
+}
index 309c1a26166c06ec22c4b4161fb45ca4f7e1eedf..1c6b782970f68bdd818675927a6b1ead9fef9912 100644 (file)
@@ -12,6 +12,7 @@ module.exports = class BaseRequestScheduler {
   constructor (options) {
     this.lastRequestTimestamp = 0
     this.timer = null
+    this.requestInterval = constants.REQUESTS_INTERVAL
   }
 
   activate () {
@@ -21,7 +22,7 @@ module.exports = class BaseRequestScheduler {
     this.timer = setInterval(() => {
       this.lastRequestTimestamp = Date.now()
       this.makeRequests()
-    }, constants.REQUESTS_INTERVAL)
+    }, this.requestInterval)
   }
 
   deactivate () {
@@ -41,6 +42,10 @@ module.exports = class BaseRequestScheduler {
     return constants.REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
   }
 
+  remainingRequestsCount (callback) {
+    return this.getRequestModel().countTotalRequests(callback)
+  }
+
   // ---------------------------------------------------------------------------
 
   // Make a requests to friends of a certain type
index 203f0e52c2912261b1da7c8559f853a518c3e047..7bd087d8cfdb630f3371183e880eed40c6d39b70 100644 (file)
@@ -19,8 +19,8 @@ const RequestVideoEventScheduler = require('./request-video-event-scheduler')
 const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
 
 const requestScheduler = new RequestScheduler()
-const requestSchedulerVideoQadu = new RequestVideoQaduScheduler()
-const requestSchedulerVideoEvent = new RequestVideoEventScheduler()
+const requestVideoQaduScheduler = new RequestVideoQaduScheduler()
+const requestVideoEventScheduler = new RequestVideoEventScheduler()
 
 const friends = {
   activate,
@@ -33,13 +33,16 @@ const friends = {
   makeFriends,
   quitFriends,
   removeVideoToFriends,
-  sendOwnedVideosToPod
+  sendOwnedVideosToPod,
+  getRequestScheduler,
+  getRequestVideoQaduScheduler,
+  getRequestVideoEventScheduler
 }
 
 function activate () {
   requestScheduler.activate()
-  requestSchedulerVideoQadu.activate()
-  requestSchedulerVideoEvent.activate()
+  requestVideoQaduScheduler.activate()
+  requestVideoEventScheduler.activate()
 }
 
 function addVideoToFriends (videoData, transaction, callback) {
@@ -142,7 +145,7 @@ function quitFriends (callback) {
     },
 
     function flushVideoQaduRequests (callbackAsync) {
-      requestSchedulerVideoQadu.flush(err => callbackAsync(err))
+      requestVideoQaduScheduler.flush(err => callbackAsync(err))
     },
 
     function getPodsList (callbackAsync) {
@@ -215,6 +218,18 @@ function sendOwnedVideosToPod (podId) {
   })
 }
 
+function getRequestScheduler () {
+  return requestScheduler
+}
+
+function getRequestVideoQaduScheduler () {
+  return requestVideoQaduScheduler
+}
+
+function getRequestVideoEventScheduler () {
+  return requestVideoEventScheduler
+}
+
 // ---------------------------------------------------------------------------
 
 module.exports = friends
@@ -345,13 +360,13 @@ function createRequest (options, callback) {
 function createVideoQaduRequest (options, callback) {
   if (!callback) callback = utils.createEmptyCallback()
 
-  requestSchedulerVideoQadu.createRequest(options, callback)
+  requestVideoQaduScheduler.createRequest(options, callback)
 }
 
 function createVideoEventRequest (options, callback) {
   if (!callback) callback = utils.createEmptyCallback()
 
-  requestSchedulerVideoEvent.createRequest(options, callback)
+  requestVideoEventScheduler.createRequest(options, callback)
 }
 
 function isMe (host) {