From e0090622dd64b94bf8e99d43362a4a2689bf932e Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Thu, 28 Jun 2018 15:50:32 +0200
Subject: [PATCH] [enh] sync: add sandbox watching

---
 app/modules/crawler/lib/sandbox.ts      |   9 ++
 app/modules/crawler/lib/sync.ts         |  25 ++---
 app/modules/crawler/lib/sync/Watcher.ts | 119 ++++++++++++------------
 3 files changed, 73 insertions(+), 80 deletions(-)

diff --git a/app/modules/crawler/lib/sandbox.ts b/app/modules/crawler/lib/sandbox.ts
index 58d3d79a7..f4a532180 100644
--- a/app/modules/crawler/lib/sandbox.ts
+++ b/app/modules/crawler/lib/sandbox.ts
@@ -54,29 +54,38 @@ export const pullSandboxToLocalServer = async (currency:string, fromHost:any, to
   if (res) {
     const docs = getDocumentsTree(currency, res)
 
+    let t = 0
+    let T = docs.identities.length + docs.certifications.length + docs.revocations.length + docs.memberships.length
+
     for (let i = 0; i < docs.identities.length; i++) {
       const idty = docs.identities[i];
       watcher && watcher.writeStatus('Identity ' + (i+1) + '/' + docs.identities.length)
+      watcher && watcher.sbxPercent((t++) / T * 100)
       await submitIdentityToServer(idty, toServer, notify, logger)
     }
 
     for (let i = 0; i < docs.revocations.length; i++) {
       const idty = docs.revocations[i];
       watcher && watcher.writeStatus('Revocation ' + (i+1) + '/' + docs.revocations.length)
+      watcher && watcher.sbxPercent((t++) / T * 100)
       await submitRevocationToServer(idty, toServer, notify, logger)
     }
 
     for (let i = 0; i < docs.certifications.length; i++) {
       const cert = docs.certifications[i];
       watcher && watcher.writeStatus('Certification ' + (i+1) + '/' + docs.certifications.length)
+      watcher && watcher.sbxPercent((t++) / T * 100)
       await submitCertificationToServer(cert, toServer, notify, logger)
     }
 
     for (let i = 0; i < docs.memberships.length; i++) {
       const ms = docs.memberships[i];
       watcher && watcher.writeStatus('Membership ' + (i+1) + '/' + docs.memberships.length)
+      watcher && watcher.sbxPercent((t++) / T * 100)
       await submitMembershipToServer(ms, toServer, notify, logger)
     }
+
+    watcher && watcher.sbxPercent(100)
   }
 }
 
