Queue concurrent calls when initializing contents in BookModel (#14586) (#14619)

* Initial work for handling concurrent operations when calling initialized books

* fixes to init contents

* create a queue of deferred promises for initializing books

* resolve active promise and set to undefined

* remove duplicated variable

* address pr comments
This commit is contained in:
Barbara Valdez
2021-03-10 19:04:20 -08:00
committed by GitHub
parent 4772be5dcc
commit 9ae254c91e

View File

@@ -14,6 +14,7 @@ import * as loc from '../common/localizedConstants';
import { IJupyterBookToc, JupyterBookSection } from '../contracts/content'; import { IJupyterBookToc, JupyterBookSection } from '../contracts/content';
import { convertFrom, getContentPath, BookVersion } from './bookVersionHandler'; import { convertFrom, getContentPath, BookVersion } from './bookVersionHandler';
import { debounce } from '../common/utils'; import { debounce } from '../common/utils';
import { Deferred } from '../common/promise';
const fsPromises = fileServices.promises; const fsPromises = fileServices.promises;
const content = 'content'; const content = 'content';
@@ -26,6 +27,8 @@ export class BookModel {
private _bookVersion: BookVersion; private _bookVersion: BookVersion;
private _rootPath: string; private _rootPath: string;
private _errorMessage: string; private _errorMessage: string;
private _activePromise: Deferred<void> | undefined = undefined;
private _queuedPromises: Deferred<void>[] = [];
constructor( constructor(
public readonly bookPath: string, public readonly bookPath: string,
@@ -56,6 +59,16 @@ export class BookModel {
} }
public async initializeContents(): Promise<void> { public async initializeContents(): Promise<void> {
const deferred = new Deferred<void>();
if (!this._activePromise && this._queuedPromises.length === 0) {
this._activePromise = deferred;
}
else {
// If there's an active promise, then we need to add the new promise to the queue.
this._queuedPromises.push(deferred);
await deferred.promise;
}
try {
this._bookItems = []; this._bookItems = [];
this._allNotebooks = new Map<string, BookTreeItem>(); this._allNotebooks = new Map<string, BookTreeItem>();
if (this.isNotebook) { if (this.isNotebook) {
@@ -66,6 +79,13 @@ export class BookModel {
await this.readBooks(); await this.readBooks();
} }
} }
finally {
// Resolve next promise in queue
const queuedPromise = this._queuedPromises.shift();
queuedPromise?.resolve();
this._activePromise = queuedPromise;
}
}
public async readBookStructure(): Promise<void> { public async readBookStructure(): Promise<void> {
// check book structure to determine version // check book structure to determine version