Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[serve][deploy refactor][2/X] Move lightweight update logic to DeploymentVersion #34430

Merged
merged 35 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c8fe847
move lightweight update logic to DeploymentVersion
zcin Apr 15, 2023
ded09de
wip
zcin Apr 16, 2023
c06156f
java attempt
zcin Apr 16, 2023
6b2e1b3
Merge branch 'master' into version-improvements
zcin Apr 18, 2023
9361ec0
add test for missing deployments in config
zcin Apr 18, 2023
f2c6cb3
unify reconfigure path for user config and other deployment config op…
zcin Apr 19, 2023
8023af7
Merge branch 'master' into version-improvements
zcin Apr 19, 2023
22b1578
don't start task if code version didn't change
zcin Apr 19, 2023
e981957
fix java
zcin Apr 19, 2023
5c1c266
fix
zcin Apr 19, 2023
65bb55c
fix
zcin Apr 19, 2023
91e3e5f
Merge branch 'master' into version-improvements
zcin Apr 19, 2023
81fea37
fix
zcin Apr 19, 2023
b333529
fix
zcin Apr 19, 2023
fb23da4
fix
zcin Apr 19, 2023
7c96c85
Merge branch 'master' into version-improvements
zcin Apr 20, 2023
a63da29
clean
zcin Apr 20, 2023
7dcd27b
fix snapshot test
zcin Apr 20, 2023
0bfb720
encode whether option is lighweight or not into deployment config
zcin Apr 20, 2023
c639912
Merge branch 'master' into version-improvements
zcin Apr 20, 2023
8b9a82f
fix
zcin Apr 20, 2023
6c7cab5
move version into actor replica wrapper
zcin Apr 22, 2023
daa1dca
add more tests
zcin Apr 22, 2023
5c97224
fix + improve
zcin Apr 22, 2023
9371a1f
Merge branch 'master' into version-improvements
zcin Apr 22, 2023
4988852
fix java
zcin Apr 24, 2023
35ac43d
Merge branch 'master' into version-improvements
zcin Apr 24, 2023
4d200c5
add e2e test for user config, max concurrent queries, and graceful sh…
zcin Apr 25, 2023
40e8bfb
fix typo
zcin Apr 25, 2023
0257ada
Merge branch 'master' into version-improvements
zcin Apr 25, 2023
aef4ad1
fix deployment names
zcin Apr 25, 2023
e13b317
address comments
zcin Apr 26, 2023
6b09917
add e2e tests for health check timout and health check period
zcin Apr 26, 2023
127a4ed
fix
zcin Apr 26, 2023
8a1edd6
Merge branch 'master' into version-improvements
zcin Apr 26, 2023
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
20 changes: 20 additions & 0 deletions java/serve/src/main/java/io/ray/serve/config/DeploymentConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,26 @@ public byte[] toProtoBytes() {
return builder.build().toByteArray();
}

public io.ray.serve.generated.DeploymentConfig toProto() {
io.ray.serve.generated.DeploymentConfig.Builder builder =
io.ray.serve.generated.DeploymentConfig.newBuilder()
.setNumReplicas(numReplicas)
.setMaxConcurrentQueries(maxConcurrentQueries)
.setGracefulShutdownWaitLoopS(gracefulShutdownWaitLoopS)
.setGracefulShutdownTimeoutS(gracefulShutdownTimeoutS)
.setHealthCheckPeriodS(healthCheckPeriodS)
.setHealthCheckTimeoutS(healthCheckTimeoutS)
.setIsCrossLanguage(isCrossLanguage)
.setDeploymentLanguage(deploymentLanguage);
if (null != userConfig) {
builder.setUserConfig(ByteString.copyFrom(MessagePackSerializer.encode(userConfig).getKey()));
}
if (null != autoscalingConfig) {
builder.setAutoscalingConfig(autoscalingConfig.toProto());
}
return builder.build();
}

