From 84b37f11c8096b4e0b09ebc66565c0382e2b4118 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Thu, 4 Oct 2018 15:39:00 -0400 Subject: [PATCH 1/3] Record timings in metadata --- packages/cells/src/widget.ts | 31 ++++++++++++++++++++++++++++- tests/test-cells/src/widget.spec.ts | 8 ++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/cells/src/widget.ts b/packages/cells/src/widget.ts index b88ed62c7157..b18b5ee67009 100644 --- a/packages/cells/src/widget.ts +++ b/packages/cells/src/widget.ts @@ -805,9 +805,38 @@ export namespace CodeCell { cell.setPrompt('*'); model.trusted = true; - return OutputArea.execute(code, cell.outputArea, session, metadata) + const p = OutputArea.execute(code, cell.outputArea, session, metadata); + // cell.outputArea.future assigned synchronously in `execute` + cell.outputArea.future.onIOPub = (msg: KernelMessage.IIOPubMessage) => { + let label: string; + switch (msg.header.msg_type) { + case 'status': + label = `status.${msg.content.execution_state}`; + break; + case 'execute_input': + label = 'execute_input'; + break; + default: + return; + } + const value = msg.header.date; + if (!value) { + return; + } + model.metadata.set(`timing.iopub.${label}`, value); + }; + return p .then(msg => { model.executionCount = msg.content.execution_count; + const started = msg.metadata.started as string; + if (started) { + model.metadata.set('timing.shell.execute_reply.started', started); + } + const date = msg.header.date as string; + if (date) { + model.metadata.set('timing.shell.execute_reply', date); + } + return msg; }) .catch(e => { diff --git a/tests/test-cells/src/widget.spec.ts b/tests/test-cells/src/widget.spec.ts index f53522bb3545..dce6c6cdf407 100644 --- a/tests/test-cells/src/widget.spec.ts +++ b/tests/test-cells/src/widget.spec.ts @@ -460,6 +460,14 @@ describe('cells/widget', () => { await CodeCell.execute(widget, session); const executionCount = widget.model.executionCount; expect(executionCount).to.not.equal(originalCount); + expect(widget.model.metadata.get('timing.iopub.execute_input')).to + .exist; + expect(widget.model.metadata.get('timing.shell.execute_reply.started')) + .to.exist; + expect(widget.model.metadata.get('timing.shell.execute_reply')).to + .exist; + expect(widget.model.metadata.get('timing.iopub.status.busy')).to.exist; + expect(widget.model.metadata.get('timing.iopub.status.idle')).to.exist; }); }); }); From 313c86d2646e0dec52e3732d5df23942ca5f785e Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Thu, 4 Oct 2018 17:06:22 -0400 Subject: [PATCH 2/3] Add ability to toggle saving execution timing --- packages/cells/src/widget.ts | 46 ++++++++++++------------ packages/notebook-extension/src/index.ts | 14 ++++++++ packages/notebook/src/actions.tsx | 16 ++++++++- tests/test-cells/src/widget.spec.ts | 31 +++++++++++----- 4 files changed, 76 insertions(+), 31 deletions(-) diff --git a/packages/cells/src/widget.ts b/packages/cells/src/widget.ts index b18b5ee67009..b70787460991 100644 --- a/packages/cells/src/widget.ts +++ b/packages/cells/src/widget.ts @@ -797,9 +797,8 @@ export namespace CodeCell { model.outputs.clear(); return Promise.resolve(void 0); } - - let cellId = { cellId: model.id }; - metadata = { ...metadata, ...cellId }; + metadata = { ...metadata, cellId: model.id }; + const { recordTiming } = metadata; model.executionCount = null; cell.outputHidden = false; cell.setPrompt('*'); @@ -807,33 +806,36 @@ export namespace CodeCell { const p = OutputArea.execute(code, cell.outputArea, session, metadata); // cell.outputArea.future assigned synchronously in `execute` - cell.outputArea.future.onIOPub = (msg: KernelMessage.IIOPubMessage) => { - let label: string; - switch (msg.header.msg_type) { - case 'status': - label = `status.${msg.content.execution_state}`; - break; - case 'execute_input': - label = 'execute_input'; - break; - default: + if (recordTiming) { + cell.outputArea.future.onIOPub = (msg: KernelMessage.IIOPubMessage) => { + let label: string; + switch (msg.header.msg_type) { + case 'status': + label = `status.${msg.content.execution_state}`; + break; + case 'execute_input': + label = 'execute_input'; + break; + default: + return; + } + const value = msg.header.date; + if (!value) { return; - } - const value = msg.header.date; - if (!value) { - return; - } - model.metadata.set(`timing.iopub.${label}`, value); - }; + } + model.metadata.set(`timing.iopub.${label}`, value); + }; + } + return p .then(msg => { model.executionCount = msg.content.execution_count; const started = msg.metadata.started as string; - if (started) { + if (recordTiming && started) { model.metadata.set('timing.shell.execute_reply.started', started); } const date = msg.header.date as string; - if (date) { + if (recordTiming && date) { model.metadata.set('timing.shell.execute_reply', date); } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index c29b62fd6d0b..f964038dc966 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -157,6 +157,8 @@ namespace CommandIDs { export const toggleAllLines = 'notebook:toggle-all-cell-line-numbers'; + export const toggleRecordTiming = 'notebook:toggle-record-timing'; + export const undoCellAction = 'notebook:undo-cell-action'; export const redoCellAction = 'notebook:redo-cell-action'; @@ -1284,6 +1286,17 @@ function addCommands( }, isEnabled }); + commands.addCommand(CommandIDs.toggleRecordTiming, { + label: 'Toggle Recording Cell Timing', + execute: args => { + const current = getCurrent(args); + + if (current) { + return NotebookActions.toggleRecordTiming(current.content); + } + }, + isEnabled + }) commands.addCommand(CommandIDs.commandMode, { label: 'Enter Command Mode', execute: args => { @@ -1616,6 +1629,7 @@ function populatePalette( CommandIDs.deselectAll, CommandIDs.clearAllOutputs, CommandIDs.toggleAllLines, + CommandIDs.toggleRecordTiming, CommandIDs.editMode, CommandIDs.commandMode, CommandIDs.changeKernel, diff --git a/packages/notebook/src/actions.tsx b/packages/notebook/src/actions.tsx index 40bee26d2424..65a540945033 100644 --- a/packages/notebook/src/actions.tsx +++ b/packages/notebook/src/actions.tsx @@ -913,6 +913,19 @@ export namespace NotebookActions { Private.handleState(notebook, state); } + /** + * Toggle whether to record cell timing execution. + * + * @param notebook - The target notebook widget. + */ + export function toggleRecordTiming(notebook: Notebook): void { + if (!notebook.model) { + return; + } + const currentValue = notebook.model.metadata.get('record_timing') || false; + notebook.model.metadata.set('record_timing', !currentValue); + } + /** * Clear the code outputs of the selected cells. * @@ -1454,7 +1467,8 @@ namespace Private { case 'code': if (session) { return CodeCell.execute(cell as CodeCell, session, { - deletedCells: notebook.model.deletedCells + deletedCells: notebook.model.deletedCells, + recordTiming: notebook.model.metadata.get('record_timing') || false }) .then(reply => { notebook.model.deletedCells.splice( diff --git a/tests/test-cells/src/widget.spec.ts b/tests/test-cells/src/widget.spec.ts index dce6c6cdf407..974c470169d9 100644 --- a/tests/test-cells/src/widget.spec.ts +++ b/tests/test-cells/src/widget.spec.ts @@ -460,14 +460,29 @@ describe('cells/widget', () => { await CodeCell.execute(widget, session); const executionCount = widget.model.executionCount; expect(executionCount).to.not.equal(originalCount); - expect(widget.model.metadata.get('timing.iopub.execute_input')).to - .exist; - expect(widget.model.metadata.get('timing.shell.execute_reply.started')) - .to.exist; - expect(widget.model.metadata.get('timing.shell.execute_reply')).to - .exist; - expect(widget.model.metadata.get('timing.iopub.status.busy')).to.exist; - expect(widget.model.metadata.get('timing.iopub.status.idle')).to.exist; + }); + + const TIMING_KEYS = [ + 'timing.iopub.execute_input', + 'timing.shell.execute_reply.started', + 'timing.shell.execute_reply', + 'timing.iopub.status.busy', + 'timing.iopub.status.idle' + ]; + + it('should not save timing info by default', async () => { + const widget = new CodeCell({ model, rendermime, contentFactory }); + await CodeCell.execute(widget, session); + for (const key of TIMING_KEYS) { + expect(widget.model.metadata.get(key)).to.not.exist; + } + }); + it('should save timing info if requested', async () => { + const widget = new CodeCell({ model, rendermime, contentFactory }); + await CodeCell.execute(widget, session, { recordTiming: true }); + for (const key of TIMING_KEYS) { + expect(widget.model.metadata.get(key)).to.exist; + } }); }); }); From 052398b36fdff6f808680023ca9ad033e768e07f Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Fri, 5 Oct 2018 10:17:49 -0400 Subject: [PATCH 3/3] prettier --- packages/notebook-extension/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index f964038dc966..b84e54fbfbd8 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -1296,7 +1296,7 @@ function addCommands( } }, isEnabled - }) + }); commands.addCommand(CommandIDs.commandMode, { label: 'Enter Command Mode', execute: args => {