mirror of
https://github.com/wassname/ray.git
synced 2026-06-27 23:08:32 +08:00
[Java] Support direct actor call in Java worker (#5504)
This commit is contained in:
+1
-1
@@ -65,7 +65,7 @@
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>6.9.9</version>
|
||||
<version>6.9.10</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.ray.api;
|
||||
|
||||
import java.util.List;
|
||||
import org.ray.api.options.ActorCreationOptions;
|
||||
import org.testng.IAlterSuiteListener;
|
||||
import org.testng.xml.XmlGroups;
|
||||
import org.testng.xml.XmlRun;
|
||||
import org.testng.xml.XmlSuite;
|
||||
|
||||
public class RayAlterSuiteListener implements IAlterSuiteListener {
|
||||
|
||||
@Override
|
||||
public void alter(List<XmlSuite> suites) {
|
||||
XmlSuite suite = suites.get(0);
|
||||
if (ActorCreationOptions.DEFAULT_USE_DIRECT_CALL) {
|
||||
XmlGroups groups = new XmlGroups();
|
||||
XmlRun run = new XmlRun();
|
||||
run.onInclude("directCall");
|
||||
groups.setRun(run);
|
||||
suite.setGroups(groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.ray.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Supplier;
|
||||
import org.ray.api.annotation.RayRemote;
|
||||
import org.ray.api.options.ActorCreationOptions;
|
||||
import org.ray.api.runtime.RayRuntime;
|
||||
import org.ray.runtime.AbstractRayRuntime;
|
||||
import org.ray.runtime.RayMultiWorkerNativeRuntime;
|
||||
@@ -12,6 +14,11 @@ import org.testng.SkipException;
|
||||
|
||||
public class TestUtils {
|
||||
|
||||
public static class LargeObject implements Serializable {
|
||||
|
||||
public byte[] data = new byte[1024 * 1024];
|
||||
}
|
||||
|
||||
private static final int WAIT_INTERVAL_MS = 5;
|
||||
|
||||
public static void skipTestUnderSingleProcess() {
|
||||
@@ -20,6 +27,12 @@ public class TestUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void skipTestIfDirectActorCallEnabled() {
|
||||
if (ActorCreationOptions.DEFAULT_USE_DIRECT_CALL) {
|
||||
throw new SkipException("This test doesn't work when direct actor call is enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until the given condition is met.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.ray.api.options.ActorCreationOptions;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = {"directCall"})
|
||||
public class ActorReconstructionTest extends BaseTest {
|
||||
|
||||
@RayRemote()
|
||||
@@ -44,7 +45,6 @@ public class ActorReconstructionTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActorReconstruction() throws InterruptedException, IOException {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
ActorCreationOptions options =
|
||||
@@ -65,7 +65,7 @@ public class ActorReconstructionTest extends BaseTest {
|
||||
|
||||
// Try calling increase on this actor again and check the value is now 4.
|
||||
int value = Ray.call(Counter::increase, actor).get();
|
||||
Assert.assertEquals(value, 4);
|
||||
Assert.assertEquals(value, options.useDirectCall ? 1 : 4);
|
||||
|
||||
Assert.assertTrue(Ray.call(Counter::wasCurrentActorReconstructed, actor).get());
|
||||
|
||||
@@ -125,7 +125,6 @@ public class ActorReconstructionTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActorCheckpointing() throws IOException, InterruptedException {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
ActorCreationOptions options =
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.ray.api.Ray;
|
||||
import org.ray.api.RayActor;
|
||||
import org.ray.api.RayObject;
|
||||
import org.ray.api.TestUtils;
|
||||
import org.ray.api.TestUtils.LargeObject;
|
||||
import org.ray.api.annotation.RayRemote;
|
||||
import org.ray.api.exception.UnreconstructableException;
|
||||
import org.ray.api.id.UniqueId;
|
||||
@@ -16,6 +17,7 @@ import org.ray.runtime.object.NativeRayObject;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = {"directCall"})
|
||||
public class ActorTest extends BaseTest {
|
||||
|
||||
@RayRemote
|
||||
@@ -39,9 +41,13 @@ public class ActorTest extends BaseTest {
|
||||
value += delta;
|
||||
return value;
|
||||
}
|
||||
|
||||
public int accessLargeObject(LargeObject largeObject) {
|
||||
value += largeObject.data.length;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateAndCallActor() {
|
||||
// Test creating an actor from a constructor
|
||||
RayActor<Counter> actor = Ray.createActor(Counter::new, 1);
|
||||
@@ -52,12 +58,18 @@ public class ActorTest extends BaseTest {
|
||||
Assert.assertEquals(Integer.valueOf(3), Ray.call(Counter::increaseAndGet, actor, 1).get());
|
||||
}
|
||||
|
||||
public void testCallActorWithLargeObject() {
|
||||
RayActor<Counter> actor = Ray.createActor(Counter::new, 1);
|
||||
LargeObject largeObject = new LargeObject();
|
||||
Assert.assertEquals(Integer.valueOf(largeObject.data.length + 1),
|
||||
Ray.call(Counter::accessLargeObject, actor, largeObject).get());
|
||||
}
|
||||
|
||||
@RayRemote
|
||||
public static Counter factory(int initValue) {
|
||||
static Counter factory(int initValue) {
|
||||
return new Counter(initValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateActorFromFactory() {
|
||||
// Test creating an actor from a factory method
|
||||
RayActor<Counter> actor = Ray.createActor(ActorTest::factory, 1);
|
||||
@@ -67,24 +79,23 @@ public class ActorTest extends BaseTest {
|
||||
}
|
||||
|
||||
@RayRemote
|
||||
public static int testActorAsFirstParameter(RayActor<Counter> actor, int delta) {
|
||||
static int testActorAsFirstParameter(RayActor<Counter> actor, int delta) {
|
||||
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor, delta);
|
||||
return res.get();
|
||||
}
|
||||
|
||||
@RayRemote
|
||||
public static int testActorAsSecondParameter(int delta, RayActor<Counter> actor) {
|
||||
static int testActorAsSecondParameter(int delta, RayActor<Counter> actor) {
|
||||
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor, delta);
|
||||
return res.get();
|
||||
}
|
||||
|
||||
@RayRemote
|
||||
public static int testActorAsFieldOfParameter(List<RayActor<Counter>> actor, int delta) {
|
||||
static int testActorAsFieldOfParameter(List<RayActor<Counter>> actor, int delta) {
|
||||
RayObject<Integer> res = Ray.call(Counter::increaseAndGet, actor.get(0), delta);
|
||||
return res.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPassActorAsParameter() {
|
||||
RayActor<Counter> actor = Ray.createActor(Counter::new, 0);
|
||||
Assert.assertEquals(Integer.valueOf(1),
|
||||
@@ -96,7 +107,6 @@ public class ActorTest extends BaseTest {
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForkingActorHandle() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
RayActor<Counter> counter = Ray.createActor(Counter::new, 100);
|
||||
@@ -105,9 +115,11 @@ public class ActorTest extends BaseTest {
|
||||
Assert.assertEquals(Integer.valueOf(103), Ray.call(Counter::increaseAndGet, counter2, 2).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnreconstructableActorObject() throws InterruptedException {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
// The UnreconstructableException is created by raylet.
|
||||
// TODO (kfstorm): This should be supported by direct actor call.
|
||||
TestUtils.skipTestIfDirectActorCallEnabled();
|
||||
RayActor<Counter> counter = Ray.createActor(Counter::new, 100);
|
||||
// Call an actor method.
|
||||
RayObject value = Ray.call(Counter::getValue, counter);
|
||||
|
||||
@@ -45,7 +45,7 @@ public abstract class BaseMultiLanguageTest {
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
@BeforeClass(alwaysRun = true)
|
||||
public void setUp() {
|
||||
if (!"1".equals(System.getenv("ENABLE_MULTI_LANGUAGE_TESTS"))) {
|
||||
LOGGER.info("Skip Multi-language tests because environment variable "
|
||||
@@ -100,7 +100,7 @@ public abstract class BaseMultiLanguageTest {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@AfterClass(alwaysRun = true)
|
||||
public void tearDown() {
|
||||
// Disconnect to the cluster.
|
||||
Ray.shutdown();
|
||||
|
||||
@@ -16,7 +16,7 @@ public class BaseTest {
|
||||
|
||||
private List<File> filesToDelete;
|
||||
|
||||
@BeforeMethod
|
||||
@BeforeMethod(alwaysRun = true)
|
||||
public void setUpBase(Method method) {
|
||||
LOGGER.info("===== Running test: "
|
||||
+ method.getDeclaringClass().getName() + "." + method.getName());
|
||||
@@ -34,7 +34,7 @@ public class BaseTest {
|
||||
filesToDelete.forEach(File::deleteOnExit);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
@AfterMethod(alwaysRun = true)
|
||||
public void tearDownBase() {
|
||||
Ray.shutdown();
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.apache.commons.io.FileUtils;
|
||||
import org.ray.api.Ray;
|
||||
import org.ray.api.RayObject;
|
||||
import org.ray.api.RayPyActor;
|
||||
import org.ray.api.TestUtils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -45,8 +46,10 @@ public class CrossLanguageInvocationTest extends BaseMultiLanguageTest {
|
||||
Assert.assertEquals(res.get(), "Response from Python: hello".getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"directCall"})
|
||||
public void testCallingPythonActor() {
|
||||
// Python worker doesn't support direct call yet.
|
||||
TestUtils.skipTestIfDirectActorCallEnabled();
|
||||
RayPyActor actor = Ray.createPyActor(PYTHON_MODULE, "Counter", "1".getBytes());
|
||||
RayObject res = Ray.callPy(actor, "increase", "1".getBytes());
|
||||
Assert.assertEquals(res.get(), "2".getBytes());
|
||||
|
||||
@@ -76,14 +76,14 @@ public class FailureTest extends BaseTest {
|
||||
assertTaskFailedWithRayTaskException(Ray.call(FailureTest::badFunc));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"directCall"})
|
||||
public void testActorCreationFailure() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
RayActor<BadActor> actor = Ray.createActor(BadActor::new, true);
|
||||
assertTaskFailedWithRayTaskException(Ray.call(BadActor::badMethod, actor));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"directCall"})
|
||||
public void testActorTaskFailure() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
RayActor<BadActor> actor = Ray.createActor(BadActor::new, false);
|
||||
@@ -102,9 +102,12 @@ public class FailureTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"directCall"})
|
||||
public void testActorProcessDying() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
// This test case hangs if the worker to worker connection is implemented with grpc.
|
||||
// TODO (kfstorm): Should be fixed.
|
||||
TestUtils.skipTestIfDirectActorCallEnabled();
|
||||
RayActor<BadActor> actor = Ray.createActor(BadActor::new, false);
|
||||
try {
|
||||
Ray.call(BadActor::badMethod2, actor).get();
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
@Test(groups = {"directCall"})
|
||||
public class MultiThreadingTest extends BaseTest {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MultiThreadingTest.class);
|
||||
@@ -30,7 +30,7 @@ public class MultiThreadingTest extends BaseTest {
|
||||
private static final int NUM_THREADS = 20;
|
||||
|
||||
@RayRemote
|
||||
public static Integer echo(int num) {
|
||||
static Integer echo(int num) {
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class MultiThreadingTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
public static String testMultiThreading() {
|
||||
static String testMultiThreading() {
|
||||
Random random = new Random();
|
||||
// Test calling normal functions.
|
||||
runTestCaseInMultipleThreads(() -> {
|
||||
@@ -123,12 +123,10 @@ public class MultiThreadingTest extends BaseTest {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInDriver() {
|
||||
testMultiThreading();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInWorker() {
|
||||
// Single-process mode doesn't have real workers.
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
@@ -136,7 +134,6 @@ public class MultiThreadingTest extends BaseTest {
|
||||
Assert.assertEquals("ok", obj.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCurrentActorId() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
RayActor<ActorIdTester> actorIdTester = Ray.createActor(ActorIdTester::new);
|
||||
|
||||
@@ -2,11 +2,11 @@ package org.ray.api.test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.ray.api.Ray;
|
||||
import org.ray.api.TestUtils;
|
||||
import org.ray.api.TestUtils.LargeObject;
|
||||
import org.ray.api.annotation.RayRemote;
|
||||
import org.ray.api.id.ObjectId;
|
||||
import org.testng.Assert;
|
||||
@@ -67,11 +67,6 @@ public class RayCallTest extends BaseTest {
|
||||
return val;
|
||||
}
|
||||
|
||||
public static class LargeObject implements Serializable {
|
||||
|
||||
private byte[] data = new byte[1024 * 1024];
|
||||
}
|
||||
|
||||
@RayRemote
|
||||
private static LargeObject testLargeObject(LargeObject largeObject) {
|
||||
return largeObject;
|
||||
|
||||
@@ -72,7 +72,7 @@ public class StressTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(groups = {"directCall"})
|
||||
public void testSubmittingManyTasksToOneActor() {
|
||||
TestUtils.skipTestUnderSingleProcess();
|
||||
RayActor<Actor> actor = Ray.createActor(Actor::new);
|
||||
|
||||
Reference in New Issue
Block a user