Skip to content

Commit 17f53e0

Browse files
authored
Merge pull request #19 from Quansight/feat/avoid-constant-pooling
Pool only the active kernel and if the sidebar is visible
2 parents b98c9f8 + 7ab05a4 commit 17f53e0

File tree

2 files changed

+53
-90
lines changed

2 files changed

+53
-90
lines changed

src/panel.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export class KernelUsagePanel extends StackedPanel {
2424
this.title.closable = true;
2525
const widget = new KernelUsageWidget({
2626
widgetAdded: props.widgetAdded,
27-
currentNotebookChanged: props.currentNotebookChanged
27+
currentNotebookChanged: props.currentNotebookChanged,
28+
panel: this
2829
});
2930
this.addWidget(widget);
3031
}

src/widget.tsx

Lines changed: 51 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { useState } from 'react';
2-
import { Poll } from '@lumino/polling';
32
import { ISignal } from '@lumino/signaling';
43
import { ReactWidget, ISessionContext } from '@jupyterlab/apputils';
54
import { IChangedArgs } from '@jupyterlab/coreutils';
65
import { Kernel } from '@jupyterlab/services';
76
import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
87
import { requestAPI } from './handler';
8+
import { KernelUsagePanel } from "./panel";
99
import useInterval from './useInterval';
1010
import { formatForDisplay } from './format';
1111

