Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions verl/tools/search_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,20 @@ def __init__(self, enable_global_rate_limit=True, rate_limit=10):
self.rate_limit_worker = self._init_rate_limit(rate_limit) if enable_global_rate_limit else None

def _init_rate_limit(self, rate_limit):
"""Initialize singleton rate limiter."""
return TokenBucketWorker.options(name="rate-limiter", get_if_exists=True).remote(rate_limit)
"""Initialize singleton rate limiter as a detached actor."""
namespace = ray.get_runtime_context().namespace
try:
actor = ray.get_actor("rate-limiter", namespace=namespace)
logger.info("Reusing existing detached rate-limiter actor.")
return actor
except ValueError:
logger.info("Creating new detached rate-limiter actor.")
return TokenBucketWorker.options(
name="rate-limiter",
lifetime="detached",
namespace=namespace,
get_if_exists=True
).remote(rate_limit)
Comment on lines +82 to +94
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The use of the generic name "rate-limiter" for a detached actor is risky because it can collide with other tools (such as SandboxFusionTool in this repository) that might also use the same name within the same Ray namespace. If another tool creates a non-detached actor with this name first, this code will reuse it, and the ActorDiedError will still occur when that other tool is destroyed. Additionally, the try...except block and manual namespace handling are redundant; Ray's get_if_exists=True option in options() already handles the 'get or create' logic safely and respects the current namespace by default.

        # Use a specific name to avoid collisions with other tools in the same namespace.
        return TokenBucketWorker.options(
            name="search-tool-rate-limiter",
            lifetime="detached",
            get_if_exists=True
        ).remote(rate_limit)


def ping(self):
"""Health check method."""
Expand Down