Skip to content

Commit

Permalink
Implement busy support for cell execution (#26)
Browse files Browse the repository at this point in the history
* Implement busy support

* Fixup api so that it works for unit tests too
  • Loading branch information
rchiodo authored Oct 18, 2018
1 parent 3481bad commit 0963949
Show file tree
Hide file tree
Showing 16 changed files with 452 additions and 228 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,7 @@
"typescript": "^2.9.1",
"typescript-formatter": "^7.1.0",
"url-loader": "^1.1.1",
"uuid": "^3.2.1",
"uuid": "^3.3.2",
"vscode": "^1.1.21",
"vscode-debugadapter-testsupport": "^1.27.0",
"webpack": "^4.20.2",
Expand Down
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"LanguageServiceSurveyBanner.bannerLabelYes": "Yes, take survey now",
"LanguageServiceSurveyBanner.bannerLabelNo": "No, thanks",
"DataScience.unknownMimeType" : "Unknown mime type for data",
"DataScience.historyTitle" : "History",
"DataScience.historyTitle" : "History - (beta)",
"DataScience.badWebPanelFormatString": "<html><body><h1>{0} is not a valid file name</h1></body></html>",
"DataScience.sessionDisposed" : "Cannot execute code, session has been disposed.",
"DataScience.exportDialogTitle" : "Export to Jupyter Notebook",
Expand Down
2 changes: 1 addition & 1 deletion src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export namespace LanguageServiceSurveyBanner {
}

export namespace DataScience {
export const historyTitle = localize('DataScience.historyTitle', 'History');
export const historyTitle = localize('DataScience.historyTitle', 'History - (beta)');
export const badWebPanelFormatString = localize('DataScience.badWebPanelFormatString', '<html><body><h1>{0} is not a valid file name</h1></body></html>');
export const sessionDisposed = localize('DataScience.sessionDisposed', 'Cannot execute code, session has been disposed.');
export const unknownMimeType = localize('DataScience.unknownMimeType', 'Unknown mime type for data');
Expand Down
3 changes: 2 additions & 1 deletion src/client/datascience/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export namespace RegExpValues {
}

export namespace HistoryMessages {
export const AddCell = 'add_cell';
export const StartCell = 'start_cell';
export const FinishCell = 'finish_cell';
export const GotoCodeCell = 'gotocell_code';

export const RestartKernel = 'restart_kernel';
Expand Down
345 changes: 211 additions & 134 deletions src/client/datascience/history-react/MainPanel.tsx

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions src/client/datascience/history-react/cell.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@
display: none;
}

.cell-execution-count {
font-weight: bold;
color: green;
}

.cell-result-container {
width: 100%;
}
Expand Down Expand Up @@ -63,6 +58,7 @@

.controls-flex {
display:flex;
min-width: 40px;
}

.center-img {
Expand All @@ -81,4 +77,4 @@

.collapse-input-svg-vscode-dark {
fill: lightgray;
}
}
30 changes: 17 additions & 13 deletions src/client/datascience/history-react/cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import JSONTree from 'react-json-tree';
import { nbformat } from '@jupyterlab/coreutils';
import { getLocString } from '../react-common/locReactSide';
import { RelativeImage } from '../react-common/relativeImage';
import { ICell } from '../types';
import { CellState, ICell } from '../types';
import './cell.css';
import { CellButton } from './cellButton';
import { ExecutionCount } from './executionCount';
import { MenuBar } from './menuBar';
import { strictEqual } from 'assert';

interface ICellProps {
cell: ICell;
Expand Down Expand Up @@ -72,12 +72,14 @@ export class Cell extends React.Component<ICellProps, ICellState> {
<div className='cell-outer'>
<div className='controls-div'>
<div className='controls-flex'>
<div className='cell-execution-count'>{`[${this.props.cell.execution_count}]:`}</div>
<button className={collapseInputClassNames} onClick={this.toggleInputBlock}>
<svg version='1.1' baseProfile='full' width='8px' height='11px'>
<polygon points='0,0 0,10 5,5' className={collapseInputPolygonClassNames} fill='black' />
</svg>
</button>
<ExecutionCount cell={this.props.cell} theme={this.props.theme} />
<div className='collapse-button-container'>
<button className={collapseInputClassNames} onClick={this.toggleInputBlock}>
<svg version='1.1' baseProfile='full' width='8px' height='11px'>
<polygon points='0,0 0,10 5,5' className={collapseInputPolygonClassNames} fill='black' />
</svg>
</button>
</div>
</div>
</div>
<div className='content-div'>
Expand Down Expand Up @@ -109,10 +111,10 @@ export class Cell extends React.Component<ICellProps, ICellState> {
private concatMultilineString(str : nbformat.MultilineString) : string {
if (Array.isArray(str)) {
let result = '';
for (let i=0; i<str.length; i++) {
for (let i = 0; i < str.length; i += 1) {
const s = str[i];
if (i < str.length - 1 && !s.endsWith('\n')) {
result = result.concat(`${s}\n`)
result = result.concat(`${s}\n`);
} else {
result = result.concat(s);
}
Expand All @@ -127,9 +129,11 @@ export class Cell extends React.Component<ICellProps, ICellState> {
}

private renderOutputs = () => {
return this.props.cell.outputs.map((output : nbformat.IOutput, index : number) => {
return this.renderOutput(output, index);
});
if (this.props.cell && (this.props.cell.state === CellState.finished || this.props.cell.state === CellState.error)) {
return this.props.cell.outputs.map((output: nbformat.IOutput, index: number) => {
return this.renderOutput(output, index);
});
}
}

private renderWithTransform = (mimetype: string, output : nbformat.IOutput, index : number) => {
Expand Down
37 changes: 37 additions & 0 deletions src/client/datascience/history-react/executionCount.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.execution-count {
font-weight: bold;
color: green;
}

.execution-count-busy-outer {
font-weight: bold;
color: green;
display:flex;
width: 16px;
height: 16px;
}
.execution-count-busy-svg {
animation-name: spin;
animation-duration: 4000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
transform-origin: 50% 50%;
width: 16px;
height: 16px;
}

.execution-count-busy-polyline {
fill: none;
stroke: green;
stroke-width: 5;
}

@keyframes spin {
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
}

31 changes: 31 additions & 0 deletions src/client/datascience/history-react/executionCount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

'use strict';
import * as React from 'react';
import { CellState, ICell } from '../types';
import './executionCount.css';

interface IExecutionCountProps {
cell: ICell;
theme: string;
}

export class ExecutionCount extends React.Component<IExecutionCountProps> {
constructor(props) {
super(props);
}

public render() {
const isBusy = this.props.cell.state === CellState.init || this.props.cell.state === CellState.executing;

return isBusy ?
(
<div className='execution-count-busy-outer'>[<svg className='execution-count-busy-svg' viewBox='0 0 100 100'><polyline points='50,0, 50,50, 85,15, 50,50, 100,50, 50,50, 85,85, 50,50 50,100 50,50 15,85 50,50 0,50 50,50 15,15' className='execution-count-busy-polyline'/></svg>]</div>
) :
(
<div className='execution-count'>{`[${this.props.cell.execution_count}]`}</div>
);
}

}
45 changes: 38 additions & 7 deletions src/client/datascience/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import * as fs from 'fs-extra';
import * as path from 'path';
import { Position, Range, Selection, TextEditor, Uri, ViewColumn } from 'vscode';
import { IApplicationShell, IDocumentManager, IWebPanel, IWebPanelMessageListener, IWebPanelProvider } from '../common/application/types';
import { createDeferred } from '../common/utils/async';
import * as localize from '../common/utils/localize';
import { IServiceContainer } from '../ioc/types';
import { HistoryMessages } from './constants';
import { ICell, IJupyterServer, IJupyterServerProvider } from './types';
import { CellState, ICell, IJupyterServer, IJupyterServerProvider } from './types';

export class History implements IWebPanelMessageListener {
private static activeHistory: History;
Expand Down Expand Up @@ -55,13 +56,43 @@ export class History implements IWebPanelMessageListener {
await this.loadPromise;

if (this.jupyterServer) {
// First attempt to evaluate this cell in the jupyter notebook
const newCell = await this.jupyterServer.execute(code, file, line);
// Create a deferred that we'll fire when we're done
const deferred = createDeferred();

// Attempt to evaluate this cell in the jupyter notebook
const observable = this.jupyterServer.executeObservable(code, file, line);

// Sign up for cell changes
observable.subscribe(
(cell: ICell) => {
if (this.webPanel) {
switch (cell.state) {
case CellState.init:
// Tell the react controls we have a new cell
this.webPanel.postMessage({ type: HistoryMessages.StartCell, payload: cell });
break;

case CellState.error:
case CellState.finished:
// Tell the react controls we're done
this.webPanel.postMessage({ type: HistoryMessages.FinishCell, payload: cell });
break;

default:
break; // might want to do a progress bar or something
}
}
},
(error) => {
this.applicationShell.showErrorMessage(error);
deferred.resolve();
},
() => {
deferred.resolve();
});

// Send our new state to our panel
if (this.webPanel) {
this.webPanel.postMessage({type: HistoryMessages.AddCell, payload: newCell});
}
// Wait for the execution to finish
await deferred.promise;
}
}

Expand Down
Loading

0 comments on commit 0963949

Please sign in to comment.