Ray框架:event_stats.cc使用CoreWorkerProcess及快速编译求助
Ray C++开发问题解答
问题背景
为区分rpc_address是本地节点还是远程节点,我在event_stats.cc中添加了如下代码:
const auto &rpc_address = CoreWorkerProcess::GetCoreWorker().GetRpcAddress(); RAY_LOG(INFO) << rpc_address.SerializeAsString() << "\n\n";
随后在BUILD.bazel中为ray_common添加core_worker_lib依赖,却出现循环依赖错误:
ERROR: /home/Ray/ray/BUILD.bazel:2028:11: in cc_library rule //:gcs_client_lib: cycle in dependency graph: //:ray_pkg //:cp_raylet //:raylet //:raylet_lib .-> //:gcs_client_lib | //:gcs_service_rpc | //:pubsub_lib | //:pubsub_rpc | //:grpc_common_lib | //:ray_common | //:core_worker_lib `-- //:gcs_client_lib
技术问题
- 如何在
event_stats.cc中正确使用CoreWorkerProcess? - 修改Ray的C++代码后,除了执行
pip3 install -e . --verbose,是否有更快的重新编译方式?
解答
1. 解决event_stats.cc中CoreWorkerProcess的使用与循环依赖问题
循环依赖的核心是ray_common与core_worker_lib形成了双向依赖链,可通过以下三种方案解决:
- 依赖注入传递地址
不在event_stats.cc中主动调用CoreWorkerProcess::GetCoreWorker(),而是在EventStats初始化时,从外部(比如core_worker的启动代码)将RPC地址作为参数传入。这样ray_common无需依赖core_worker_lib,彻底切断循环。 - 抽象接口解耦
在一个独立的无循环依赖的公共库中定义抽象接口(如NodeAddressProvider),让core_worker_lib实现该接口,ray_common仅依赖这个抽象接口而非具体的CoreWorkerProcess。程序启动时将实现类实例注入给EventStats使用。 - 调整代码归属
评估event_stats.cc的职责,如果它更偏向core worker相关的统计逻辑,直接将其迁移到core_worker_lib下,这样可以直接调用CoreWorkerProcess,无需跨库添加依赖。
2. 更快的Ray C++代码重新编译方式
pip3 install -e . --verbose会触发全量编译与安装,速度较慢,推荐以下几种增量编译方式:
- 直接用Bazel编译指定目标
针对修改的文件对应的Bazel目标单独编译,比如修改了ray_common库的代码,执行:
若需要编译raylet组件,则执行:bazel build //:ray_common
编译完成后无需重新安装pip包,直接从Bazel输出目录运行Ray即可(如bazel build //:rayletbazel-bin/ray start --head)。 - 利用Bazel增量编译特性
Bazel默认支持增量编译,只会重新编译修改过的文件及其直接依赖,直接指定目标编译的速度远快于全量安装。 - 跳过pip安装步骤
若仅修改C核心代码、未改动Python层逻辑,编译完C目标后直接运行Ray二进制文件即可,无需执行pip安装流程。
内容的提问来源于stack exchange,提问作者HCCH HCCH
相关产品推荐
相关产品推荐

