Skip to content

Commit

Permalink
Enable run and detached with registered functions (#132)
Browse files Browse the repository at this point in the history
* Enable run and detached with registered functions

* resonate run registeredfn
  • Loading branch information
Tomperez98 authored Jan 23, 2025
1 parent 3f61e69 commit a430f01
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
13 changes: 12 additions & 1 deletion src/resonate/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ def lfc(
unit = Invocation(func_or_cmd, *args, **kwargs)
return LFC(unit)

@overload
def detached(
self,
id: str,
coro: RegisteredFn[P, Any],
/,
*args: P.args,
**kwargs: P.kwargs,
) -> DI: ...
@overload
def detached(
self,
Expand All @@ -240,7 +249,7 @@ def detached(
def detached(
self,
id: str,
coro: DurableCoro[P, T] | DurableFn[P, T],
coro: DurableCoro[P, T] | DurableFn[P, T] | RegisteredFn[P, T],
/,
*args: P.args,
**kwargs: P.kwargs,
Expand All @@ -251,4 +260,6 @@ def detached(
Invoke as a root invocation. Is equivalent to do ``Scheduler.run(...)``
invoked execution will be retried and managed from the server.
"""
if isinstance(coro, RegisteredFn):
coro = coro.fn
return DI(id=id, unit=Invocation(coro, *args, **kwargs))
14 changes: 13 additions & 1 deletion src/resonate/resonate.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ def register(
)
return RegisteredFn[P, T](self._scheduler, func)

@overload
def run(
self,
id: str,
func: RegisteredFn[P, T],
/,
*args: P.args,
**kwargs: P.kwargs,
) -> Handle[T]: ...
@overload
def run(
self,
Expand Down Expand Up @@ -183,7 +192,8 @@ def run(
def run(
self,
id: str,
func: Callable[
func: RegisteredFn[P, T]
| Callable[
Concatenate[Context, P],
Generator[Yieldable, Any, T],
]
Expand All @@ -204,4 +214,6 @@ def run(
) -> Handle[T]:
if isinstance(func, tuple):
raise NotImplementedError
if isinstance(func, RegisteredFn):
func = func.fn
return self._scheduler.run(id, func, *args, **kwargs)
44 changes: 44 additions & 0 deletions tests/test_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,3 +780,47 @@ def baz_golden_device_detached(
assert isinstance(p, Handle)
assert p.result() == "hi"
resonate.stop()


@pytest.mark.skipif(
os.getenv("RESONATE_STORE_URL") is None, reason="env variable is not set"
)
def test_golden_device_detached_with_registered() -> None:
group = "test-golden-device-detached"
resonate = Resonate(
store=RemoteStore(url=os.environ["RESONATE_STORE_URL"]),
task_source=Poller("http://localhost:8002", group=group),
)

@resonate.register
def foo_golden_device_detached_with_registered(
ctx: Context, n: str
) -> Generator[Yieldable, Any, str]:
p: Promise[str] = yield ctx.detached(
"bar", bar_golden_device_detached_with_registered, n
)
yield ctx.detached("baz.1", baz_golden_device_detached_with_registered, p.id)
yield ctx.detached("baz.2", baz_golden_device_detached_with_registered, p.id)
yield ctx.detached("baz.3", baz_golden_device_detached_with_registered, p.id)
v: str = yield p
return v

@resonate.register
def bar_golden_device_detached_with_registered(ctx: Context, n: str) -> str: # noqa: ARG001
return n

@resonate.register
def baz_golden_device_detached_with_registered(
ctx: Context, # noqa: ARG001
promise_id: str,
) -> Generator[Yieldable, Any, str]:
v: str = yield Promise[str](promise_id)
return v

p: Handle[str] = resonate.run(
f"{group}-foo", foo_golden_device_detached_with_registered, "hi"
)

assert isinstance(p, Handle)
assert p.result() == "hi"
resonate.stop()

0 comments on commit a430f01

Please sign in to comment.