Files
ray-project--ray/python/ray/includes/common.pxi
T
2026-07-13 13:17:40 +08:00

217 lines
7.3 KiB
Cython

from libcpp cimport bool as c_bool
from libcpp.string cimport string as c_string
from libcpp.vector cimport vector as c_vector
from ray.includes.common cimport (
CObjectLocation,
CGcsClientOptions,
CPythonGcsSubscriber,
kWorkerSetupHookKeyName,
kResourceUnitScaling,
kImplicitResourcePrefix,
kStreamingGeneratorReturn,
kGcsAutoscalerStateNamespace,
kGcsAutoscalerV2EnabledKey,
kGcsAutoscalerClusterConfigKey,
kGcsPidKey,
kNodeTypeNameEnv,
kNodeMarketTypeEnv,
kNodeRegionEnv,
kNodeZoneEnv,
kLabelKeyNodeAcceleratorType,
kLabelKeyNodeMarketType,
kLabelKeyNodeRegion,
kLabelKeyNodeZone,
kLabelKeyNodeID,
kLabelKeyNodeGroup,
kLabelKeyTpuTopology,
kLabelKeyTpuSliceName,
kLabelKeyTpuWorkerId,
kLabelKeyTpuPodType,
kRayInternalNamespacePrefix,
kRuntimeEnvAgentPortName,
kMetricsAgentPortName,
kMetricsExportPortName,
kDashboardAgentListenPortName,
kGcsServerPortName,
)
from ray.exceptions import (
RayActorError,
ActorAlreadyExistsError,
ActorDiedError,
RayError,
RaySystemError,
AuthenticationError,
RayTaskError,
ObjectStoreFullError,
OutOfDiskError,
GetTimeoutError,
TaskCancelledError,
AsyncioActorExit,
PendingCallsLimitExceeded,
RpcError,
ObjectRefStreamEndOfStreamError,
)
cdef class GcsClientOptions:
"""Cython wrapper class of C++ `ray::gcs::GcsClientOptions`."""
cdef:
unique_ptr[CGcsClientOptions] inner
@classmethod
def create(
cls, gcs_address, cluster_id_hex, allow_cluster_id_nil, fetch_cluster_id_if_nil
):
"""
Creates a GcsClientOption with a maybe-Nil cluster_id, and may fetch from GCS.
"""
cdef CClusterID c_cluster_id = CClusterID.Nil()
if cluster_id_hex:
c_cluster_id = CClusterID.FromHex(cluster_id_hex)
self = GcsClientOptions()
try:
ip, port_str = parse_address(gcs_address)
port = int(port_str)
self.inner.reset(
new CGcsClientOptions(
ip, port, c_cluster_id, allow_cluster_id_nil, allow_cluster_id_nil))
except Exception:
raise ValueError(f"Invalid gcs_address: {gcs_address}")
return self
cdef CGcsClientOptions* native(self):
return <CGcsClientOptions*>(self.inner.get())
cdef int check_status(const CRayStatus& status) except -1 nogil:
if status.ok():
return 0
with gil:
message = status.message().decode()
if status.IsObjectStoreFull():
raise ObjectStoreFullError(message)
elif status.IsInvalidArgument():
raise ValueError(message)
elif status.IsAlreadyExists():
raise ActorAlreadyExistsError(message)
elif status.IsOutOfDisk():
raise OutOfDiskError(message)
elif status.IsObjectRefEndOfStream():
raise ObjectRefStreamEndOfStreamError(message)
elif status.IsInterrupted():
raise KeyboardInterrupt()
elif status.IsTimedOut():
raise GetTimeoutError(message)
elif status.IsNotFound():
raise ValueError(message)
elif status.IsObjectNotFound():
raise ValueError(message)
elif status.IsObjectUnknownOwner():
raise ValueError(message)
elif status.IsIOError():
raise IOError(message)
elif status.IsUnauthenticated():
raise AuthenticationError(message)
elif status.IsRpcError():
raise RpcError(message, rpc_code=status.rpc_code())
elif status.IsIntentionalSystemExit():
with gil:
raise_sys_exit_with_custom_error_message(message)
elif status.IsUnexpectedSystemExit():
with gil:
raise_sys_exit_with_custom_error_message(
message, exit_code=1)
elif status.IsChannelError():
raise RayChannelError(message)
elif status.IsChannelTimeoutError():
raise RayChannelTimeoutError(message)
else:
raise RaySystemError(message)
cdef int check_status_timeout_as_rpc_error(const CRayStatus& status) except -1 nogil:
"""
Same as check_status, except that it raises RpcError for timeout. This is for
backward compatibility: on timeout, `ray.get` raises GetTimeoutError, while
GcsClient methods raise RpcError. So in the binding, `get_objects` use check_status
and GcsClient methods use check_status_timeout_as_rpc_error.
"""
if status.IsTimedOut():
raise RpcError(status.message().decode(),
rpc_code=CGrpcStatusCode.DEADLINE_EXCEEDED)
return check_status(status)
WORKER_PROCESS_SETUP_HOOK_KEY_NAME_GCS = str(kWorkerSetupHookKeyName)
RESOURCE_UNIT_SCALING = kResourceUnitScaling
IMPLICIT_RESOURCE_PREFIX = kImplicitResourcePrefix.decode()
STREAMING_GENERATOR_RETURN = kStreamingGeneratorReturn
GCS_AUTOSCALER_STATE_NAMESPACE = kGcsAutoscalerStateNamespace.decode()
GCS_AUTOSCALER_V2_ENABLED_KEY = kGcsAutoscalerV2EnabledKey.decode()
GCS_AUTOSCALER_CLUSTER_CONFIG_KEY = kGcsAutoscalerClusterConfigKey.decode()
GCS_PID_KEY = kGcsPidKey.decode()
# Ray node label related constants from src/ray/common/constants.h
NODE_TYPE_NAME_ENV = kNodeTypeNameEnv.decode()
NODE_MARKET_TYPE_ENV = kNodeMarketTypeEnv.decode()
NODE_REGION_ENV = kNodeRegionEnv.decode()
NODE_ZONE_ENV = kNodeZoneEnv.decode()
RAY_NODE_ACCELERATOR_TYPE_KEY = kLabelKeyNodeAcceleratorType.decode()
RAY_NODE_MARKET_TYPE_KEY = kLabelKeyNodeMarketType.decode()
RAY_NODE_REGION_KEY = kLabelKeyNodeRegion.decode()
RAY_NODE_ZONE_KEY = kLabelKeyNodeZone.decode()
# Keep this in sync with NODE_ID_LABEL_KEY in ray.util.placement_group. That
# module cannot import this exported value because it forms a circular dependency
RAY_NODE_ID_KEY = kLabelKeyNodeID.decode()
RAY_NODE_GROUP_KEY = kLabelKeyNodeGroup.decode()
# TPU specifc Ray node label related constants
RAY_NODE_TPU_TOPOLOGY_KEY = kLabelKeyTpuTopology.decode()
RAY_NODE_TPU_SLICE_NAME_KEY = kLabelKeyTpuSliceName.decode()
RAY_NODE_TPU_WORKER_ID_KEY = kLabelKeyTpuWorkerId.decode()
RAY_NODE_TPU_POD_TYPE_KEY = kLabelKeyTpuPodType.decode()
RAY_INTERNAL_NAMESPACE_PREFIX = kRayInternalNamespacePrefix.decode()
# Prefix for namespaces which are used internally by ray.
# Jobs within these namespaces should be hidden from users
# Port names for local port discovery
RUNTIME_ENV_AGENT_PORT_NAME = kRuntimeEnvAgentPortName.decode()
METRICS_AGENT_PORT_NAME = kMetricsAgentPortName.decode()
METRICS_EXPORT_PORT_NAME = kMetricsExportPortName.decode()
DASHBOARD_AGENT_LISTEN_PORT_NAME = kDashboardAgentListenPortName.decode()
GCS_SERVER_PORT_NAME = kGcsServerPortName.decode()
# and should not be considered user activity.
RAY_INTERNAL_DASHBOARD_NAMESPACE = f"{RAY_INTERNAL_NAMESPACE_PREFIX}dashboard"
# Util functions for async handling
cdef incremented_fut():
fut = concurrent.futures.Future()
cpython.Py_INCREF(fut)
return fut
cdef void assign_and_decrement_fut(result, fut) noexcept with gil:
assert isinstance(fut, concurrent.futures.Future)
assert not fut.done()
try:
ret, exc = result
if exc:
fut.set_exception(exc)
else:
fut.set_result(ret)
finally:
# We INCREFed it in `incremented_fut` to keep it alive during the async wait,
# and we DECREF it here to balance it.
cpython.Py_DECREF(fut)
cdef raise_or_return(tup):
ret, exc = tup
if exc:
raise exc
return ret