@@ -31,73 +31,31 @@ type Usage = {
3131

3232
const POLL_INTERVAL_SEC = 5;
3333

34-
const POLL_MAX_INTERVAL_SEC = 300;
35-
36-
type KernelPoll = {
37-
poll: Poll<void, any, 'stand-by'>;
38-
path: string;
39-
usage: Usage | undefined;
40-
};
41-
42-
const kernelPools = new Map<string, KernelPoll>();
43-
4434
const KernelUsage = (props: {
4535
widgetAdded: ISignal<INotebookTracker, NotebookPanel | null>;
4636
currentNotebookChanged: ISignal<INotebookTracker, NotebookPanel | null>;
37+
panel: KernelUsagePanel;
4738
}) => {
39+
const { panel } = props;
4840
const [kernelId, setKernelId] = useState<string>();
49-
const [refresh, setRefresh] = useState<boolean>(true);
41+
const [path, setPath] = useState<string>();
42+
const [usage, setUsage] = useState<Usage | undefined>();
5043

5144
useInterval(async () => {
52-
setRefresh(!refresh);
45+
if (kernelId && panel.isVisible) {
46+
requestUsage(kernelId).then(usage => setUsage(usage));
47+
}
5348
}, POLL_INTERVAL_SEC * 1000);
5449

55-
const requestUsage = async (kernelId: string) => {
56-
requestAPI<any>(`get_usage/${kernelId}`)
57-
.then(data => {
58-
const kernelPoll = kernelPools.get(kernelId);
59-
if (kernelPoll) {
60-
kernelPoll.usage = {
61-
...data.content,
62-
kernelId,
63-
timestamp: new Date()
64-
};
65-
kernelPools.set(kernelId, kernelPoll);
66-
}
67-
})
68-
.catch(reason => {
69-
console.error(
70-
`The kernelusage server extension has returned an error.\n${reason}`
71-
);
72-
const kernelPoll = kernelPools.get(kernelId);
73-
kernelPoll?.poll.stop().then(() => {
74-
kernelPools.delete(kernelId);
75-
});
76-
});
77-
};
78-
79-
const doPoll = (kernelId: string, path: string) => {
80-
let kernelPoll = kernelPools.get(kernelId);
81-
if (!kernelPoll) {
82-
const poll = new Poll<void, any, 'stand-by'>({
83-
auto: true,
84-
factory: () => requestUsage(kernelId),
85-
frequency: {
86-
interval: POLL_INTERVAL_SEC * 1000,
87-
backoff: true,
88-
max: POLL_MAX_INTERVAL_SEC * 1000
89-
},
90-
name: `@jupyterlab/kernel:KernelUsage#${kernelId}`,
91-
standby: 'never'
92-
});
93-
kernelPoll = {
94-
poll,
95-
path,
96-
usage: undefined
50+
const requestUsage = (kid: string) =>
51+
requestAPI<any>(`get_usage/${kid}`).then(data => {
52+
const usage: Usage = {
53+
...data.content,
54+
kernelId: kid,
55+
timestamp: new Date()
9756
};
98-
kernelPools.set(kernelId, kernelPoll);
99-
}
100-
};
57+
return usage;
58+
});
10159

10260
props.currentNotebookChanged.connect(
10361
(sender: INotebookTracker, panel: NotebookPanel | null) => {
@@ -110,17 +68,20 @@ const KernelUsage = (props: {
11068
'kernel'
11169
>
11270
) => {
71+
/*
11372
const oldKernelId = args.oldValue?.id;
11473
if (oldKernelId) {
11574
const poll = kernelPools.get(oldKernelId);
11675
poll?.poll.dispose();
11776
kernelPools.delete(oldKernelId);
11877
}
78+
*/
11979
const newKernelId = args.newValue?.id;
12080
if (newKernelId) {
12181
setKernelId(newKernelId);
12282
const path = panel?.sessionContext.session?.model.path;
123-
doPoll(newKernelId as string, path as string);
83+
setPath(path);
84+
requestUsage(newKernelId).then(usage => setUsage(usage));
12485
}
12586
}
12687
);
@@ -130,17 +91,17 @@ const KernelUsage = (props: {
13091
if (kernelId) {
13192
setKernelId(kernelId);
13293
const path = panel?.sessionContext.session?.model.path;
133-
doPoll(kernelId as string, path);
94+
setPath(path);
95+
requestUsage(kernelId).then(usage => setUsage(usage));
13496
}
13597
}
13698
}
13799
}
138100
);
139101

140102
if (kernelId) {
141-
const kernelPool = kernelPools.get(kernelId);
142-
if (kernelPool && kernelPool.usage) {
143-
return !kernelPool.usage.hostname ? (
103+
if (usage) {
104+
return !usage.hostname ? (
144105
<>
145106
<h3 className="jp-KernelUsage-section-separator">
146107
Kernel usage details are not available
@@ -154,60 +115,57 @@ const KernelUsage = (props: {
154115
<>
155116
<h3 className="jp-KernelUsage-section-separator">Kernel usage</h3>
156117
<div className="jp-KernelUsage-separator">
157-
Kernel Host: {kernelPool.usage.hostname}
158-
</div>
159-
<div className="jp-KernelUsage-separator">
160-
Notebook: {kernelPool.path}
118+
Kernel Host: {usage.hostname}
161119
</div>
120+
<div className="jp-KernelUsage-separator">Notebook: {path}</div>
162121
<div className="jp-KernelUsage-separator">Kernel ID: {kernelId}</div>
163122
<div className="jp-KernelUsage-separator">
164-
Timestamp: {kernelPool.usage.timestamp?.toLocaleString()}
123+
Timestamp: {usage.timestamp?.toLocaleString()}
165124
</div>
166125
<div className="jp-KernelUsage-separator">
167-
Process ID: {kernelPool.usage.pid}
126+
Process ID: {usage.pid}
168127
</div>
169128
<div className="jp-KernelUsage-separator">
170-
CPU: {kernelPool.usage.kernel_cpu}
129+
CPU: {usage.kernel_cpu}
171130
</div>
172131
<div className="jp-KernelUsage-separator">
173-
Memory: {formatForDisplay(kernelPool.usage.kernel_memory)}
132+
Memory: {formatForDisplay(usage.kernel_memory)}
174133
</div>
175134
<hr className="jp-KernelUsage-section-separator"></hr>
176135
<h4 className="jp-KernelUsage-section-separator">Host CPU</h4>
177-
<div className="jp-KernelUsage-separator">
178-
Percentage {kernelPool.usage.host_cpu_percent.toFixed(1)}
179-
</div>
136+
{usage.host_cpu_percent && (
137+
<div className="jp-KernelUsage-separator">
138+
Percentage {usage.host_cpu_percent.toFixed(1)}
139+
</div>
140+
)}
180141
<h4 className="jp-KernelUsage-section-separator">
181142
Host Virtual Memory
182143
</h4>
183144
<div className="jp-KernelUsage-separator">
184-
Active:{' '}
185-
{formatForDisplay(kernelPool.usage.host_virtual_memory.active)}
186-
</div>
187-
<div className="jp-KernelUsage-separator">
188-
Available:{' '}
189-
{formatForDisplay(kernelPool.usage.host_virtual_memory.available)}
145+
Active: {formatForDisplay(usage.host_virtual_memory.active)}
190146
</div>
191147
<div className="jp-KernelUsage-separator">
192-
Free: {formatForDisplay(kernelPool.usage.host_virtual_memory.free)}
148+
Available: {formatForDisplay(usage.host_virtual_memory.available)}
193149
</div>
194150
<div className="jp-KernelUsage-separator">
195-
Inactive:{' '}
196-
{formatForDisplay(kernelPool.usage.host_virtual_memory.inactive)}
151+
Free: {formatForDisplay(usage.host_virtual_memory.free)}
197152
</div>
198153
<div className="jp-KernelUsage-separator">
199-
Percent: {kernelPool.usage.host_virtual_memory.percent.toFixed(1)}
154+
Inactive: {formatForDisplay(usage.host_virtual_memory.inactive)}
200155
</div>
156+
{usage.host_virtual_memory.percent && (
157+
<div className="jp-KernelUsage-separator">
158+
Percent: {usage.host_virtual_memory.percent.toFixed(1)}
159+
</div>
160+
)}
201161
<div className="jp-KernelUsage-separator">
202-
Total:{' '}
203-
{formatForDisplay(kernelPool.usage.host_virtual_memory.total)}
162+
Total: {formatForDisplay(usage.host_virtual_memory.total)}
204163
</div>
205164
<div className="jp-KernelUsage-separator">
206-
Used: {formatForDisplay(kernelPool.usage.host_virtual_memory.used)}
165+
Used: {formatForDisplay(usage.host_virtual_memory.used)}
207166
</div>
208167
<div className="jp-KernelUsage-separator">
209-
Wired:{' '}
210-
{formatForDisplay(kernelPool.usage.host_virtual_memory.wired)}
168+
Wired: {formatForDisplay(usage.host_virtual_memory.wired)}
211169
</div>
212170
</>
213171
);
@@ -222,20 +180,24 @@ export class KernelUsageWidget extends ReactWidget {
222180
INotebookTracker,
223181
NotebookPanel | null
224182
>;
183+
private _panel: KernelUsagePanel;
225184
constructor(props: {
226185
widgetAdded: ISignal<INotebookTracker, NotebookPanel | null>;
227186
currentNotebookChanged: ISignal<INotebookTracker, NotebookPanel | null>;
187+
panel: KernelUsagePanel;
228188
}) {
229189
super();
230190
this._widgetAdded = props.widgetAdded;
231191
this._currentNotebookChanged = props.currentNotebookChanged;
192+
this._panel = props.panel;
232193
}
233194

234195
protected render(): React.ReactElement<any> {
235196
return (
236197
<KernelUsage
237198
widgetAdded={this._widgetAdded}
238199
currentNotebookChanged={this._currentNotebookChanged}
200+
panel={this._panel}
239201
/>
240202
);
241203
}

0 commit comments

Comments
 (0)