Skip to content

Commit

Permalink
[Serve] Expose ApplicationStatus, ApplicationStatusInfo, and StatusOv…
Browse files Browse the repository at this point in the history
…erview classes to API docs

Signed-off-by: akyang-anyscale <[email protected]>
  • Loading branch information
akyang-anyscale committed Oct 23, 2024
1 parent 6e9a397 commit ecdecbf
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@

from ray._private.test_utils import wait_for_condition
from ray.serve._private.common import (
ApplicationStatus,
DeploymentStatus,
DeploymentStatusTrigger,
ProxyStatus,
ReplicaState,
)
from ray.serve._private.constants import SERVE_NAMESPACE
from ray.serve.schema import ServeInstanceDetails
from ray.serve.schema import ApplicationStatus, ServeInstanceDetails
from ray.serve.tests.conftest import * # noqa: F401 F403
from ray.tests.conftest import * # noqa: F401 F403
from ray.util.state import list_actors
Expand Down
4 changes: 2 additions & 2 deletions python/ray/serve/_private/application_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from ray._private.utils import import_attr
from ray.exceptions import RuntimeEnvSetupError
from ray.serve._private.common import (
ApplicationStatus,
ApplicationStatusInfo,
DeploymentID,
DeploymentStatus,
DeploymentStatusInfo,
Expand Down Expand Up @@ -44,6 +42,8 @@
from ray.serve.generated.serve_pb2 import DeploymentLanguage
from ray.serve.schema import (
APIType,
ApplicationStatus,
ApplicationStatusInfo,
DeploymentDetails,
LoggingConfig,
ServeApplicationSchema,
Expand Down
10 changes: 7 additions & 3 deletions python/ray/serve/_private/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@
import ray
from ray.actor import ActorHandle
from ray.serve._private.common import (
ApplicationStatus,
DeploymentHandleSource,
DeploymentID,
DeploymentStatus,
DeploymentStatusInfo,
MultiplexedReplicaInfo,
StatusOverview,
)
from ray.serve._private.constants import (
CLIENT_CHECK_CREATION_POLLING_INTERVAL_S,
Expand All @@ -33,7 +31,13 @@
)
from ray.serve.generated.serve_pb2 import StatusOverview as StatusOverviewProto
from ray.serve.handle import DeploymentHandle, _HandleOptions
from ray.serve.schema import LoggingConfig, ServeApplicationSchema, ServeDeploySchema
from ray.serve.schema import (
ApplicationStatus,
LoggingConfig,
ServeApplicationSchema,
ServeDeploySchema,
StatusOverview,
)

logger = logging.getLogger(SERVE_LOGGER_NAME)

Expand Down
108 changes: 0 additions & 108 deletions python/ray/serve/_private/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,13 @@

from ray.actor import ActorHandle
from ray.serve._private.constants import SERVE_DEFAULT_APP_NAME
from ray.serve.generated.serve_pb2 import ApplicationStatus as ApplicationStatusProto
from ray.serve.generated.serve_pb2 import (
ApplicationStatusInfo as ApplicationStatusInfoProto,
)
from ray.serve.generated.serve_pb2 import DeploymentStatus as DeploymentStatusProto
from ray.serve.generated.serve_pb2 import (
DeploymentStatusInfo as DeploymentStatusInfoProto,
)
from ray.serve.generated.serve_pb2 import (
DeploymentStatusInfoList as DeploymentStatusInfoListProto,
)
from ray.serve.generated.serve_pb2 import (
DeploymentStatusTrigger as DeploymentStatusTriggerProto,
)
from ray.serve.generated.serve_pb2 import StatusOverview as StatusOverviewProto
from ray.serve.grpc_util import RayServegRPCContext

REPLICA_ID_FULL_ID_STR_PREFIX = "SERVE_REPLICA::"
Expand Down Expand Up @@ -115,41 +107,6 @@ class ReplicaState(str, Enum):
PENDING_MIGRATION = "PENDING_MIGRATION"


class ApplicationStatus(str, Enum):
NOT_STARTED = "NOT_STARTED"
DEPLOYING = "DEPLOYING"
DEPLOY_FAILED = "DEPLOY_FAILED"
RUNNING = "RUNNING"
UNHEALTHY = "UNHEALTHY"
DELETING = "DELETING"


@dataclass(eq=True)
class ApplicationStatusInfo:
status: ApplicationStatus
message: str = ""
deployment_timestamp: float = 0

def debug_string(self):
return json.dumps(asdict(self), indent=4)

def to_proto(self):
return ApplicationStatusInfoProto(
status=f"APPLICATION_STATUS_{self.status.name}",
message=self.message,
deployment_timestamp=self.deployment_timestamp,
)

@classmethod
def from_proto(cls, proto: ApplicationStatusInfoProto):
status = ApplicationStatusProto.Name(proto.status)[len("APPLICATION_STATUS_") :]
return cls(
status=ApplicationStatus(status),
message=proto.message,
deployment_timestamp=proto.deployment_timestamp,
)


class DeploymentStatus(str, Enum):
UPDATING = "UPDATING"
HEALTHY = "HEALTHY"
Expand Down Expand Up @@ -508,71 +465,6 @@ def from_proto(cls, proto: DeploymentStatusInfoProto):
)


@dataclass(eq=True)
class StatusOverview:
app_status: ApplicationStatusInfo
name: str = ""
deployment_statuses: List[DeploymentStatusInfo] = field(default_factory=list)

def debug_string(self):
return json.dumps(asdict(self), indent=4)

def get_deployment_status(self, name: str) -> Optional[DeploymentStatusInfo]:
"""Get a deployment's status by name.
Args:
name: Deployment's name.
Return (Optional[DeploymentStatusInfo]): Status with a name matching
the argument, if one exists. Otherwise, returns None.
"""

for deployment_status in self.deployment_statuses:
if name == deployment_status.name:
return deployment_status

return None

def to_proto(self):
# Create a protobuf for the Serve Application info
app_status_proto = self.app_status.to_proto()

# Create protobufs for all individual deployment statuses
deployment_status_protos = map(
lambda status: status.to_proto(), self.deployment_statuses
)

# Create a protobuf list containing all the deployment status protobufs
deployment_status_proto_list = DeploymentStatusInfoListProto()
deployment_status_proto_list.deployment_status_infos.extend(
deployment_status_protos
)

# Return protobuf encapsulating application and deployment protos
return StatusOverviewProto(
name=self.name,
app_status=app_status_proto,
deployment_statuses=deployment_status_proto_list,
)

@classmethod
def from_proto(cls, proto: StatusOverviewProto) -> "StatusOverview":
# Recreate Serve Application info
app_status = ApplicationStatusInfo.from_proto(proto.app_status)

# Recreate deployment statuses
deployment_statuses = []
for info_proto in proto.deployment_statuses.deployment_status_infos:
deployment_statuses.append(DeploymentStatusInfo.from_proto(info_proto))

# Recreate StatusInfo
return cls(
app_status=app_status,
deployment_statuses=deployment_statuses,
name=proto.name,
)


@dataclass(frozen=True)
class RunningReplicaInfo:
replica_id: ReplicaID
Expand Down
2 changes: 1 addition & 1 deletion python/ray/serve/_private/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
MultiplexedReplicaInfo,
NodeId,
RunningReplicaInfo,
StatusOverview,
TargetCapacityDirection,
)
from ray.serve._private.constants import (
Expand Down Expand Up @@ -68,6 +67,7 @@
ServeApplicationSchema,
ServeDeploySchema,
ServeInstanceDetails,
StatusOverview,
gRPCOptionsSchema,
)
from ray.util import metrics
Expand Down
8 changes: 2 additions & 6 deletions python/ray/serve/_private/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,15 @@
from ray import serve
from ray.actor import ActorHandle
from ray.serve._private.client import ServeControllerClient
from ray.serve._private.common import (
ApplicationStatus,
DeploymentID,
DeploymentStatus,
RequestProtocol,
)
from ray.serve._private.common import DeploymentID, DeploymentStatus, RequestProtocol
from ray.serve._private.constants import SERVE_DEFAULT_APP_NAME, SERVE_NAMESPACE
from ray.serve._private.deployment_state import ALL_REPLICA_STATES, ReplicaState
from ray.serve._private.proxy import DRAINING_MESSAGE
from ray.serve._private.usage import ServeUsageTag
from ray.serve._private.utils import TimerBase
from ray.serve.context import _get_global_client
from ray.serve.generated import serve_pb2, serve_pb2_grpc
from ray.serve.schema import ApplicationStatus

