LP#1775466 String service queue pending
authorBill Erickson <berickxx@gmail.com>
Mon, 23 Jul 2018 21:42:33 +0000 (17:42 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 5 Sep 2018 14:05:23 +0000 (10:05 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/string/string.service.ts

index 37a07d9..9eb1196 100644 (file)
@@ -5,24 +5,74 @@ interface StringAssignment {
     resolver: (ctx: any) => Promise<string>;
 }
 
+interface PendingInterpolation {
+    key: string;
+    ctx: any;
+    resolve: (string) => any;
+    reject: (string) => any;
+}
+
 @Injectable()
 export class StringService {
 
     strings: {[key: string]: StringAssignment} = {};
 
-    constructor() {}
+    // This service can only interpolate one string at a time, since it
+    // maintains only one string component instance.  Avoid clobbering
+    // in-process interpolation requests by maintaining a request queue.
+    private pending: PendingInterpolation[];
+
+    constructor() {
+        this.pending = [];
+    }
 
     register(assn: StringAssignment) {
         this.strings[assn.key] = assn;
     }
 
     interpolate(key: string, ctx?: any): Promise<string> {
+
         if (!this.strings[key]) {
-            return Promise.reject('No Such String');
+            return Promise.reject(`String key not found: "${key}"`);
         }
-        return this.strings[key].resolver(ctx);
+
+        return new Promise( (resolve, reject) => {
+            const pend: PendingInterpolation = {
+                key: key,
+                ctx: ctx,
+                resolve: resolve,
+                reject: reject
+            }
+
+            this.pending.push(pend);
+
+            // Avoid launching the pending string processer with >1
+            // pending, because the processor will have already started.
+            if (this.pending.length === 1) {
+                this.processPending();
+            }
+        });
     }
 
+    processPending() {
+        const pstring = this.pending[0];
+        this.strings[pstring.key].resolver(pstring.ctx).then(
+            txt => { 
+                pstring.resolve(txt);
+                this.pending.shift();
+                if (this.pending.length) {
+                    this.processPending();
+                }
+            },
+            err => {
+                pstring.reject(err);
+                this.pending.shift();
+                if (this.pending.length) {
+                    this.processPending();
+                }
+            }
+        );
+    }
 }