Selaa lähdekoodia

Добавил блокировку при загрузке книг, теперь загружаются последовательно

Book Pauk 3 vuotta sitten
vanhempi
commit
b387509f88
2 muutettua tiedostoa jossa 76 lisäystä ja 6 poistoa
  1. 23 6
      client/components/Reader/Reader.vue
  2. 53 0
      client/share/LockQueue.js

+ 23 - 6
client/components/Reader/Reader.vue

@@ -201,6 +201,7 @@ import miscApi from '../../api/misc';
 
 import {versionHistory} from './versionHistory';
 import * as utils from '../../share/utils';
+import LockQueue from '../../share/LockQueue';
 
 const componentOptions = {
     components: {
@@ -313,6 +314,8 @@ class Reader {
         this.reader = this.$store.state.reader;
         this.config = this.$store.state.config;
 
+        this.lock = new LockQueue(100);
+
         this.$root.addEventHook('key', this.keyHook);
 
         this.lastActivePage = false;
@@ -1051,7 +1054,7 @@ class Reader {
         return result;
     }
 
-    async loadBook(opts) {
+    async _loadBook(opts) {
         if (!opts || !opts.url) {
             this.mostRecentBook();
             return;
@@ -1061,10 +1064,6 @@ class Reader {
 
         let url = encodeURI(decodeURI(opts.url));
 
-        //TODO: убрать конвертирование 'file://' после 06.2021
-        if (url.length == 71 && url.indexOf('file://') == 0)
-            url = url.replace(/^file/, 'disk');
-
         if ((url.indexOf('http://') != 0) && (url.indexOf('https://') != 0) &&
             (url.indexOf('disk://') != 0))
             url = 'http://' + url;
@@ -1189,7 +1188,16 @@ class Reader {
         }
     }
 
-    async loadFile(opts) {
+    async loadBook(opts) {
+        await this.lock.get();
+        try {
+            await this._loadBook(opts);
+        } finally {
+            this.lock.ret();
+        }
+    }
+
+    async _loadFile(opts) {
         this.progressActive = true;
 
         await this.$nextTick();
@@ -1213,6 +1221,15 @@ class Reader {
         }
     }
 
+    async loadFile(opts) {
+        await this.lock.get();
+        try {
+            await this._loadFile(opts);
+        } finally {
+            this.lock.ret();
+        }
+    }
+
     blinkCachedLoadMessage() {
         if (!this.blinkCachedLoad)
             return;

+ 53 - 0
client/share/LockQueue.js

@@ -0,0 +1,53 @@
+class LockQueue {
+    constructor(queueSize) {
+        this.queueSize = queueSize;
+        this.freed = true;
+        this.waitingQueue = [];
+    }
+
+    //async
+    get(take = true) {
+        return new Promise((resolve, reject) => {
+            if (this.freed) {
+                if (take)
+                    this.freed = false;
+                resolve();
+                return;
+            }
+
+            if (this.waitingQueue.length < this.queueSize) {
+                this.waitingQueue.push({resolve, reject});
+            } else {
+                reject(new Error('Lock queue is too long'));
+            }
+        });
+    }
+
+    ret() {
+        if (this.waitingQueue.length) {
+            this.waitingQueue.shift().resolve();
+        } else {
+            this.freed = true;
+        }
+    }
+
+    //async
+    wait() {
+        return this.get(false);
+    }
+
+    retAll() {
+        while (this.waitingQueue.length) {
+            this.waitingQueue.shift().resolve();
+        }
+    }
+
+    errAll(error = 'rejected') {
+        while (this.waitingQueue.length) {
+            this.waitingQueue.shift().reject(new Error(error));
+        }
+    }
+
+}
+
+export default LockQueue;