Skip to content

fix(ray): propagate original function name to Ray metrics instead of generic _capture [ENG-358]#128

Merged
eywalker merged 2 commits intonauticalab:devfrom
brian-arnold:dev
Apr 7, 2026
Merged

fix(ray): propagate original function name to Ray metrics instead of generic _capture [ENG-358]#128
eywalker merged 2 commits intonauticalab:devfrom
brian-arnold:dev

Conversation

@brian-arnold
Copy link
Copy Markdown
Collaborator

This PR reimplements the feature that the function passed to Ray retains it's original name, instead of getting passed as _capture. This way, functions show of as distinct entities in Grafana dashboards.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/orcapod/core/executors/ray.py 80.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Ray executor’s remote capture wrapper creation so Ray reports the original packet function name in Ray metrics/dashboard (instead of the generic _capture), improving observability in Grafana.

Changes:

  • Pass the target function name into RayExecutor._get_remote_fn() and cache remote wrappers by (remote_opts, fn_name).
  • Extend make_capture_wrapper() to optionally set the wrapper function’s __name__ / __qualname__ to the original function name.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/orcapod/core/executors/ray.py Creates/caches Ray-remote wrappers per function name so Ray metrics reflect the executed function’s name.
src/orcapod/core/executors/capture_wrapper.py Adds an optional name parameter to rename the capture wrapper function for remote-framework reporting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +15 to +22
def make_capture_wrapper(name: str | None = None) -> Callable[..., Any]:
"""Return a capture wrapper suitable for remote execution.

Args:
name: If provided, the wrapper's ``__name__`` and ``__qualname__``
are set to this value so that remote frameworks (e.g. Ray) report
the original function name in dashboards and metrics rather than
the generic ``_capture``.
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior (setting wrapper name/qualname when name is provided) isn't covered by tests. Please add a unit test asserting that make_capture_wrapper(name="...") returns a callable whose __name__ and __qualname__ match the provided name (and that default None keeps the original _capture name).

Copilot uses AI. Check for mistakes.
Comment on lines 240 to 248
opts = self._build_remote_opts()
cache_key = self._normalize_opts(opts)
cache_key = (self._normalize_opts(opts), fn_name)
if cache_key not in self._remote_fn_cache:
with self._remote_fn_cache_lock:
# Double-checked: another thread may have filled the slot
# while we waited for the lock.
if cache_key not in self._remote_fn_cache:
wrapper = make_capture_wrapper()
wrapper = make_capture_wrapper(name=fn_name)
self._remote_fn_cache[cache_key] = ray.remote(**opts)(wrapper)
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_get_remote_fn() now caches remote wrappers per (remote_opts, fn_name). If callers can generate many distinct function names (e.g., dynamically generated callables), this cache can grow without bound over the lifetime of the process. Consider bounding/evicting entries (e.g., LRU) or normalizing the name to a stable identifier (such as module + qualname) to avoid unexpected memory growth.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged — in practice the set of function names is bounded by the pipeline's topology (a fixed, small number of packet functions defined at construction time), so unbounded growth isn't a realistic concern here. Dismissing as not applicable.

Comment on lines 182 to 210
@@ -206,7 +206,7 @@ async def async_execute_callable(
import ray

self._ensure_ray_initialized()
remote_fn = self._get_remote_fn(ray)
remote_fn = self._get_remote_fn(ray, fn.__name__)
ref = remote_fn.options(name=fn.__name__).remote(fn, kwargs)
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metrics-related change (propagating fn.__name__ into the Ray-remote wrapper via _get_remote_fn(..., fn.__name__)) isn't covered by tests. Adding a unit test with a mocked ray module that asserts make_capture_wrapper(name=...) is used and that different fn_name values result in distinct cached remote functions would help prevent regressions.

Copilot uses AI. Check for mistakes.
@brian-arnold brian-arnold requested a review from eywalker April 4, 2026 01:18
@brian-arnold brian-arnold changed the title fix(ray): propagate original function name to Ray metrics instead of generic _capture fix(ray): propagate original function name to Ray metrics instead of generic _capture [ENG-358] Apr 4, 2026
@eywalker eywalker merged commit 5935264 into nauticalab:dev Apr 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants