Advanced Remote Calls & Non-Blocking Execution

Even though enabling Ray ensures that one plugin’s heavy workload will not block other plugins, it does not prevent blocking inside a single plugin itself.

If some part of your plugin code performs a blocking operation (e.g., time.sleep, long-running computation, or a non-async library call), the entire plugin instance may become unresponsive.

FrameX provides the @remote decorator to solve this issue:

  • it offloads the decorated function to distributed execution (via Ray when enabled, or a fallback mechanism otherwise), making it non-blocking by design.

1) How It Works

  • Add @remote() to a method (sync or async).
  • Call it with .remote(...) instead of normal invocation.
  • FrameX automatically executes the method in a separate worker (via Ray when available).
  • Your plugin remains responsive, even if the method blocks.

2) Supported Function Types

The @remote decorator is fully compatible with:

  • Regular (synchronous) functions
  • Asynchronous (async) functions
  • Instance methods (with self)
  • Static methods and class methods

3) Example Highlights

1. Add @remote() to a method.

(a). Blocking synchronous function

@remote()
def remote_sleep():
    time.sleep(0.1)
    return "remote_sleep"

(b). Asynchronous function

@remote()
async def remote_func_async_with_params(a: int, b: str):
    return f"{a}, {b}"

(c). Class instance method

class Worker:
    @remote()
    def heavy_compute(self, n: int):
        return sum(i * i for i in range(n))

(d). Static method

class Utils:
    @remote()
    @staticmethod
    def convert(data: str) -> str:
        time.sleep(1)
        return data.upper()

2. Call it with .remote(...) instead of normal invocation.

results = [
    await remote_sleep.remote(),
    await remote_func_async_with_params.remote(123, "abc"),
    await Worker().heavy_compute.remote(10000),
    await Utils.convert.remote("framex"),
]

3) Key Benefits

  • ✅ Prevents plugin self-blocking.
  • ✅ Works with both sync and async methods.
  • ✅ Transparent: no code changes needed when Ray is disabled/enabled.
  • ✅ Simple syntax: .remote(...) for non-blocking execution.

With @remote, you can safely use blocking libraries, legacy synchronous code, or heavy computations inside FrameX plugins, while still keeping your APIs responsive and scalable.