mirror of
https://github.com/wassname/ray.git
synced 2026-07-11 05:32:40 +08:00
[java] support creating an actor with parameters (#2817)
Previously `Ray.createActor` only support creating an actor without any parameter. This PR adds the support for creating an actor with parameters. Moreover, besides using a constructor, it's now also allowed to create an actor with a factory method. For more usage, prefer refer to `ActorTest.java`.
This commit is contained in:
committed by
Robert Nishihara
parent
b37a283053
commit
9d655721e5
@@ -4,6 +4,8 @@ import com.google.common.base.Preconditions;
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.MethodHandleInfo;
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -67,13 +69,15 @@ public final class MethodId {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static MethodId fromMethod(Method method) {
|
||||
final boolean isstatic = Modifier.isStatic(method.getModifiers());
|
||||
public static MethodId fromExecutable(Executable method) {
|
||||
final boolean isStatic = Modifier.isStatic(method.getModifiers());
|
||||
final String className = method.getDeclaringClass().getName();
|
||||
final String methodName = method.getName();
|
||||
final Type type = Type.getType(method);
|
||||
final String methodName = method instanceof Method
|
||||
? method.getName() : "<init>";
|
||||
final Type type = method instanceof Method
|
||||
? Type.getType((Method) method) : Type.getType((Constructor) method);
|
||||
final String methodDesc = type.getDescriptor();
|
||||
return new MethodId(className, methodName, methodDesc, isstatic);
|
||||
return new MethodId(className, methodName, methodDesc, isStatic);
|
||||
}
|
||||
|
||||
public static MethodId fromSerializedLambda(Serializable serial) {
|
||||
@@ -101,7 +105,6 @@ public final class MethodId {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public Method load() {
|
||||
return load(null);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.ray.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.ray.api.annotation.RayRemote;
|
||||
import org.ray.api.annotation.ResourceItem;
|
||||
|
||||
public class ResourceUtil {
|
||||
@@ -11,17 +12,18 @@ public class ResourceUtil {
|
||||
/**
|
||||
* Convert the array that contains resource items to a map.
|
||||
*
|
||||
* @param resourceArray The resources list to be converted.
|
||||
* @param remoteAnnotation The RayRemote annotation that contains the resource items.
|
||||
* @return The map whose key represents the resource name
|
||||
* and the value represents the resource quantity.
|
||||
*/
|
||||
public static Map<String, Double> getResourcesMapFromArray(ResourceItem[] resourceArray) {
|
||||
public static Map<String, Double> getResourcesMapFromArray(RayRemote remoteAnnotation) {
|
||||
Map<String, Double> resourceMap = new HashMap<>();
|
||||
if (resourceArray != null) {
|
||||
for (ResourceItem item : resourceArray) {
|
||||
if (!item.name().isEmpty()) {
|
||||
resourceMap.put(item.name(), item.value());
|
||||
}
|
||||
if (remoteAnnotation == null) {
|
||||
return resourceMap;
|
||||
}
|
||||
for (ResourceItem item : remoteAnnotation.resources()) {
|
||||
if (!item.name().isEmpty()) {
|
||||
resourceMap.put(item.name(), item.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ public abstract class BaseGenerator {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
|
||||
protected void newLine(int numIndents, String line) {
|
||||
indents(numIndents);
|
||||
newLine(line);
|
||||
}
|
||||
|
||||
protected void indents(int numIndents) {
|
||||
for (int i = 0; i < numIndents; i++) {
|
||||
sb.append(" ");
|
||||
|
||||
@@ -6,7 +6,8 @@ import java.util.List;
|
||||
import org.ray.util.FileUtil;
|
||||
|
||||
/**
|
||||
* A util class that generates `RayCall.java`
|
||||
* A util class that generates `RayCall.java`,
|
||||
* which provides type-safe interfaces for `Ray.call` and `Ray.createActor`.
|
||||
*/
|
||||
public class RayCallGenerator extends BaseGenerator {
|
||||
|
||||
@@ -24,64 +25,76 @@ public class RayCallGenerator extends BaseGenerator {
|
||||
newLine("");
|
||||
|
||||
newLine("/**");
|
||||
newLine(" * This class provides type-safe interfaces for Ray.call.");
|
||||
newLine(" * This class provides type-safe interfaces for `Ray.call` and `Ray.createActor`.");
|
||||
newLine(" **/");
|
||||
newLine("@SuppressWarnings({\"rawtypes\", \"unchecked\"})");
|
||||
newLine("class RayCall {");
|
||||
for (int i = 0; i <= 6; i++) {
|
||||
if (i > 0) {
|
||||
buildCalls(i, true);
|
||||
}
|
||||
buildCalls(i, false);
|
||||
newLine(1, "// =======================================");
|
||||
newLine(1, "// Methods for remote function invocation.");
|
||||
newLine(1, "// =======================================");
|
||||
for (int i = 0; i <= MAX_PARAMETERS; i++) {
|
||||
buildCalls(i, false, false);
|
||||
}
|
||||
newLine(1, "// ===========================================");
|
||||
newLine(1, "// Methods for remote actor method invocation.");
|
||||
newLine(1, "// ===========================================");
|
||||
for (int i = 0; i <= MAX_PARAMETERS - 1; i++) {
|
||||
buildCalls(i, true, false);
|
||||
}
|
||||
newLine(1, "// ===========================");
|
||||
newLine(1, "// Methods for actor creation.");
|
||||
newLine(1, "// ===========================");
|
||||
for (int i = 0; i <= MAX_PARAMETERS; i++) {
|
||||
buildCalls(i, false, true);
|
||||
}
|
||||
newLine("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the `Ray.call` methods for given number of parameters.
|
||||
* @param numParameters the number of parameters, including the actor parameter.
|
||||
* Build the `Ray.call` or `Ray.createActor` methods with the given number of parameters.
|
||||
* @param numParameters the number of parameters
|
||||
* @param forActor build actor api when true, otherwise build task api.
|
||||
* @param forActorCreation build `Ray.createActor` when true, otherwise build `Ray.call`.
|
||||
*/
|
||||
private void buildCalls(int numParameters, boolean forActor) {
|
||||
private void buildCalls(int numParameters, boolean forActor, boolean forActorCreation) {
|
||||
String genericTypes = "";
|
||||
String argList = "";
|
||||
for (int i = 0; i < numParameters; i++) {
|
||||
genericTypes += "T" + i + ", ";
|
||||
if (!forActor || i > 0) {
|
||||
argList += "t" + i + ", ";
|
||||
}
|
||||
argList += "t" + i + ", ";
|
||||
}
|
||||
if (forActor) {
|
||||
genericTypes = "A, " + genericTypes;
|
||||
}
|
||||
genericTypes += forActorCreation ? "A" : "R";
|
||||
if (argList.endsWith(", ")) {
|
||||
argList = argList.substring(0, argList.length() - 2);
|
||||
}
|
||||
|
||||
String funcParam = String.format("RayFunc%d<%sR> f%s",
|
||||
numParameters,
|
||||
genericTypes,
|
||||
numParameters > 0 ? ", " : "");
|
||||
String actorParam = "";
|
||||
String paramPrefix = String.format("RayFunc%d<%s> f",
|
||||
!forActor ? numParameters : numParameters + 1,
|
||||
genericTypes);
|
||||
if (forActor) {
|
||||
actorParam = "RayActor<T0> actor";
|
||||
if (numParameters > 1) {
|
||||
actorParam += ", ";
|
||||
}
|
||||
paramPrefix += ", RayActor<A> actor";
|
||||
}
|
||||
if (numParameters > 0) {
|
||||
paramPrefix += ", ";
|
||||
}
|
||||
|
||||
for (String param : generateParameters(forActor ? 1 : 0, numParameters)) {
|
||||
String returnType = !forActorCreation ? "RayObject<R>" : "RayActor<A>";
|
||||
String funcName = !forActorCreation ? "call" : "createActor";
|
||||
String funcArgs = !forActor ? "f, args" : "f, actor, args";
|
||||
for (String param : generateParameters(0, numParameters)) {
|
||||
// method signature
|
||||
indents(1);
|
||||
newLine(String.format(
|
||||
"public static <%sR> RayObject<R> call(%s%s%s) {",
|
||||
genericTypes, funcParam, actorParam, param
|
||||
newLine(1, String.format(
|
||||
"public static <%s> %s %s(%s) {",
|
||||
genericTypes, returnType, funcName, paramPrefix + param
|
||||
));
|
||||
// method body
|
||||
indents(2);
|
||||
newLine(String.format("Object[] args = new Object[]{%s};", argList));
|
||||
indents(2);
|
||||
newLine(String.format("return Ray.internal().call(f%s, args);", forActor ? ", actor" : ""));
|
||||
indents(1);
|
||||
newLine("}");
|
||||
newLine(2, String.format("Object[] args = new Object[]{%s};", argList));
|
||||
newLine(2, String.format("return Ray.internal().%s(%s);", funcName, funcArgs));
|
||||
newLine(1, "}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user