Skip to content

Commit ed60492

Browse files
committed
widgets: a little code org before we start implementing buffers for custom messages from backend to frontend
1 parent b3b66f2 commit ed60492

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

src/packages/frontend/jupyter/widgets/manager2.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,19 @@ VBox([s1, s2])
330330
const message = this.ipywidgets_state.get_message(model_id);
331331
log("handleMessageChange: ", model_id, message);
332332
if (size(message) == 0) {
333-
// TODO: temporary until we have delete functionality (?)
333+
// TODO: temporary until we have delete functionality for tables
334+
log("handleMessageChange: message is empty -- nothing to do");
334335
return;
335336
}
337+
log("handleMessageChange: getting model", model_id);
336338
const model = await this.manager.get_model(model_id);
337-
if (model == null) {
338-
log("handleMessageChange: no model yet");
339-
return;
340-
}
339+
log(
340+
"handleMessageChange:",
341+
"got model",
342+
model_id,
343+
"and now sending msg:custom",
344+
message,
345+
);
341346
model.trigger("msg:custom", message);
342347
};
343348

@@ -613,15 +618,11 @@ class Environment implements WidgetEnvironment {
613618
}
614619

615620
async loadClass(
616-
className: string,
617-
moduleName: string,
621+
_className: string,
622+
_moduleName: string,
618623
_moduleVersion: string,
619624
): Promise<any> {
620-
if (false && moduleName === "k3d") {
621-
// NOTE: I completely rewrote the entire k3d widget interface...
622-
console.log("using builtin k3d");
623-
return await import("k3d")[className];
624-
}
625+
return;
625626
}
626627

627628
async getSerializedModelState(model_id) {

src/packages/jupyter/kernel/kernel.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,9 @@ class JupyterKernel extends EventEmitter implements JupyterKernelInterface {
976976
return;
977977
}
978978
const dbg = this.dbg("process_comm_message_from_kernel");
979-
dbg(mesg);
979+
// This can be HUGE so don't print out the entire message; e.g., it could contain
980+
// massive binary data!
981+
dbg(mesg.header);
980982
this._actions.process_comm_message_from_kernel(mesg);
981983
}
982984

src/packages/sync/editor/generic/ipywidgets-state.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type Value = { [key: string]: any };
3737
// Also, we don't implement complete object delete yet so instead we
3838
// set the data field to null, which clears all state about and
3939
// object and makes it easy to know to ignore it.
40+
// We also use this time for deleting ephemeral messages.
4041
const GC_DEBOUNCE_MS = 10000;
4142

4243
// If for some reason GC needs to be deleted, e.g., maybe you
@@ -475,11 +476,16 @@ scat.x, scat.y = np.random.rand(2, 50)
475476
}
476477
const [string_id, model_id, type] = JSON.parse(key);
477478
if (!activeIds.has(model_id)) {
479+
// Delete this model from the table (or as close to delete as we have).
478480
this.table.set(
479481
{ string_id, type, model_id, data: null },
480482
"none",
481483
false,
482484
);
485+
486+
// Also delete buffers for this model, which are stored in memory, and
487+
// won't be requested again.
488+
delete this.buffers[model_id];
483489
}
484490
});
485491
await this.table.save();
@@ -682,6 +688,8 @@ scat.x, scat.y = np.random.rand(2, 50)
682688
// the other data; otherwise, deserialization on
683689
// the client side can't work, since it is missing
684690
// the data it needs.
691+
// This happens with method "update". With method="custom",
692+
// there is just an array of buffers and no buffer_paths at all.
685693
if (content.data.buffer_paths?.length > 0) {
686694
// Deal with binary buffers:
687695
dbg("setting binary buffers");
@@ -696,9 +704,19 @@ scat.x, scat.y = np.random.rand(2, 50)
696704
switch (content.data.method) {
697705
case "custom":
698706
const message = content.data.content;
699-
dbg("custom message", message);
700-
// NOTE: any buffers that are part of this comm message
701-
// already got set above.
707+
const { buffers } = msg;
708+
dbg("custom message", {
709+
message,
710+
buffers: `${buffers?.length ?? "no"} buffers`,
711+
});
712+
if (
713+
buffers != null &&
714+
buffers.length > 0 &&
715+
content.data.buffer_paths == null
716+
) {
717+
// TODO
718+
dbg("custom message -- there are BUFFERS -- NOT implemented!!");
719+
}
702720
// We now send the message.
703721
this.sendCustomMessage(model_id, message, false);
704722
break;
@@ -893,10 +911,14 @@ with out:
893911
via the table for a few seconds, then remove it. Any clients
894912
that are connected while we do this can react, and any that aren't
895913
just don't get the message (which is presumably fine).
914+
915+
Some widgets like ipympl use this to initialize state, so when a new
916+
client connects, it requests a message describing the plot, and everybody
917+
receives it.
896918
*/
897919

898920
this.set(model_id, "message", message, fire_change_event);
899-
await delay(3000);
921+
await delay(GC_DEBOUNCE_MS);
900922
// Actually, delete is not implemented for synctable, so for
901923
// now we just set it to an empty message.
902924
this.set(model_id, "message", {}, fire_change_event);

0 commit comments

Comments
 (0)