Skip to content

Commit

Permalink
Merge pull request #2490 from rgbkrk/more-kernel-ops
Browse files Browse the repository at this point in the history
create more selectors, apply generously
  • Loading branch information
theengineear committed Feb 7, 2018
2 parents 0326d73 + d7b24c4 commit ce305cb
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 58 deletions.
49 changes: 13 additions & 36 deletions applications/desktop/src/notebook/epics/zeromq-kernels.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ import type { NewKernelAction } from "@nteract/core/actionTypes";

import type { KernelInfo, LocalKernelProps } from "@nteract/types/core/records";

import {
getCurrentKernel,
getCurrentHost,
isCurrentKernelZeroMQ
} from "@nteract/core/selectors";

import {
createMessage,
childOf,
Expand Down Expand Up @@ -179,8 +185,7 @@ export const launchKernelEpic = (
// We must kill the previous kernel now
// Then launch the next one
switchMap(action => {
const state = store.getState();
const kernel = state.app.kernel;
const kernel = getCurrentKernel(store.getState());

return merge(
launchKernelObservable(action.kernelSpec, action.cwd),
Expand All @@ -196,25 +201,12 @@ export const launchKernelEpic = (
export const interruptKernelEpic = (action$: *, store: *): Observable<Action> =>
action$.pipe(
ofType(INTERRUPT_KERNEL),
filter(() => {
const state = store.getState();
const host = state.app.host;
const kernel = state.app.kernel;

// This epic can only interrupt direct zeromq connected kernels
return (
host &&
kernel &&
host.type === "local" &&
kernel.type === "zeromq" &&
kernel.spawn
);
}),
// This epic can only interrupt direct zeromq connected kernels
filter(() => isCurrentKernelZeroMQ(store.getState())),
// If the user fires off _more_ interrupts, we shouldn't interrupt the in-flight
// interrupt, instead doing it after the last one happens
concatMap(() => {
const state = store.getState();
const kernel = state.app.kernel;
const kernel = getCurrentKernel(store.getState());

const spawn = kernel.spawn;

Expand Down Expand Up @@ -314,25 +306,10 @@ function killKernel(kernel): Observable<Action> {
export const killKernelEpic = (action$: *, store: *): Observable<Action> =>
action$.pipe(
ofType(KILL_KERNEL),
filter(() => {
const state = store.getState();
const host = state.app.host;
const kernel = state.app.kernel;

// This epic can only interrupt direct zeromq connected kernels
return (
host &&
kernel &&
host.type === "local" &&
kernel.type === "zeromq" &&
kernel.spawn &&
kernel.channels
);
}),
// This epic can only interrupt direct zeromq connected kernels
filter(() => isCurrentKernelZeroMQ(store.getState())),
concatMap(action => {
const app = store.getState().app;
const kernel = app.kernel;

const kernel = getCurrentKernel(store.getState());
return killKernel(kernel);
})
);
Expand Down
1 change: 1 addition & 0 deletions packages/core/selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./").selectors;
5 changes: 3 additions & 2 deletions packages/core/src/epics/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
executionCounts
} from "@nteract/messaging";

import { getCurrentKernel } from "../selectors";

import { Observable } from "rxjs/Observable";
import { of } from "rxjs/observable/of";
import { from } from "rxjs/observable/from";
Expand Down Expand Up @@ -135,9 +137,8 @@ export function createExecuteCellStream(
message: ExecuteRequest,
id: string
) {
const state = store.getState();
const kernel = getCurrentKernel(store.getState());

const kernel = state.app.kernel;
const channels = kernel ? kernel.channels : null;

const kernelConnected =
Expand Down
28 changes: 8 additions & 20 deletions packages/core/src/epics/websocket-kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import type { AppState, RemoteKernelProps } from "@nteract/types/core/records";
import { kernels, shutdown } from "rx-jupyter";
import { v4 as uuid } from "uuid";

import { getServerConfig } from "../selectors";
import {
getServerConfig,
isCurrentHostJupyter,
isCurrentKernelJupyterWebsocket
} from "../selectors";

import {
LAUNCH_KERNEL,
Expand All @@ -40,10 +44,7 @@ export const launchWebSocketKernelEpic = (action$: *, store: *) =>
action$.pipe(
ofType(LAUNCH_KERNEL_BY_NAME),
// Only accept jupyter servers for the host with this epic
filter(action => {
const host = store.getState().app.host;
return host && host.type === "jupyter" && host.serverUrl;
}),
filter(() => isCurrentHostJupyter(store.getState())),
// TODO: When a switchMap happens, we need to close down the originating
// kernel, likely by sending a different action. Right now this gets
// coordinated in a different way.
Expand Down Expand Up @@ -71,21 +72,8 @@ export const launchWebSocketKernelEpic = (action$: *, store: *) =>
export const interruptKernelEpic = (action$: *, store: *) =>
action$.pipe(
ofType(INTERRUPT_KERNEL),
filter(() => {
const state = store.getState();
const host = state.app.host;
const kernel = state.app.kernel;

// This epic can only interrupt kernels on jupyter websockets
return (
host &&
kernel &&
host.type === "jupyter" &&
host.serverUrl &&
kernel.id &&
kernel.type === "websocket"
);
}),
// This epic can only interrupt kernels on jupyter websockets
filter(() => isCurrentKernelJupyterWebsocket(store.getState())),
// If the user fires off _more_ interrupts, we shouldn't interrupt the in-flight
// interrupt, instead doing it after the last one happens
concatMap(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as components from "./components";
import * as providers from "./providers";
import * as themes from "./themes";
import * as epics from "./epics";
import * as selectors from "./selectors";

// keeping with backwards compatiblity for now
const constants = actionTypes;
Expand All @@ -20,5 +21,6 @@ export {
components,
providers,
themes,
selectors,
epics
};
50 changes: 50 additions & 0 deletions packages/core/src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,53 @@ export const getServerConfig = createSelector(
token
})
);

// Quick memoized host and kernel selection.
//
// Intended to be useful for a core app and be future proof for when we have
// both refs and selected/current hosts and kernels
export const getCurrentHost = createSelector(
(state: AppState) => state.app.host,
host => host
);

export const getCurrentKernel = createSelector(
(state: AppState) => state.app.kernel,
kernel => kernel
);

export const getCurrentKernelType = createSelector(
[getCurrentKernel],
kernel => {
if (kernel && kernel.type) {
return kernel.type;
}
return null;
}
);

export const getCurrentHostType = createSelector([getCurrentHost], host => {
if (host && host.type) {
return host.type;
}
return null;
});

export const isCurrentKernelZeroMQ = createSelector(
[getCurrentHostType, getCurrentKernelType],
(hostType, kernelType) => {
return hostType === "local" && kernelType === "zeromq";
}
);

export const isCurrentHostJupyter = createSelector(
[getCurrentHostType],
hostType => hostType === "jupyter"
);

export const isCurrentKernelJupyterWebsocket = createSelector(
[getCurrentHostType, getCurrentKernelType],
(hostType, kernelType) => {
return hostType === "jupyter" && kernelType === "websocket";
}
);

0 comments on commit ce305cb

Please sign in to comment.