public static DeploymentConfig fromProto(io.ray.serve.generated.DeploymentConfig proto) {

DeploymentConfig deploymentConfig = new DeploymentConfig();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,52 @@
package io.ray.serve.deployment;

import com.google.protobuf.ByteString;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import io.ray.runtime.serializer.MessagePackSerializer;
import io.ray.serve.config.DeploymentConfig;
import io.ray.serve.exception.RayServeException;
import java.io.Serializable;
import java.util.Map;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

public class DeploymentVersion implements Serializable {

private static Gson gson = new Gson();

private static final long serialVersionUID = 3400261981775851058L;

private String codeVersion;

private Object userConfig;

private DeploymentConfig deploymentConfig;

private Map<String, Object> rayActorOptions;

private boolean unversioned;

public DeploymentVersion() {
this(null, null);
this(null, new DeploymentConfig(), null);
}

public DeploymentVersion(String codeVersion) {
this(codeVersion, null);
this(codeVersion, new DeploymentConfig(), null);
}

public DeploymentVersion(String codeVersion, Object userConfig) {
public DeploymentVersion(
String codeVersion, DeploymentConfig deploymentConfig, Map<String, Object> rayActorOptions) {
if (StringUtils.isBlank(codeVersion)) {
this.unversioned = true;
this.codeVersion = RandomStringUtils.randomAlphabetic(6);
} else {
this.codeVersion = codeVersion;
}
this.userConfig = userConfig;
if (deploymentConfig == null) {
deploymentConfig = new DeploymentConfig();
}
this.deploymentConfig = deploymentConfig;
this.rayActorOptions = rayActorOptions;
this.userConfig = deploymentConfig.getUserConfig();
}

public String getCodeVersion() {
Expand All @@ -44,6 +57,14 @@ public Object getUserConfig() {
return userConfig;
}

public DeploymentConfig getDeploymentConfig() {
return deploymentConfig;
}

public Map<String, Object> getRayActorOptions() {
return rayActorOptions;
}

public boolean isUnversioned() {
return unversioned;
}
Expand All @@ -64,12 +85,8 @@ public static DeploymentVersion fromProtoBytes(byte[] bytes) {
}
return new DeploymentVersion(
proto.getCodeVersion(),
proto.getUserConfig() != null && proto.getUserConfig().size() != 0
? new Object[] {
MessagePackSerializer.decode(
proto.getUserConfig().toByteArray(), Object.class) // TODO-xlang
}
: null);
DeploymentConfig.fromProto(proto.getDeploymentConfig()),
gson.fromJson(proto.getRayActorOptions(), Map.class));
}

public byte[] toProtoBytes() {
Expand All @@ -79,9 +96,9 @@ public byte[] toProtoBytes() {
if (StringUtils.isNotBlank(codeVersion)) {
proto.setCodeVersion(codeVersion);
}
if (userConfig != null) {
proto.setUserConfig(
ByteString.copyFrom(MessagePackSerializer.encode(userConfig).getLeft())); // TODO-xlang
proto.setDeploymentConfig(deploymentConfig.toProto());
if (rayActorOptions != null && !rayActorOptions.isEmpty()) {
proto.setRayActorOptions(gson.toJson(rayActorOptions));
}
return proto.build().toByteArray();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package io.ray.serve.replica;

import io.ray.serve.deployment.DeploymentVersion;

public interface RayServeReplica {

Object handleRequest(Object requestMetadata, Object requestArgs);

default Object reconfigure(Object userConfig) {
return new DeploymentVersion(null, userConfig);
default Object reconfigure(byte[] deploymentConfigBytes) {
return null;
}

default boolean checkHealth() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,11 @@ public synchronized boolean prepareForShutdown() {
}

@Override
public DeploymentVersion reconfigure(Object userConfig) {
public DeploymentVersion reconfigure(byte[] deploymentConfigBytes) {
config = DeploymentConfig.fromProtoBytes(deploymentConfigBytes);
Object userConfig = config.getUserConfig();
DeploymentVersion deploymentVersion =
new DeploymentVersion(version.getCodeVersion(), userConfig);
new DeploymentVersion(version.getCodeVersion(), config, version.getRayActorOptions());
version = deploymentVersion;
if (userConfig == null) {
return deploymentVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ public boolean isAllocated() {
*
* @return
*/
public Object isInitialized(Object userConfig) {
Object deploymentVersion = reconfigure(userConfig);
public Object isInitialized(byte[] deploymentConfigBytes) {
Object deploymentVersion = reconfigure(deploymentConfigBytes);
checkHealth();
return deploymentVersion;
}
Expand All @@ -213,13 +213,8 @@ public boolean prepareForShutdown() {
* DeploymentVersion is serialized to protobuf byte[].
*/
@Override
public Object reconfigure(Object userConfig) {
boolean isCrossLanguage = userConfig instanceof byte[];
DeploymentVersion deploymentVersion =
replica.reconfigure(
isCrossLanguage && userConfig != null
? MessagePackSerializer.decode((byte[]) userConfig, Object.class)
: userConfig);
public Object reconfigure(byte[] deploymentConfigBytes) {
DeploymentVersion deploymentVersion = replica.reconfigure(deploymentConfigBytes);
return deploymentVersion.toProtoBytes();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,17 @@ public void test() throws IOException {

// reconfigure
ObjectRef<Object> versionRef =
replicHandle.task(RayServeWrappedReplica::reconfigure, (Object) null).remote();
replicHandle
.task(RayServeWrappedReplica::reconfigure, (new DeploymentConfig()).toProtoBytes())
.remote();
Assert.assertEquals(
DeploymentVersion.fromProtoBytes((byte[]) (versionRef.get())).getCodeVersion(), version);

replicHandle.task(RayServeWrappedReplica::reconfigure, new Object()).remote().get();
deploymentConfig = deploymentConfig.setUserConfig(new Object());
replicHandle
.task(RayServeWrappedReplica::reconfigure, deploymentConfig.toProtoBytes())
.remote()
.get();
resultRef =
replicHandle
.task(
Expand All @@ -84,8 +90,9 @@ public void test() throws IOException {
.remote();
Assert.assertEquals((String) resultRef.get(), "1");

deploymentConfig = deploymentConfig.setUserConfig(ImmutableMap.of("value", "100"));
replicHandle
.task(RayServeWrappedReplica::reconfigure, ImmutableMap.of("value", "100"))
.task(RayServeWrappedReplica::reconfigure, deploymentConfig.toProtoBytes())
.remote()
.get();
resultRef =
Expand Down
22 changes: 22 additions & 0 deletions python/ray/serve/_private/deploy_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import Dict, Tuple, Union, Callable, Type, Optional, Any
import hashlib
import json
import logging
import time

from ray.serve.config import ReplicaConfig, DeploymentConfig
from ray.serve.schema import ServeApplicationSchema
from ray.serve._private.constants import SERVE_LOGGER_NAME
from ray.serve._private.autoscaling_policy import BasicAutoscalingPolicy
from ray.serve._private.common import DeploymentInfo
Expand Down Expand Up @@ -135,3 +138,22 @@ def deploy_args_to_deployment_info(
autoscaling_policy=autoscaling_policy,
is_driver_deployment=is_driver_deployment,
)


def get_app_code_version(app_config: ServeApplicationSchema) -> str:
"""Returns the code version of an application.

Args:
app_config: The application config.

Returns: a hash of the import path and (application level) runtime env representing
the code version of the application.
"""
encoded = json.dumps(
{
"import_path": app_config.import_path,
"runtime_env": app_config.runtime_env,
},
sort_keys=True,
Copy link
Contributor

Choose a reason for hiding this comment

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

nice with sort_keys.

).encode("utf-8")
return hashlib.md5(encoded).hexdigest()
Loading