diff --git a/app/modules/crawler/lib/sync.ts b/app/modules/crawler/lib/sync.ts
index 67f2455be..7e50d0b78 100644
--- a/app/modules/crawler/lib/sync.ts
+++ b/app/modules/crawler/lib/sync.ts
@@ -40,7 +40,7 @@ const EVAL_REMAINING_INTERVAL = 1000;
 
 export class Synchroniser extends stream.Duplex {
 
-  private watcher:Watcher
+  private watcher:EventWatcher
   private speed = 0
   private blocksApplied = 0
   private contacterOptions:any
@@ -55,24 +55,11 @@ export class Synchroniser extends stream.Duplex {
     super({ objectMode: true })
 
     // Wrapper to also push event stream
-    this.watcher = new EventWatcher(
-      interactive ? new MultimeterWatcher() : new LoggerWatcher(this.logger),
-      (pct:number, innerWatcher:Watcher) => {
-        if (pct !== undefined && innerWatcher.downloadPercent() < pct) {
-          this.push({ download: pct });
-        }
-      },
-      (pct:number, innerWatcher:Watcher) => {
-        if (pct !== undefined && innerWatcher.savedPercent() < pct) {
-          this.push({ saved: pct });
-        }
-      },
-      (pct:number, innerWatcher:Watcher) => {
-        if (pct !== undefined && innerWatcher.appliedPercent() < pct) {
-          this.push({ applied: pct });
-        }
-      }
-    )
+    this.watcher = new EventWatcher(interactive ? new MultimeterWatcher() : new LoggerWatcher(this.logger))
+    this.watcher.on('downloadChange', (pct: number) => this.push({ download: pct }))
+    this.watcher.on('savedChange',    (pct: number) => this.push({ saved: pct }))
+    this.watcher.on('appliedChange',  (pct: number) => this.push({ applied: pct }))
+    this.watcher.on('certChange',     (pct: number) => this.push({ sbx_cert: pct }))
 
     if (interactive) {
       this.logger.mute();
diff --git a/app/modules/crawler/lib/sync/Watcher.ts b/app/modules/crawler/lib/sync/Watcher.ts
index 288a11264..e4ad34c28 100644
--- a/app/modules/crawler/lib/sync/Watcher.ts
+++ b/app/modules/crawler/lib/sync/Watcher.ts
@@ -1,3 +1,5 @@
+import * as events from "events"
+
 const multimeter   = require('multimeter')
 
 export interface Watcher {
@@ -5,16 +7,14 @@ export interface Watcher {
   downloadPercent(pct?: number): number
   savedPercent(pct?: number): number
   appliedPercent(pct?: number): number
+  sbxPercent(pct?: number): number
   end(): void
 }
 
-export class EventWatcher implements Watcher {
+export class EventWatcher extends events.EventEmitter implements Watcher {
 
-  constructor(
-    private innerWatcher:Watcher,
-    private beforeDownloadPercentHook: (pct:number, innerWatcher:Watcher) => void,
-    private beforeSavedPercentHook: (pct:number, innerWatcher:Watcher) => void,
-    private beforeAppliedPercentHook: (pct:number, innerWatcher:Watcher) => void) {
+  constructor(private innerWatcher:Watcher) {
+    super()
   }
 
   writeStatus(str: string): void {
@@ -22,18 +22,26 @@ export class EventWatcher implements Watcher {
   }
 
   downloadPercent(pct?: number): number {
-    this.beforeDownloadPercentHook(pct || 0, this.innerWatcher)
-    return this.innerWatcher.downloadPercent(pct)
+    return this.change('downloadChange', (pct) => this.innerWatcher.downloadPercent(pct), pct)
   }
 
   savedPercent(pct?: number): number {
-    this.beforeSavedPercentHook(pct || 0, this.innerWatcher)
-    return this.innerWatcher.savedPercent(pct)
+    return this.change('savedChange', (pct) => this.innerWatcher.savedPercent(pct), pct)
   }
 
   appliedPercent(pct?: number): number {
-    this.beforeAppliedPercentHook(pct || 0, this.innerWatcher)
-    return this.innerWatcher.appliedPercent(pct)
+    return this.change('appliedChange', (pct) => this.innerWatcher.appliedPercent(pct), pct)
+  }
+
+  sbxPercent(pct?: number): number {
+    return this.change('sbxChange', (pct) => this.innerWatcher.sbxPercent(pct), pct)
+  }
+
+  change(changeName: string, method: (pct?: number) => number, pct?: number) {
+    if (pct !== undefined && method() < pct) {
+      this.emit(changeName, pct || 0)
+    }
+    return method(pct)
   }
 
   end(): void {
@@ -50,6 +58,7 @@ export class MultimeterWatcher implements Watcher {
   private appliedBar:any
   private savedBar:any
   private downloadBar:any
+  private sbxBar:any
   private writtens:string[] = []
 
   constructor() {
@@ -60,38 +69,10 @@ export class MultimeterWatcher implements Watcher {
 
     this.multi.write('Progress:\n\n');
 
-    this.multi.write("Download:   \n");
-    this.downloadBar = this.multi("Download:   \n".length, 3, {
-      width : 20,
-      solid : {
-        text : '|',
-        foreground : 'white',
-        background : 'blue'
-      },
-      empty : { text : ' ' }
-    });
-
-    this.multi.write("Blockchain: \n");
-    this.savedBar = this.multi("Blockchain: \n".length, 4, {
-      width : 20,
-      solid : {
-        text : '|',
-        foreground : 'white',
-        background : 'blue'
-      },
-      empty : { text : ' ' }
-    });
-
-    this.multi.write("Apply:      \n");
-    this.appliedBar = this.multi("Apply:      \n".length, 5, {
-      width : 20,
-      solid : {
-        text : '|',
-        foreground : 'white',
-        background : 'blue'
-      },
-      empty : { text : ' ' }
-    });
+    this.downloadBar = this.createBar('Download', 3)
+    this.savedBar    = this.createBar('Storage',  4)
+    this.appliedBar  = this.createBar('Apply',    5)
+    this.sbxBar      = this.createBar('Sandbox',  6)
 
     this.multi.write('\nStatus: ');
 
@@ -105,11 +86,11 @@ export class MultimeterWatcher implements Watcher {
     this.downloadBar.percent(0);
     this.savedBar.percent(0);
     this.appliedBar.percent(0);
+    this.sbxBar.percent(0);
   }
 
   writeStatus(str:string) {
     this.writtens.push(str);
-    //require('fs').writeFileSync('writtens.json', JSON.stringify(writtens));
     this.charm
       .position(this.xPos, this.yPos)
       .erase('end')
@@ -129,10 +110,28 @@ export class MultimeterWatcher implements Watcher {
     return this.appliedBar.percent(pct)
   }
 
+  sbxPercent(pct:number) {
+    return this.sbxBar.percent(pct)
+  }
+
   end() {
     this.multi.write('\nAll done.\n');
     this.multi.destroy();
   }
+
+  private createBar(title: string, line: number) {
+    const header = (title + ':').padEnd(14, ' ') + '\n'
+    this.multi.write(header)
+    return this.multi(header.length, line, {
+      width : 20,
+      solid : {
+        text : '|',
+        foreground : 'white',
+        background : 'blue'
+      },
+      empty : { text : ' ' }
+    })
+  }
 }
 
 export class LoggerWatcher implements Watcher {
@@ -157,30 +156,28 @@ export class LoggerWatcher implements Watcher {
   }
 
   downloadPercent(pct:number) {
-    if (pct !== undefined) {
-      let changed = pct > this.downPct;
-      this.downPct = pct;
-      if (changed) this.showProgress();
-    }
-    return this.downPct;
+    return this.change('downPct', pct)
   }
 
   savedPercent(pct:number) {
-    if (pct !== undefined) {
-      let changed = pct > this.savedPct;
-      this.savedPct = pct;
-      if (changed) this.showProgress();
-    }
-    return this.savedPct;
+    return this.change('savedPct', pct)
   }
 
   appliedPercent(pct:number) {
+    return this.change('appliedPct', pct)
+  }
+
+  sbxPercent(pct:number) {
+    return 0
+  }
+
+  change(prop: 'downPct'|'savedPct'|'appliedPct', pct:number) {
     if (pct !== undefined) {
-      let changed = pct > this.appliedPct;
-      this.appliedPct = pct;
-      if (changed) this.showProgress();
+      let changed = pct > this[prop]
+      this[prop] = pct
+      if (changed) this.showProgress()
     }
-    return this.appliedPct;
+    return this[prop]
   }
 
   end() {
-- 
GitLab