Browse Source

Use a kernel future for execution

Steven Silvester 8 years ago
parent
commit
b14036ef0e
1 changed files with 44 additions and 24 deletions
  1. 44 24
      packages/outputarea/src/widget.ts

+ 44 - 24
packages/outputarea/src/widget.ts

@@ -157,9 +157,25 @@ class OutputArea extends Widget {
   readonly outputLengthChanged = new Signal<this, number>(this);
 
   /**
-   * Clear the output area.
+   * The kernel future associated with the output area.
    */
-  clear(): void {
+  get future(): Kernel.IFuture {
+    return this._future;
+  }
+
+  set future(value: Kernel.IFuture) {
+    // Bail if the model is disposed.
+    if (this.model.isDisposed) {
+      throw Error('Model is disposed');
+    }
+    if (this._future === value) {
+      return;
+    }
+    if (this._future) {
+      this._future.dispose();
+    }
+    this._future = value;
+
     this.model.clear();
 
     // Make sure there were no input widgets.
@@ -167,33 +183,30 @@ class OutputArea extends Widget {
       this._clear();
       this.outputLengthChanged.emit(this.model.length);
     }
-  }
-
-  /**
-   * Handle messages from code execution.
-   */
-  handleExecution(future: Kernel.IFuture): Promise<void> {
-    // Bail if the model is disposed.
-    if (this.model.isDisposed) {
-      return Promise.reject('Model is disposed');
-    }
 
     // Handle published messages.
-    future.onIOPub = (msg: KernelMessage.IIOPubMessage) => {
-      this._onIOPub(msg);
-    };
+    value.onIOPub = this._onIOPub.bind(this);
+
     // Handle the execute reply.
-    future.onReply = (msg: KernelMessage.IExecuteReplyMsg) => {
-      this._onExecuteReply(msg);
-    };
+    value.onReply = this._onExecuteReply.bind(this);
+
     // Handle stdin.
-    future.onStdin = (msg: KernelMessage.IStdinMessage) => {
+    value.onStdin = msg => {
       if (KernelMessage.isInputRequestMsg(msg)) {
-        this._onInputRequest(msg, future);
+        this._onInputRequest(msg, value);
       }
     };
+  }
 
-    return future.done;
+  /**
+   * Dispose of the resources used by the output area.
+   */
+  dispose(): void {
+    if (this._future) {
+      this._future.dispose();
+    }
+    this._future = null;
+    super.dispose();
   }
 
   /**
@@ -283,7 +296,12 @@ class OutputArea extends Widget {
   /**
    * Handle an execute reply message.
    */
-  private _onExecuteReply(msg: KernelMessage.IExecuteReplyMsg): void {
+  private _onExecuteReply(msg: KernelMessage.IExecuteReplyMsg): nbformat.ExecutionCount {
+    let count: nbformat.ExecutionCount;
+    let status = msg.content.status;
+    if (status !== 'abort') {
+      count = msg.content.execution_count;
+    }
     // API responses that contain a pager are special cased and their type
     // is overriden from 'execute_reply' to 'display_data' in order to
     // render output.
@@ -291,11 +309,11 @@ class OutputArea extends Widget {
     let content = msg.content as KernelMessage.IExecuteOkReply;
     let payload = content && content.payload;
     if (!payload || !payload.length) {
-      return;
+      return count;
     }
     let pages = payload.filter((i: any) => (i as any).source === 'page');
     if (!pages.length) {
-      return;
+      return count;
     }
     let page = JSON.parse(JSON.stringify(pages[0]));
     let output: nbformat.IOutput = {
@@ -304,6 +322,7 @@ class OutputArea extends Widget {
       metadata: {}
     };
     model.add(output);
+    return count;
   }
 
   /**
@@ -377,6 +396,7 @@ class OutputArea extends Widget {
   }
 
   private _minHeightTimeout: number = null;
+  private _future: Kernel.IFuture = null;
 }