This repository has been archived by the owner on Jul 31, 2019. It is now read-only.
/
app.js
executable file
·153 lines (127 loc) · 4.48 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env electron
"use strict";
var app = require('app'); // Electron app
var BrowserWindow = require('browser-window'); // Creating Browser Windows
var globalShortcut = require('global-shortcut');
var jupyter = require("./lib/jupyter.js");
var RuntimeWatch = require("./lib/runtime-watch.js");
var jp = require('jupyter-paths');
// Report crashes to our server.
require('crash-reporter').start();
// Quit when all windows are closed.
app.on('window-all-closed', function() {
// Fully close up, even on OS X
app.quit();
});
function launchSideCar(session) {
// Keep a global reference of the side car window object
// If we don't, the window will be closed automatically when the javascript
// object is GCed.
var sideCar = null;
// Create the browser window.
sideCar = new BrowserWindow({
width: 800,
height: 800,
//"node-integration": false, // Would have to use a web-view and work with events
frame: false
});
// and load the index.html of the app.
sideCar.loadUrl('file://' + __dirname + '/index.html');
sideCar.webContents.on('did-finish-load', function () {
session.on(function (message) {
sideCar.webContents.send("message", message);
});
});
// Emitted when the window is closed.
sideCar.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
sideCar = null;
});
return sideCar;
}
let liveSidecars = new Map();
function updateKernel(connFiles) {
for (let i = 0; i < connFiles.length; i++) {
let
connPath = connFiles[i].path,
connStat = connFiles[i].stat;
if (connStat.nlink !== 0) {
// This connection file is still present. Create a connection and probe its heartbeat to
// verify that the kernel is still responsive.
let config = require(connPath);
let session = new jupyter.IOPubSession(config);
session.checkHealth(makeHeartbeatHandler(connPath, session));
} else {
handleDeadKernel(connPath);
}
}
}
/**
* Callback to be executed with the result of a specific kernel's heartbeat.
* @callback heartbeatHandler
* @param alive {bool} True if the kernel responded to a probe, false if it timed out.
*/
/**
* Ensure that the sidecar corresponding to a connection file is alive or dead depending on the
* response from the session's heartbeat.
*
* @param connPath {string} the filesystem path to the connection JSON file.
* @param session {jupyter.IOPubSession} an opened session to this kernel.
*/
function makeHeartbeatHandler(connPath, session) {
return function (alive) {
console.log("Kernel " + connPath + " responded to a heartbeat with: " + alive);
if (alive) {
handleLiveKernel(connPath, session);
} else {
handleDeadKernel(connPath);
}
};
}
/**
* A kernel at the given connection path is alive and responding to heartbeat messages. Launch a
* new sidecar window if it does exist already.
*
* @param connPath {string} the filesystem path to the connection JSON file.
* @param session {jupyter.IOPubSession} an opened session to this kernel.
*/
function handleLiveKernel(connPath, session) {
if (! liveSidecars.has(connPath)) {
console.log("Launching sidecar for connection " + connPath + ".");
liveSidecars.set(connPath, launchSideCar(session));
}
}
/**
* A kernel connection JSON file has been deleted from the filesystem, or the kernel that a JSON
* file is referencing no longer responds to a heartbeat. Locate the sidecar window corresponding
* to this kernel and shut it down.
*
* @param connPath {string} the filesystem path to the connection JSON file.
*/
function handleDeadKernel(connPath) {
console.log("Connection " + connPath + " is no longer present.");
if (liveSidecars.has(connPath)) {
console.log("Closing the corresponding sidecar.");
liveSidecars.get(connPath).close();
liveSidecars.delete(connPath);
}
}
var kw = new RuntimeWatch(updateKernel, jp.paths.runtime[0]);
// This method will be called when Electron has done every
// initialization and is ready for creating browser windows.
app.on('ready', function() {
globalShortcut.register('Alt+CmdOrCtrl+I', function () {
var win = BrowserWindow.getFocusedWindow();
if (win) {
win.toggleDevTools();
}
});
globalShortcut.register('CmdOrCtrl+R', function () {
var win = BrowserWindow.getFocusedWindow();
if (win) {
win.reloadIgnoringCache();
}
});
});