Skip to content

Commit

Permalink
feat: use_execution_context hook (#205)
Browse files Browse the repository at this point in the history
The hook can be used to call code within an execution context

It is a fairly niche hook, but here as an example of it being used to do
a table update on a separate thread

```
import deephaven.ui as ui
import threading
from deephaven.execution_context import get_exec_ctx
from deephaven import agg as agg
import deephaven.pandas as dhpd
import deephaven.plot.express as dx

stocks = dx.data.stocks()

def print_sym(source):
    print(dhpd.to_pandas(source.update(["Symbol = sym"]) \
        .agg_by([agg.avg(cols=["AVG = size"])], by=["Symbol"])))

@ui.component
def exec_ctx_hook(source):

    with_exec_ctx = ui.use_execution_context()
    
    def thread_func():
        #print_sym(source)
        with_exec_ctx(lambda: print_sym(source))

    def start_thread():
        thread = threading.Thread(target=thread_func)
        thread.start()

    ui.use_memo(start_thread, source)

    return None

exec_hook = exec_ctx_hook(stocks)
```

Fixes #184
  • Loading branch information
jnumainville authored Jan 23, 2024
1 parent 63945e7 commit 76cd7ab
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugins/ui/src/deephaven/ui/hooks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .use_row_data import use_row_data
from .use_row_list import use_row_list
from .use_cell_data import use_cell_data
from .use_execution_context import use_execution_context


__all__ = [
Expand All @@ -25,4 +26,5 @@
"use_row_data",
"use_row_list",
"use_cell_data",
"use_execution_context",
]
36 changes: 36 additions & 0 deletions plugins/ui/src/deephaven/ui/hooks/use_execution_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from __future__ import annotations

from functools import partial
from typing import Callable

from deephaven.execution_context import get_exec_ctx, ExecutionContext

from . import use_memo


def func_with_ctx(
exec_ctx: ExecutionContext,
func: Callable,
) -> None:
"""
Call the function within an execution context.
Args:
exec_ctx: ExecutionContext: The execution context to use.
func: Callable: The function to call.
"""
with exec_ctx:
func()


def use_execution_context(exec_ctx: ExecutionContext = None) -> None:
"""
Create an execution context wrapper for a function.
Args:
exec_ctx: ExecutionContext: The execution context to use. Defaults to
the current execution context if not provided.
"""
exec_ctx = use_memo(lambda: exec_ctx if exec_ctx else get_exec_ctx(), [exec_ctx])
exec_fn = use_memo(lambda: partial(func_with_ctx, exec_ctx), [exec_ctx])
return exec_fn
48 changes: 48 additions & 0 deletions plugins/ui/test/deephaven/ui/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,54 @@ def _test_cell_data(t=table):

self.assertEqual(result, expected)

def test_execution_context(self):
from deephaven.ui.hooks import use_execution_context, use_state, use_memo
from deephaven import empty_table

def _test_execution_context():
with_exec_ctx = use_execution_context()

def table_func():
# This would fail if not using an execution context
empty_table(0).update("X=1")

def thread_func():
with_exec_ctx(table_func)

def start_thread():
thread = threading.Thread(target=thread_func)
thread.start()
thread.join()

use_memo(start_thread, [])

render_hook(_test_execution_context)

def test_execution_context_custom(self):
from deephaven.ui.hooks import use_execution_context, use_state, use_memo
from deephaven import empty_table
from deephaven.execution_context import make_user_exec_ctx

table = None

def _test_execution_context():
with_exec_ctx = use_execution_context(make_user_exec_ctx())

def table_func():
# This would fail if not using an execution context
empty_table(0).update("X=1")

def thread_func():
with_exec_ctx(table_func)

def start_thread():
thread = threading.Thread(target=thread_func)
thread.start()

use_memo(start_thread, [])

render_hook(_test_execution_context)


if __name__ == "__main__":
unittest.main()

0 comments on commit 76cd7ab

Please sign in to comment.