浏览代码

Switch to global busy

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

+ 20 - 1
packages/application-extension/src/index.tsx

@@ -251,6 +251,25 @@ const notfound: JupyterLabPlugin<void> = {
 };
 
 
+/**
+ * The favicon changing based on kernel busy status extension.
+ */
+const faviconbusy: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/application-extension:faviconbusy',
+  activate: async ({serviceManager: {kernels}}: JupyterLab) => {
+    await kernels.ready;
+    kernels.runningChanged.connect((_, kernels) => {
+      const isBusy = kernels.some(kernel => kernel.execution_state === 'busy');
+      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
+};
+
+
 /**
  * Add the main application commands.
  */
@@ -358,6 +377,6 @@ function addCommands(app: JupyterLab, palette: ICommandPalette): void {
 /**
  * Export the plugins as default.
  */
-const plugins: JupyterLabPlugin<any>[] = [main, layout, router, notfound];
+const plugins: JupyterLabPlugin<any>[] = [main, layout, router, notfound, faviconbusy];
 
 export default plugins;

+ 0 - 26
packages/application/src/shell.ts

@@ -26,13 +26,6 @@ import {
   DocumentRegistry
 } from '@jupyterlab/docregistry';
 
-import {
-  IClientSession
-} from '@jupyterlab/apputils';
-
-import {
-  Kernel
-} from '@jupyterlab/services';
 
 /**
  * The class name added to AppShell instances.
@@ -668,25 +661,6 @@ class ApplicationShell extends Widget {
     }
     this._currentChanged.emit(args);
     this._onLayoutModified();
-
-    this._onCurrentSessionChanged(args.newValue ? (args.newValue as any).session : undefined);
-  }
-
-  /**
-   * Handle a change to the session of the current widget.
-   */
-  private _onCurrentSessionChanged(session?: IClientSession) {
-    this._onCurrentStatusChanged(session, session ? session.status : undefined);
-    Signal.disconnectReceiver(this._onCurrentStatusChanged);
-    if (session) {
-      session.statusChanged.connect(this._onCurrentStatusChanged);
-    }
-  }
-
-  private _onCurrentStatusChanged(sender?: IClientSession, status?: Kernel.Status) {
-    const filename = status === 'busy' ? 'favicon-busy-1.ico' : 'favicon.ico';
-    const favicon = document.querySelector('link[rel="shortcut icon"]') as HTMLLinkElement;
-    favicon.href = `/static/base/images/${filename}`;
   }
 
   /**

+ 8 - 0
packages/docregistry/src/context.ts

@@ -85,6 +85,7 @@ class Context<T extends DocumentRegistry.IModel> implements DocumentRegistry.ICo
       name: PathExt.basename(localPath),
       kernelPreference: options.kernelPreference || { shouldStart: false }
     });
+    this.session.statusChanged.connect(this._onStatusChanged, this);
     this.session.propertyChanged.connect(this._onSessionChanged, this);
     manager.contents.fileChanged.connect(this._onFileChanged, this);
 
@@ -383,6 +384,13 @@ class Context<T extends DocumentRegistry.IModel> implements DocumentRegistry.ICo
     }
   }
 
+  /**
+   * Handle a change to a kernel status.
+   */
+  private _onStatusChanged(sender: IClientSession, status: string): void {
+    this._manager.kernels.updateStatus(sender.kernel.id, status);
+  }
+
   /**
    * Update our contents model, without the content.
    */

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

@@ -657,6 +657,11 @@ 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;
   }
 
   /**
@@ -832,6 +837,12 @@ namespace Kernel {
      * The name of the kernel.
      */
     readonly name: string;
+
+    /**
+     * The execution state of the kernel.
+     */
+    readonly execution_state?: string;
+
   }
 
   /**

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

@@ -258,6 +258,22 @@ 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.
    */

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

@@ -18,7 +18,7 @@ import {
 } from './contents';
 
 import {
-  Kernel
+  Kernel, KernelManager
 } from './kernel';
 
 import {
@@ -61,6 +61,7 @@ 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);
@@ -101,6 +102,7 @@ class ServiceManager implements ServiceManager.IManager {
     this.contents.dispose();
     this.sessions.dispose();
     this.terminals.dispose();
+    this.kernels.dispose();
   }
 
   /**
@@ -145,6 +147,11 @@ class ServiceManager implements ServiceManager.IManager {
    */
   readonly workspaces: WorkspaceManager;
 
+  /**
+   * Get the kernels manager instance.
+   */
+  readonly kernels: KernelManager;
+
   /**
    * Test whether the manager is ready.
    */
@@ -216,6 +223,11 @@ namespace ServiceManager {
      */
     readonly terminals: TerminalSession.IManager;
 
+    /**
+     * The kernels manager for the manager.
+     */
+    readonly kernels: Kernel.IManager;
+
     /**
      * Test whether the manager is ready.
      */