You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何清理Ray对象关联的非序列化状态并注册驱逐回调?

Ray对象驱逐时触发创建者Actor的清理回调方法

问题场景

我有一个Ray Actor,用于创建关联非序列化状态(示例为临时目录)的Ray对象,现有代码如下:

class MyObject:
    pass

_non_serializable_states = {}

@ray.remote
class MyCreatorActor:
    def create(self):
        ref = ray.put(MyObject())
        _non_serializable_states[ref] = tempfile.mkdtemp()
        return ref

当该Ray对象的分布式引用计数归0(即ref被驱逐)时,希望在创建者Actor的工作进程中触发以下清理函数:

def on_evicted(ref):
    shutil.rmtree(_non_serializable_states[ref])
    del _non_serializable_states[ref]

请问如何修改MyCreatorActor.create方法注册该回调?Ray是否有类似weakref.ref(obj, callback)的API?


解决方案

Ray没有完全等同于Python标准库weakref.ref的直接API,但可以通过两种稳定方式实现需求:

方法1:后台线程监听对象引用释放

在Actor内部启动一个守护线程,通过ray.wait循环监听对象引用的释放状态,一旦引用被驱逐就触发清理回调。这种方法兼容性强,适用于所有Ray稳定版本:

import ray
import tempfile
import shutil
import threading
import time

class MyObject:
    pass

_non_serializable_states = {}

def on_evicted(ref):
    shutil.rmtree(_non_serializable_states[ref])
    del _non_serializable_states[ref]

@ray.remote
class MyCreatorActor:
    def __init__(self):
        self._pending_refs = set()
        # 启动后台监听线程
        self._listener_thread = threading.Thread(target=self._monitor_releases, daemon=True)
        self._listener_thread.start()

    def _monitor_releases(self):
        while True:
            if not self._pending_refs:
                time.sleep(0.1)
                continue
            # 等待所有待监听引用被释放
            ready_refs, _ = ray.wait(list(self._pending_refs), num_returns=len(self._pending_refs), timeout=None)
            for ref in ready_refs:
                on_evicted(ref)
                self._pending_refs.remove(ref)

    def create(self):
        ref = ray.put(MyObject())
        temp_dir = tempfile.mkdtemp()
        _non_serializable_states[ref] = temp_dir
        self._pending_refs.add(ref)
        return ref

说明

  • Actor初始化时启动的守护线程会持续运行,监听所有待处理的对象引用。
  • ray.wait会在对象引用的分布式计数归0(被驱逐)时,将该引用标记为ready,此时即可触发清理逻辑。

方法2:使用Ray实验性对象释放回调API

如果使用的Ray版本支持(建议v1.13+),可以直接使用ray.experimental.register_object_release_callback为ObjectRef注册释放回调,代码更简洁:

import ray
import tempfile
import shutil

class MyObject:
    pass

_non_serializable_states = {}

def on_evicted(ref):
    shutil.rmtree(_non_serializable_states[ref])
    del _non_serializable_states[ref]

@ray.remote
class MyCreatorActor:
    def create(self):
        ref = ray.put(MyObject())
        temp_dir = tempfile.mkdtemp()
        _non_serializable_states[ref] = temp_dir
        # 注册释放回调
        ray.experimental.register_object_release_callback(ref, on_evicted)
        return ref

说明

  • 该API是实验性特性,未来可能有接口变动,使用前需确认版本兼容性。
  • 回调会在对象被驱逐时,在创建该引用的Actor工作进程中触发,无需额外线程管理。

内容的提问来源于stack exchange,提问作者Yang Bo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:28:39