浏览代码

Switch to using setBusy function

Saul Shanabrook 7 年之前
父节点
当前提交
0874095785

+ 5 - 13
packages/application-extension/src/index.tsx

@@ -252,27 +252,19 @@ const notfound: JupyterLabPlugin<void> = {
 
 
 /**
- * The favicon changing based on kernel busy status extension.
+ * Change the favicon changing based on the busy status;
  */
-const faviconbusy: JupyterLabPlugin<void> = {
+const busy: JupyterLabPlugin<void> = {
   id: '@jupyterlab/application-extension:faviconbusy',
   activate: async (app: JupyterLab) => {
-    await app.serviceManager.kernels.ready;
-
-    let isBusy = false;
-    app.serviceManager.kernels.runningChanged.connect((_, kernels) => {
-      const newIsBusy = kernels.some(kernel => kernel.execution_state === 'busy');
-      if (newIsBusy === isBusy) {
-        return;
-      }
-      isBusy = newIsBusy;
+    app.busySignal.connect((_, isBusy) => {
       const filename = isBusy ? 'favicon-busy-1.ico' : 'favicon.ico';
       const favicon = document.querySelector('link[rel="shortcut icon"]') as HTMLLinkElement;
       favicon.href = `/static/base/images/${filename}`;
     });
   },
   requires: [],
-  autoStart: true
+  autoStart: true,
 };
 
 
@@ -383,6 +375,6 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void {
 /**
  * Export the plugins as default.
  */
-const plugins: JupyterLabPlugin<any>[] = [main, layout, router, notfound, faviconbusy];
+const plugins: JupyterLabPlugin<any>[] = [main, layout, router, notfound, busy];
 
 export default plugins;

+ 39 - 0
packages/application/src/index.ts

@@ -39,6 +39,7 @@ import {
 import {
   ApplicationShell
 } from './shell';
+import { ISignal, Signal } from '@phosphor/signaling';
 
 export { ApplicationShell } from './shell';
 export { ILayoutRestorer, LayoutRestorer } from './layoutrestorer';
@@ -62,6 +63,7 @@ class JupyterLab extends Application<ApplicationShell> {
    */
   constructor(options: JupyterLab.IOptions = {}) {
     super({ shell: new ApplicationShell() });
+    this._busySignal = new Signal(this);
     this._info = { ...JupyterLab.defaultInfo, ...options };
     if (this._info.devMode) {
       this.shell.addClass('jp-mod-devMode');
@@ -108,6 +110,21 @@ class JupyterLab extends Application<ApplicationShell> {
     return this._dirtyCount > 0;
   }
 
+  /**
+   * Whether the application is busy.
+   */
+  get isBusy(): boolean {
+    return this._busyCount > 0;
+  }
+
+  /**
+   * Returns a signal for when application changes it's busy status.
+   */
+  get busySignal(): ISignal<JupyterLab, boolean> {
+    return this._busySignal;
+  }
+
+
   /**
    * The information about the application.
    */
@@ -137,6 +154,26 @@ class JupyterLab extends Application<ApplicationShell> {
     });
   }
 
+  /**
+   * Set the application state to busy.
+   *
+   * @returns A disposable used to clear the dirty state for the caller.
+   */
+  setBusy(): IDisposable {
+    const oldBusy = this.isBusy;
+    this._busyCount++;
+    if (this.isBusy !== oldBusy) {
+      this._busySignal.emit(this.isBusy);
+    }
+    return new DisposableDelegate(() => {
+      const oldBusy = this.isBusy;
+      this._busyCount--;
+      if (this.isBusy !== oldBusy) {
+        this._busySignal.emit(this.isBusy);
+      }
+    });
+  }
+
   /**
    * Register plugins from a plugin module.
    *
@@ -171,6 +208,8 @@ class JupyterLab extends Application<ApplicationShell> {
 
   private _info: JupyterLab.IInfo;
   private _dirtyCount = 0;
+  private _busyCount = 0;
+  private _busySignal: Signal<JupyterLab, boolean>;
 }
 
 

+ 21 - 6
packages/apputils/src/clientsession.tsx

@@ -229,10 +229,10 @@ class ClientSession implements IClientSession {
    */
   constructor(options: ClientSession.IOptions) {
     this.manager = options.manager;
-    this._kernelManager = options.kernelManager;
     this._path = options.path || uuid();
     this._type = options.type || '';
     this._name = options.name || '';
+    this._setBusy = options.setBusy;
     this._kernelPreference = options.kernelPreference || {};
   }
 
@@ -740,9 +740,23 @@ class ClientSession implements IClientSession {
    * Handle a change to the session status.
    */
   private _onStatusChanged(): void {
-    if (this._kernelManager) {
-      this._kernelManager.updateStatus(this.kernel.id, this.status);
+
+    // Set that this kernel is busy, if we haven't already
+    // If we have already, and now we aren't busy, dispose
+    // of the busy disposable.
+    if (this._setBusy) {
+      if (this.status === 'busy') {
+        if (!this._busyDisposable) {
+          this._busyDisposable = this._setBusy();
+        }
+      } else {
+        if (this._busyDisposable) {
+          this._busyDisposable.dispose();
+          delete this._busyDisposable;
+        }
+      }
     }
+
     this._statusChanged.emit(this.status);
   }
 
@@ -777,7 +791,8 @@ class ClientSession implements IClientSession {
   private _unhandledMessage = new Signal<this, KernelMessage.IMessage>(this);
   private _propertyChanged = new Signal<this, 'path' | 'name' | 'type'>(this);
   private _dialog: Dialog<any> | null = null;
-  private _kernelManager: Kernel.IManager;
+  private _setBusy: () => IDisposable | undefined;
+  private _busyDisposable: IDisposable | undefined;
 }
 
 
@@ -817,9 +832,9 @@ namespace ClientSession {
     kernelPreference?: IClientSession.IKernelPreference;
 
     /**
-     * A kernel manager instance.
+     * A function to call when the session becomes busy.
      */
-    kernelManager?: Kernel.IManager;
+    setBusy?: () => IDisposable;
   }
 
   /**

+ 2 - 1
packages/console-extension/src/index.ts

@@ -166,7 +166,7 @@ function activateConsole(app: JupyterLab, mainMenu: IMainMenu, palette: ICommand
 
   // The launcher callback.
   let callback = (cwd: string, name: string) => {
-    return createConsole({ basePath: cwd, kernelPreference: { name } });
+    return createConsole({ basePath: cwd, kernelPreference: { name }});
   };
 
   // Add a launcher item if the launcher is available.
@@ -214,6 +214,7 @@ function activateConsole(app: JupyterLab, mainMenu: IMainMenu, palette: ICommand
         contentFactory,
         mimeTypeService: editorServices.mimeTypeService,
         rendermime,
+        setBusy: app.setBusy.bind(app),
         ...options as Partial<ConsolePanel.IOptions>
       });
 

+ 8 - 2
packages/console/src/panel.ts

@@ -36,6 +36,7 @@ import {
 import {
   CodeConsole
 } from './widget';
+import { IDisposable } from '@phosphor/disposable';
 
 
 /**
@@ -70,11 +71,11 @@ class ConsolePanel extends Panel {
 
     let session = this._session = new ClientSession({
       manager: manager.sessions,
-      kernelManager: manager.kernels,
       path,
       name: name || `Console ${count}`,
       type: 'console',
-      kernelPreference: options.kernelPreference
+      kernelPreference: options.kernelPreference,
+      setBusy: options.setBusy
     });
 
     let resolver = new RenderMimeRegistry.UrlResolver({
@@ -223,6 +224,11 @@ namespace ConsolePanel {
      * The service used to look up mime types.
      */
     mimeTypeService: IEditorMimeTypeService;
+
+    /**
+     * A function to call when the kernel is busy.
+     */
+    setBusy?: () => IDisposable;
   }
 
   /**

+ 1 - 1
packages/docmanager-extension/src/index.ts

@@ -131,7 +131,7 @@ const plugin: JupyterLabPlugin<IDocumentManager> = {
     };
     const registry = app.docRegistry;
     const when = app.restored.then(() => void 0);
-    const docManager = new DocumentManager({ registry, manager, opener, when });
+    const docManager = new DocumentManager({ registry, manager, opener, when, setBusy: app.setBusy.bind(app) });
 
     // Register the file operations commands.
     addCommands(app, docManager, palette, opener, settingRegistry);

+ 9 - 1
packages/docmanager/src/manager.ts

@@ -92,6 +92,7 @@ class DocumentManager implements IDisposable {
     let widgetManager = new DocumentWidgetManager({ registry: this.registry });
     widgetManager.activateRequested.connect(this._onActivateRequested, this);
     this._widgetManager = widgetManager;
+    this._setBusy = options.setBusy;
   }
 
   /**
@@ -408,7 +409,8 @@ class DocumentManager implements IDisposable {
       factory,
       path,
       kernelPreference,
-      modelDBFactory
+      modelDBFactory,
+      setBusy: this._setBusy
     });
     let handler = new SaveHandler({ context });
     Private.saveHandlerProperty.set(context, handler);
@@ -510,6 +512,7 @@ class DocumentManager implements IDisposable {
   private _isDisposed = false;
   private _autosave = true;
   private _when: Promise<void>;
+  private _setBusy: () => IDisposable;
 }
 
 
@@ -542,6 +545,11 @@ namespace DocumentManager {
      * A promise for when to start using the manager.
      */
     when?: Promise<void>;
+
+    /**
+     * A function called when a kernel is busy.
+     */
+    setBusy?: () => IDisposable;
   }
 
   /**

+ 7 - 2
packages/docregistry/src/context.ts

@@ -80,11 +80,11 @@ class Context<T extends DocumentRegistry.IModel> implements DocumentRegistry.ICo
     let ext = PathExt.extname(this._path);
     this.session = new ClientSession({
       manager: manager.sessions,
-      kernelManager: manager.kernels,
       path: this._path,
       type: ext === '.ipynb' ? 'notebook' : 'file',
       name: PathExt.basename(localPath),
-      kernelPreference: options.kernelPreference || { shouldStart: false }
+      kernelPreference: options.kernelPreference || { shouldStart: false },
+      setBusy: options.setBusy
     });
     this.session.propertyChanged.connect(this._onSessionChanged, this);
     manager.contents.fileChanged.connect(this._onFileChanged, this);
@@ -731,6 +731,11 @@ export namespace Context {
      * An optional callback for opening sibling widgets.
      */
     opener?: (widget: Widget) => void;
+
+    /**
+     * A function to call when the kernel is busy.
+     */
+    setBusy?: () => IDisposable;
   }
 }
 

+ 0 - 11
packages/services/src/kernel/kernel.ts

@@ -657,11 +657,6 @@ namespace Kernel {
      * @returns A promise that resolves when all of the kernels are shut down.
      */
     shutdownAll(): Promise<void>;
-
-    /**
-     * Update a kernel's execuction status.
-     */
-    updateStatus(id: string, status: string): void;
   }
 
   /**
@@ -837,12 +832,6 @@ namespace Kernel {
      * The name of the kernel.
      */
     readonly name: string;
-
-    /**
-     * The execution state of the kernel.
-     */
-    readonly execution_state?: string;
-
   }
 
   /**

+ 0 - 16
packages/services/src/kernel/manager.ts

@@ -258,22 +258,6 @@ class KernelManager implements Kernel.IManager {
     });
   }
 
-  /**
-   * Update a kernel's execuction status.
-   */
-  updateStatus(id: string, status: string) {
-    for (let i = 0; i < this._models.length; i++) {
-      const model = this._models[i];
-      if (model.id === id) {
-        if (model.execution_state !== status) {
-          this._models[i] = {...model, execution_state: status};
-          this._runningChanged.emit(this._models.slice());
-        }
-        break;
-      }
-    }
-  }
-
   /**
    * Handle a kernel terminating.
    */

+ 1 - 13
packages/services/src/manager.ts

@@ -18,7 +18,7 @@ import {
 } from './contents';
 
 import {
-  Kernel, KernelManager
+  Kernel
 } from './kernel';
 
 import {
@@ -61,7 +61,6 @@ class ServiceManager implements ServiceManager.IManager {
     this.terminals = new TerminalManager(options);
     this.builder = new BuildManager(options);
     this.workspaces = new WorkspaceManager(options);
-    this.kernels = new KernelManager(options);
 
     this.sessions.specsChanged.connect((sender, specs) => {
       this._specsChanged.emit(specs);
@@ -102,7 +101,6 @@ class ServiceManager implements ServiceManager.IManager {
     this.contents.dispose();
     this.sessions.dispose();
     this.terminals.dispose();
-    this.kernels.dispose();
   }
 
   /**
@@ -147,11 +145,6 @@ class ServiceManager implements ServiceManager.IManager {
    */
   readonly workspaces: WorkspaceManager;
 
-  /**
-   * Get the kernels manager instance.
-   */
-  readonly kernels: KernelManager;
-
   /**
    * Test whether the manager is ready.
    */
@@ -223,11 +216,6 @@ namespace ServiceManager {
      */
     readonly terminals: TerminalSession.IManager;
 
-    /**
-     * The kernels manager for the manager.
-     */
-    readonly kernels: Kernel.IManager;
-
     /**
      * Test whether the manager is ready.
      */