From 811ee649cd691d0ff1752f146c022a079a92f874 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Wed, 21 Sep 2022 15:47:50 +0200 Subject: [PATCH] Throttle events in pyodide --- panel/_templates/pyodide_worker.js | 5 ++-- panel/io/convert.py | 39 ++++++++++++++++++++++++------ panel/io/pyodide.py | 21 ++++++++++------ 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/panel/_templates/pyodide_worker.js b/panel/_templates/pyodide_worker.js index ff966b9b1a..b455b4b48f 100644 --- a/panel/_templates/pyodide_worker.js +++ b/panel/_templates/pyodide_worker.js @@ -37,14 +37,15 @@ self.onmessage = async (event) => { from panel.io.state import state from panel.io.pyodide import _link_docs_worker - _link_docs_worker(state.curdoc, sendPatch) + _link_docs_worker(state.curdoc, sendPatch, setter='js') `) } else if (event.data.type === 'patch') { self.pyodide.runPythonAsync(` import json - state.curdoc.apply_json_patch(json.loads('${event.data.patch}')) + state.curdoc.apply_json_patch(json.loads('${event.data.patch}'), setter='js') `) + self.postMessage({type: 'idle'}) } } diff --git a/panel/io/convert.py b/panel/io/convert.py index 2e05ee28fc..edfa1b45e2 100644 --- a/panel/io/convert.py +++ b/panel/io/convert.py @@ -108,19 +108,44 @@ def _stdlibs(): PYODIDE_WORKER_SCRIPT = """ diff --git a/panel/io/pyodide.py b/panel/io/pyodide.py index 6f3e2bc929..63636902cb 100644 --- a/panel/io/pyodide.py +++ b/panel/io/pyodide.py @@ -129,7 +129,7 @@ def _model_json(model: Model, target: str) -> Tuple[Document, str]: version = __version__, )) -def _link_docs(pydoc: Document, jsdoc: Any) -> None: +def _link_docs(pydoc: Document, jsdoc: Any, setter: str | None =None) -> None: """ Links Python and JS documents in Pyodide ensuring taht messages are passed between them. @@ -140,29 +140,32 @@ def _link_docs(pydoc: Document, jsdoc: Any) -> None: The Python Bokeh Document instance to sync. jsdoc: Javascript Document The Javascript Bokeh Document instance to sync. + setter: str + Setter ID used for suppressing events. """ def jssync(event): - if (getattr(event, 'setter_id', None) is not None): + if (event.setter_id is not None and event.setter_id == setter): return - events = [event] - json_patch = jsdoc.create_json_patch_string(pyodide.ffi.to_js(events)) - pydoc.apply_json_patch(json.loads(json_patch)) + json_patch = jsdoc.create_json_patch_string(pyodide.ffi.to_js([event])) + pydoc.apply_json_patch(json.loads(json_patch), setter=setter) jsdoc.on_change(pyodide.ffi.create_proxy(jssync), pyodide.ffi.to_js(False)) def pysync(event): + if event.setter is not None and event.setter == setter: + return json_patch, buffers = process_document_events([event], use_buffers=True) buffer_map = {} for (ref, buffer) in buffers: buffer_map[ref['id']] = pyodide.ffi.to_js(buffer).buffer - jsdoc.apply_json_patch(JSON.parse(json_patch), pyodide.ffi.to_js(buffer_map), setter_id='js') + jsdoc.apply_json_patch(JSON.parse(json_patch), pyodide.ffi.to_js(buffer_map), setter_id=setter) pydoc.on_change(pysync) pydoc.callbacks.trigger_json_event( {'event_name': 'document_ready', 'event_values': {} }) -def _link_docs_worker(doc: Document, dispatch_fn: Any, msg_id: str | None = None): +def _link_docs_worker(doc: Document, dispatch_fn: Any, msg_id: str | None = None, setter: str | None = None): """ Links the Python document to a dispatch_fn which can be used to sync messages between a WebWorker and the main thread in the @@ -174,10 +177,14 @@ def _link_docs_worker(doc: Document, dispatch_fn: Any, msg_id: str | None = None The document to dispatch messages from. dispatch_fn: JS function The Javascript function to dispatch messages to. + setter: str + Setter ID used for suppressing events. msg_id: str | None An optional message ID to pass through to the dispatch_fn. """ def pysync(event): + if setter is not None and event.setter == setter: + return json_patch, buffers = process_document_events([event], use_buffers=True) buffer_map = {} for (ref, buffer) in buffers: