-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Jupyter comms server #145
base: main
Are you sure you want to change the base?
Conversation
@@ -1,41 +1,104 @@ | |||
import hglib from "https://esm.sh/[email protected]?deps=react@17,react-dom@17,pixi.js@6"; | |||
// import hglib from "https://esm.sh/[email protected]?deps=react@17,react-dom@17,pixi.js@6"; | |||
import * as hglib from "http://localhost:5173/app/scripts/hglib.jsx"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing with Vite locally and PR from higlass
Notebooks test code with a widget to collect the Tilesets. A collection of tilesets (should be weakrefable), that handles fulfilling requests from the front end. import higlass as hg
import ipywidgets
import traitlets
import itertools
class Tilesets(ipywidgets.DOMWidget):
value = traitlets.Int(0).tag(sync=True)
def __init__(self):
super().__init__()
self.on_msg(self._handle_custom_msg)
self.ts = dict()
def add(self, ts):
self.ts[ts.tileset.uid] = ts.tileset
return self
def _handle_custom_msg(self, data, buffers):
payload = data["payload"]
uuid = data["uuid"]
match payload:
case { "type": "tileset_info", "tilesetUid": uid }:
info = { uid: self.ts[uid].info() }
self.send({ "uuid": uuid, "payload": info })
case { "type": "tiles", "tileIds": tids }:
all_tiles = []
for uid, tids in itertools.groupby(
iterable=sorted(tids), key=lambda tid: tid.split(".")[0]
):
tiles = self.ts[uid].tiles(list(tids))
all_tiles.extend(tiles)
data = {tid: tval for tid, tval in all_tiles}
self.send({ "uuid": uuid, "payload": data })
case _:
raise ValueError("Something's wrong with the Internet")
ts = hg.cooler("./test.mcool")
tss = Tilesets().add(ts)
track = ts.track("heatmap")
hg.view(track, width=6).widget(ts=tss) |
Just other ideas. A tile request "coordinator", that can be shared among tracks. It waits an animation frame to see all the desired tiles, and then dispatches a single server request. class TileRequestCoordinator {
#model;
#requests;
#frameRequested = false;
constructor(model) {
this.#model = model;
this.#requests = [];
}
async fetchTilesetInfo({ tilesetUid }) {
let { data } = await send(this.#model, { type: "tileset_info", tilesetUid });
return data;
}
async fetchTiles({ tileIds }) {
if (!this.#frameRequested) {
this.#frameRequested = true;
requestAnimationFrame(() => this.#processRequests());
}
let { promise, resolve, reject } = Promise.withResolvers();
this.#requests.push({ tileIds, resolve, reject });
return promise;
}
async #processRequests() {
this.#frameRequested = false;
let ids = [...new Set(this.#requests.flatMap((r) => r.tileIds))];
let { data: resp } = await send(this.#model, { type: "tiles", tileIds: ids });
let data = tileResponseToData(resp, "jupyter", ids);
for (let { tileIds, resolve } of this.#requests) {
let tileData = Object.fromEntries(tileIds.map((id) => [id, data[id]]));
resolve(tileData);
}
this.#requests.length = 0;
}
registerTileset() {
throw new Error("Not implemented");
}
} |
Relevant PR that benefits from a similar kind of architecture (and ability to drop jupyter-server-proxy): |
Depends on higlass/higlass#1194. I have just got this working locally with Vite.