TELEMETRY_ROUTE_PREFIX = "/telemetry"
STORAGE_ACTOR_NAME = "storage"
Expand Down
116 changes: 114 additions & 2 deletions python/ray/serve/schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import logging
from collections import Counter
from dataclasses import dataclass, field
from dataclasses import asdict, dataclass, field
from enum import Enum
from typing import Any, Dict, List, Optional, Set, Union
from zlib import crc32
Expand All @@ -17,8 +18,8 @@
)
from ray._private.runtime_env.packaging import parse_uri
from ray.serve._private.common import (
ApplicationStatus,
DeploymentStatus,
DeploymentStatusInfo,
DeploymentStatusTrigger,
ProxyStatus,
ReplicaState,
Expand All @@ -34,6 +35,14 @@
from ray.serve._private.deployment_info import DeploymentInfo
from ray.serve._private.utils import DEFAULT
from ray.serve.config import ProxyLocation
from ray.serve.generated.serve_pb2 import ApplicationStatus as ApplicationStatusProto
from ray.serve.generated.serve_pb2 import (
ApplicationStatusInfo as ApplicationStatusInfoProto,
)
from ray.serve.generated.serve_pb2 import (
DeploymentStatusInfoList as DeploymentStatusInfoListProto,
)
from ray.serve.generated.serve_pb2 import StatusOverview as StatusOverviewProto
from ray.util.annotations import PublicAPI

# Shared amongst multiple schemas.
Expand Down Expand Up @@ -824,6 +833,109 @@ class DeploymentStatusOverview:
message: str


@PublicAPI(stability="stable")
class ApplicationStatus(str, Enum):
NOT_STARTED = "NOT_STARTED"
DEPLOYING = "DEPLOYING"
DEPLOY_FAILED = "DEPLOY_FAILED"
RUNNING = "RUNNING"
UNHEALTHY = "UNHEALTHY"
DELETING = "DELETING"


@PublicAPI(stability="stable")
@dataclass(eq=True)
class ApplicationStatusInfo:
status: ApplicationStatus
message: str = ""
deployment_timestamp: float = 0

def debug_string(self):
return json.dumps(asdict(self), indent=4)

def to_proto(self):
return ApplicationStatusInfoProto(
status=f"APPLICATION_STATUS_{self.status.name}",
message=self.message,
deployment_timestamp=self.deployment_timestamp,
)

@classmethod
def from_proto(cls, proto: ApplicationStatusInfoProto):
status = ApplicationStatusProto.Name(proto.status)[len("APPLICATION_STATUS_") :]
return cls(
status=ApplicationStatus(status),
message=proto.message,
deployment_timestamp=proto.deployment_timestamp,
)


@PublicAPI(stability="stable")
@dataclass(eq=True)
class StatusOverview:
app_status: ApplicationStatusInfo
name: str = ""
deployment_statuses: List[DeploymentStatusInfo] = field(default_factory=list)

def debug_string(self):
return json.dumps(asdict(self), indent=4)

def get_deployment_status(self, name: str) -> Optional[DeploymentStatusInfo]:
"""Get a deployment's status by name.
Args:
name: Deployment's name.
Return (Optional[DeploymentStatusInfo]): Status with a name matching
the argument, if one exists. Otherwise, returns None.
"""

for deployment_status in self.deployment_statuses:
if name == deployment_status.name:
return deployment_status

return None

def to_proto(self):
# Create a protobuf for the Serve Application info
app_status_proto = self.app_status.to_proto()

# Create protobufs for all individual deployment statuses
deployment_status_protos = map(
lambda status: status.to_proto(), self.deployment_statuses
)

# Create a protobuf list containing all the deployment status protobufs
deployment_status_proto_list = DeploymentStatusInfoListProto()
deployment_status_proto_list.deployment_status_infos.extend(
deployment_status_protos
)

# Return protobuf encapsulating application and deployment protos
return StatusOverviewProto(
name=self.name,
app_status=app_status_proto,
deployment_statuses=deployment_status_proto_list,
)

@classmethod
def from_proto(cls, proto: StatusOverviewProto) -> "StatusOverview":
# Recreate Serve Application info
app_status = ApplicationStatusInfo.from_proto(proto.app_status)

# Recreate deployment statuses
deployment_statuses = []
for info_proto in proto.deployment_statuses.deployment_status_infos:
deployment_statuses.append(DeploymentStatusInfo.from_proto(info_proto))

# Recreate StatusInfo
return cls(
app_status=app_status,
deployment_statuses=deployment_statuses,
name=proto.name,
)


@PublicAPI(stability="alpha")
@dataclass
class ApplicationStatusOverview:
Expand Down
3 changes: 1 addition & 2 deletions python/ray/serve/tests/test_autoscaling_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ray import serve
from ray._private.test_utils import SignalActor, wait_for_condition
from ray.serve._private.common import (
ApplicationStatus,
DeploymentID,
DeploymentStatus,
DeploymentStatusTrigger,
Expand All @@ -38,7 +37,7 @@
)
from ray.serve.config import AutoscalingConfig
from ray.serve.handle import DeploymentHandle
from ray.serve.schema import ServeDeploySchema
from ray.serve.schema import ApplicationStatus, ServeDeploySchema
from ray.util.state import list_actors


Expand Down
Loading

0 comments on commit ecdecbf

Please sign in to comment.