[JavaWorker] Enable java worker support (#2094)

* Enable java worker support
--------------------------
This commit includes a tailored version of the Java worker implementation from Ant Financial.
The changes for build system, python module, src module and arrow are in other commits, this commit consists of the following modules:
 - java/api: Ray API definition
 - java/common: utilities
 - java/hook: binary rewrite of the Java byte-code for remote execution
 - java/runtime-common: common implementation of the runtime in worker
 - java/runtime-dev: a pure-java mock implementation of the runtime for fast development
 - java/runtime-native: a native implementation of the runtime
 - java/test: various tests

Contributors for this work:
 Guyang Song, Peng Cao, Senlin Zhu,Xiaoying Chu, Yiming Yu, Yujie Liu, Zhenyu Guo

* change the format of java help document from markdown to RST

* update the vesion of Arrow for java worker

* adapt the new version of plasma java client from arrow which use byte[] instead of custom type

* add java worker test to ci

* add the example module for better usage guide
This commit is contained in:
Yujie Liu
2018-05-27 05:38:50 +08:00
committed by Philipp Moritz
parent 74cca3b284
commit a8d3c057c1
193 changed files with 22675 additions and 5 deletions
+395
View File
@@ -0,0 +1,395 @@
This directory contains the java worker, with the following components.
- java/api: Ray API definition
- java/common: utilities
- java/hook: binary rewrite of the Java byte-code for remote execution
- java/runtime-common: common implementation of the runtime in worker
- java/runtime-dev: a pure-java mock implementation of the runtime for
fast development
- java/runtime-native: a native implementation of the runtime
- java/test: various tests
- src/local\_scheduler/lib/java: JNI client library for local scheduler
- src/plasma/lib/java: JNI client library for plasma storage
Build and test
==============
::
# build native components
../build.sh -l java
# build java worker
mvn clean install -Dmaven.test.skip
# test
export RAY_CONFIG=ray.config.ini
mvn test
Quick start
===========
Starting Ray
------------
.. code:: java
Ray.init();
Read and write remote objects
-----------------------------
Each remote object is considered a ``RayObject<T>`` where ``T`` is the
type for this object. You can use ``Ray.put`` and ``RayObject<T>.get``
to write and read the objects.
.. code:: java
Integer x = 1;
RayObject<Integer> obj = Ray.put(x);
Integer x1 = obj.get();
assert (x.equals(x1));
Remote functions
----------------
Here is an ordinary java code piece for composing
``hello world example``.
.. code:: java
public class ExampleClass {
public static void main(String[] args) {
String str1 = add("hello", "world");
String str = add(str1, "example");
System.out.println(str);
}
public static String add(String a, String b) {
return a + " " + b;
}
}
We use ``@RayRemote`` to indicate that a function is remote, and use
``Ray.call`` to invoke it. The result from the latter is a
``RayObject<R>`` where ``R`` is the return type of the target function.
The following shows the changed example with ``add`` annotated, and
correspondent calls executed on remote machines.
.. code:: java
public class ExampleClass {
public static void main(String[] args) {
Ray.init();
RayObject<String> objStr1 = Ray.call(ExampleClass::add, "hello", "world");
RayObject<String> objStr2 = Ray.call(ExampleClass::add, objStr1, "example");
String str = objStr2.get();
System.out.println(str);
}
@RayRemote
public static String add(String a, String b) {
return a + " " + b;
}
}
Ray Java API
============
Basic API
---------
``Ray.init()``
~~~~~~~~~~~~~~
Ray.init should be invoked before any other Ray functions to initialize
the runtime.
``@RayRemote``
~~~~~~~~~~~~~~
The annotation of ``@RayRemote`` can be used to decorate static java
method or class. The former indicates that a target function is a remote
function, which is valid with the follow requirements. \* it must be a
public static method \* parameters and return value must not be the
primitive type of java such as int, double, but could use the wrapper
class like Integer,Double \* the return value of the method must always
be the same with the same input
When the annotation is used for classes, the classes are considered
actors(a mechanism to share state among many remote functions). The
member functions can be invoked using ``Ray.call``. The requirements for
an actor class are as follows. \* it must have an constructor without
any parameter \* if it is an inner class, it must be public static \* it
must not have a member field or method decorated using
``public static``, as the semantic is undefined with multiple instances
of this same class on different machines \* an actor method must be
decorated using ``public`` but no ``static``, and the other requirements
are the same as above.
``Ray.call``
~~~~~~~~~~~~
.. code:: java
RayObject<R> call(Func func, ...);
``func`` is the target method, continued with appropriate parameters.
There are some requirements here:
- the return type of ``func`` must be ``R``
- currently at most 6 parameters of ``func`` are allowed
- each parameter must be of type ``T`` of the correspondent ``func``'s
parameter, or be the lifted ``RayObject<T>`` to indicate a result
from another ray call
The returned object is labled as ``RayObject<R>`` and its value will be
put into memory of the machine where the function call is executed.
``Ray.put``
~~~~~~~~~~~
You can also invoke ``Ray.put`` to explicitly place an object into local
memory.
.. code:: java
public static <T> RayObject<T> put(T object);
public static <T, TM> RayObject<T> put(T obj, TM metadata);
``RayObject<T>.get/getMeta``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: java
public class RayObject<T> {
public T get() throws TaskExecutionException;
public <M> M getMeta() throws TaskExecutionException;
}
This method blocks current thread until requested data gets ready and is
fetched (if needed) from remote memory to local.
``Ray.wait``
~~~~~~~~~~~~
Calling ``Ray.wait`` will block current thread and wait for specified
ray calls. It returns when at least ``numReturns`` calls are completed,
or the ``timeout`` expires. See multi-value support for ``RayList``.
.. code:: java
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns, int timeout);
public static WaitResult<T> wait(RayList<T> waitfor, int numReturns);
public static WaitResult<T> wait(RayList<T> waitfor);
Multi-value API
---------------
Multi-value Types
~~~~~~~~~~~~~~~~~
Java worker supports multiple ``RayObject``\ s in a single data
structure as a return value or a ray call parameter, through the
following container types.
``MultipleReturnsX<R0, R1, ...>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are multiple heterogeneous values, with their types as ``R0``,
``R1``,... respectively. Note currently this container type is only
supported as the return type of a ray call, therefore you can not use it
as the type of an input parameter.
``RayList<T>``
''''''''''''''
A list of ``RayObject<T>``, inherited from ``List<T>`` in Java. It can
be used as the type for both return value and parameters.
``RayMap<L, T>``
''''''''''''''''
A map of ``RayObject<T>`` with each indexed using a label with type
``L``, inherited from ``Map<L, T>``. It can be used as the type for both
return value and parameters.
Enable multiple heterogeneous return values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java worker support at most four multiple heterogeneous return values,
and in order to let the runtime know the number of return values we
supply the method of ``Ray.call_X`` as follows.
.. code:: java
RayObjects2<R0, R1> call_2(Func func, ...);
RayObjects3<R0, R1, R2> call_3(Func func, ...);
RayObjects4<R0, R1, R2, R3> call_4(Func func, ...);
Note ``func`` must match the following requirements.
- It must hava the return value of ``MultipleReturnsX``, and must be
invoked using correspondent ``Ray.call_X``
Here is an example.
.. code:: java
public class MultiRExample {
public static void main(String[] args) {
Ray.init();
RayObjects2<Integer, String> refs = Ray.call_2(MultiRExample::sayMultiRet);
Integer obj1 = refs.r0().get();
String obj2 = refs.r1().get();
Assert.assertTrue(obj1.equals(123));
Assert.assertTrue(obj2.equals("123"));
}
@RayRemote
public static MultipleReturns2<Integer, String> sayMultiRet() {
return new MultipleReturns2<Integer, String>(123, "123");
}
}
Return with ``RayList``
~~~~~~~~~~~~~~~~~~~~~~~
We use ``Ray.call_n`` to do so, which is similar to ``Ray.call`` except
an additional parameter ``returnCount`` which tells the number of return
``RayObject<R>`` in ``RayList<R>``. This is because Ray core engines
needs to know it before the method is really called.
.. code:: java
RayList<R> call_n(Func func, Integer returnCount, ...);
Here is an example.
.. code:: java
public class ListRExample {
public static void main(String[] args) {
Ray.init();
RayList<Integer> ns = Ray.call_n(ListRExample::sayList, 10, 10);
for (int i = 0; i < 10; i++) {
RayObject<Integer> obj = ns.Get(i);
Assert.assertTrue(i == obj.get());
}
}
@RayRemote
public static List<Integer> sayList(Integer count) {
ArrayList<Integer> rets = new ArrayList<>();
for (int i = 0; i < count; i++)
rets.add(i);
return rets;
}
}
Return with ``RayMap``
~~~~~~~~~~~~~~~~~~~~~~
This is similar to ``RayList`` case, except that now each return
``RayObject<R>`` in ``RayMap<L,R>`` has a given label when
``Ray.call_n`` is made.
.. code:: java
RayMap<L, R> call_n(Func func, Collection<L> returnLabels, ...);
Here is an example.
.. code:: java
public class MapRExample {
public static void main(String[] args) {
Ray.init();
RayMap<Integer, String> ns = Ray.call_n(MapRExample::sayMap,
Arrays.asList(1, 2, 4, 3), "n_futures_");
for (Entry<Integer, RayObject<String>> ne : ns.EntrySet()) {
Integer key = ne.getKey();
RayObject<String> obj = ne.getValue();
Assert.assertTrue(obj.get().equals("n_futures_" + key));
}
}
@RayRemote(externalIO = true)
public static Map<Integer, String> sayMap(Collection<Integer> ids,
String prefix) {
Map<Integer, String> ret = new HashMap<>();
for (int id : ids) {
ret.put(id, prefix + id);
}
return ret;
}
}
Enable ``RayList`` and ``RayMap`` as parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: java
public class ListTExample {
public static void main(String[] args) {
Ray.init();
RayList<Integer> ints = new RayList<>();
ints.add(Ray.put(new Integer(1)));
ints.add(Ray.put(new Integer(1)));
ints.add(Ray.put(new Integer(1)));
RayObject<Integer> obj = Ray.call(ListTExample::sayReadRayList
(List<Integer>)ints);
Assert.assertTrue(obj.get().equals(3));
}
@RayRemote
public static int sayReadRayList(List<Integer> ints) {
int sum = 0;
for (Integer i : ints) {
sum += i;
}
return sum;
}
}
Actor Support
-------------
Create Actors
~~~~~~~~~~~~~
A regular class annotated with ``@RayRemote`` is an actor class.
.. code:: java
@RayRemote
public class Adder {
public Adder() {
sum = 0;
}
public Integer add(Integer n) {
return sum += n;
}
private Integer sum;
}
Whenever you call ``Ray.create()`` method, an actor will be created, and
you get a local ``RayActor`` of that actor as the return value.
.. code:: java
RayActor<Adder> adder = Ray.create(Adder.class);
Call Actor Methods
~~~~~~~~~~~~~~~~~~
The same ``Ray.call`` or its extended versions (e.g., ``Ray.call_n``) is
applied, except that the first argument becomes ``RayActor``.
.. code:: java
RayObject<R> Ray.call(Func func, RayActor<Adder> actor, ...);
RayObject<Integer> result1 = Ray.call(Adder::add, adder, 1);
RayObject<Integer> result2 = Ray.call(Adder::add, adder, 10);
result2.get(); // 11
+54
View File
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.ray.parent</groupId>
<artifactId>ray-superpom</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.ray</groupId>
<artifactId>ray-api</artifactId>
<name>java api for ray</name>
<description>java api for ray</description>
<url></url>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-common</artifactId>
<version>1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>2.47</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-plasma</artifactId>
</dependency>
</dependencies>
</project>
+119
View File
@@ -0,0 +1,119 @@
package org.ray.api;
import java.util.List;
import org.ray.api.internal.RayConnector;
import org.ray.util.exception.TaskExecutionException;
import org.ray.util.logger.DynamicLog;
import org.ray.util.logger.RayLog;
/**
* Ray API
*/
public final class Ray extends Rpc {
/**
* initialize the current worker or the single-box cluster
*/
public static void init() {
if (impl == null) {
impl = RayConnector.run();
}
}
/**
* Put obj into object store
*/
public static <T> RayObject<T> put(T obj) {
return impl.put(obj);
}
public static <T, TM> RayObject<T> put(T obj, TM metadata) {
return impl.put(obj, metadata);
}
/**
* Get obj(s) from object store
*/
static <T> T get(UniqueID objectId) throws TaskExecutionException {
return impl.get(objectId);
}
static <T> T getMeta(UniqueID objectId) throws TaskExecutionException {
return impl.getMeta(objectId);
}
static <T> List<T> get(List<UniqueID> objectIds) throws TaskExecutionException {
return impl.get(objectIds);
}
static <T> List<T> getMeta(List<UniqueID> objectIds) throws TaskExecutionException {
return impl.getMeta(objectIds);
}
/**
* wait until timeout or enough RayObject are ready
*
* @param waitfor wait for who
* @param numReturns how many of ready is enough
* @param timeoutMilliseconds in millisecond
*/
public static <T> WaitResult<T> wait(RayList<T> waitfor, int numReturns,
int timeoutMilliseconds) {
return impl.wait(waitfor, numReturns, timeoutMilliseconds);
}
public static <T> WaitResult<T> wait(RayList<T> waitfor, int numReturns) {
return impl.wait(waitfor, numReturns, Integer.MAX_VALUE);
}
public static <T> WaitResult<T> wait(RayList<T> waitfor) {
return impl.wait(waitfor, waitfor.size(), Integer.MAX_VALUE);
}
public static <T> WaitResult<T> wait(RayObject<T> waitfor, int timeoutMilliseconds) {
RayList<T> waits = new RayList<>();
waits.add(waitfor);
return impl.wait(waits, 1, timeoutMilliseconds);
}
/**
* create actor object
*/
public static <T> RayActor<T> create(Class<T> cls) {
try {
if (cls.getConstructor() == null) {
System.err.println("class " + cls.getName()
+ " does not (actors must) have a constructor with no arguments");
RayLog.core.error("class " + cls.getName()
+ " does not (actors must) have a constructor with no arguments");
}
} catch (Exception e) {
System.exit(1);
return null;
}
return impl.create(cls);
}
/**
* get underlying runtime
*/
static RayApi internal() {
return impl;
}
/**
* whether to use remote lambda
*/
public static boolean isRemoteLambda() {
return impl.isRemoteLambda();
}
private static RayApi impl = null;
/**
* for ray's app's log
*/
public static DynamicLog getRappLogger() {
return RayLog.rapp;
}
}
@@ -0,0 +1,87 @@
package org.ray.api;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.ray.util.Sha1Digestor;
/**
* Ray actor abstraction
*/
public class RayActor<T> extends RayObject<T> implements Externalizable {
private static final long serialVersionUID = 1877485807405645036L;
private int taskCounter = 0;
private UniqueID taskCursor = null;
private UniqueID actorHandleId = UniqueID.nil;
private int forksNum = 0;
public RayActor() {
}
public RayActor(UniqueID id) {
super(id);
this.taskCounter = 1;
}
public RayActor(UniqueID id, UniqueID actorHandleId) {
super(id);
this.actorHandleId = actorHandleId;
this.taskCounter = 0;
}
public int increaseTaskCounter() {
return taskCounter++;
}
/**
* Getter method for property <tt>taskCursor</tt>
*
* @return property value of taskCursor
*/
public UniqueID getTaskCursor() {
return taskCursor;
}
/**
* Setter method for property <tt>taskCursor</tt>
*
* @param taskCursor value to be assigned to property taskCursor
*/
public void setTaskCursor(UniqueID taskCursor) {
this.taskCursor = taskCursor;
}
public UniqueID computeNextActorHandleId() {
byte[] bytes = Sha1Digestor.digest(actorHandleId.id, ++forksNum);
return new UniqueID(bytes);
}
public UniqueID getActorHandleId() {
return actorHandleId;
}
public void setActorHandleId(UniqueID actorHandleId) {
this.actorHandleId = actorHandleId;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.id);
out.writeObject(this.computeNextActorHandleId());
out.writeObject(this.taskCursor);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.id = (UniqueID) in.readObject();
this.actorHandleId = (UniqueID) in.readObject();
this.taskCursor = (UniqueID) in.readObject();
}
}
@@ -0,0 +1,101 @@
package org.ray.api;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.ray.api.internal.Callable;
import org.ray.util.exception.TaskExecutionException;
/**
* Ray runtime abstraction
*/
public interface RayApi {
/**
* Put obj into object store
*
* @return RayObject
*/
<T> RayObject<T> put(T obj);
<T, TM> RayObject<T> put(T obj, TM metadata);
/**
* Get real obj from object store
*/
<T> T get(UniqueID objectId) throws TaskExecutionException;
<T> T getMeta(UniqueID objectId) throws TaskExecutionException;
/**
* Get real objects from object store
*
* @param objectIds list of ids of objects to get
*/
<T> List<T> get(List<UniqueID> objectIds) throws TaskExecutionException;
<T> List<T> getMeta(List<UniqueID> objectIds) throws TaskExecutionException;
/**
* wait until timeout or enough RayObjects are ready
*
* @param waitfor wait for who
* @param numReturns how many of ready is enough
* @param timeout in millisecond
*/
<T> WaitResult<T> wait(RayList<T> waitfor, int numReturns, int timeout);
/**
* create remote actor
*/
<T> RayActor<T> create(Class<T> cls);
/**
* submit a new task by invoking a remote function
*
* @param taskId nil
* @param funcRun the target running function with @RayRemote
* @param returnCount the number of to-be-returned objects from funcRun
* @param args arguments to this funcRun, can be its original form or RayObject<original-type>
* @return a set of ray objects with their return ids
*/
RayObjects call(UniqueID taskId, Callable funcRun, int returnCount, Object... args);
RayObjects call(UniqueID taskId, Class<?> funcCls, Serializable lambda, int returnCount,
Object... args);
/**
* In some cases, we would like the return value of a remote function to be splitted into multiple
* parts so that they are consumed by multiple further functions separately (potentially on
* different machines). We therefore introduce this API so that developers can annotate the
* outputs with a set of labels (usually with Integer or String)
*
* @param taskId nil
* @param funcRun the target running function with @RayRemote
* @param returnIds a set of labels to be used by the returned objects
* @param args arguments to this funcRun, can be its original form or RayObject<original-type>
* @return a set of ray objects with their labels and return ids
*/
<R, RID> RayMap<RID, R> callWithReturnLabels(UniqueID taskId, Callable funcRun,
Collection<RID> returnIds, Object... args);
<R, RID> RayMap<RID, R> callWithReturnLabels(UniqueID taskId, Class<?> funcCls,
Serializable lambda, Collection<RID> returnids, Object... args);
/**
* a special case for the above RID-based labeling as <0...returnCount - 1>
*
* @param taskId nil
* @param funcRun the target running function with @RayRemote
* @param returnCount the number of to-be-returned objects from funcRun
* @param args arguments to this funcRun, can be its original form or RayObject<original-type>
* @return an array of returned objects with their Unique ids
*/
<R> RayList<R> callWithReturnIndices(UniqueID taskId, Callable funcRun, Integer returnCount,
Object... args);
<R> RayList<R> callWithReturnIndices(UniqueID taskId, Class<?> funcCls, Serializable lambda,
Integer returnCount, Object... args);
boolean isRemoteLambda();
}
@@ -0,0 +1,5 @@
package org.ray.api;
public @interface RayDisabled {
}
@@ -0,0 +1,213 @@
package org.ray.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* A RayList&lt;E&gt; holds a list of RayObject&lt;E&gt;,
* and can serves as parameters and/or return values of Ray calls.
*/
public class RayList<E> extends ArrayList<E> {
private static final long serialVersionUID = 2129403593610953658L;
private final ArrayList<RayObject<E>> ids = new ArrayList<>();
public List<RayObject<E>> Objects() {
return ids;
}
@Override
public int size() {
// throw new UnsupportedOperationException();
return ids.size();
}
@Override
public boolean isEmpty() {
// throw new UnsupportedOperationException();
return ids.isEmpty();
}
@Override
public boolean contains(Object o) {
// throw new UnsupportedOperationException();
return ids.contains(o);
}
@RayDisabled
@Deprecated
@Override
public Iterator<E> iterator() {
throw new UnsupportedOperationException();
}
public Iterator<RayObject<E>> Iterator() {
return ids.iterator();
}
@Override
public Object[] toArray() {
//throw new UnsupportedOperationException();
return ids.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
//throw new UnsupportedOperationException();
return ids.toArray(a);
}
@RayDisabled
@Deprecated
@Override
public boolean add(E e) {
throw new UnsupportedOperationException();
}
public boolean add(RayObject<E> e) {
return ids.add(e);
}
@Override
public boolean remove(Object o) {
//throw new UnsupportedOperationException();
return ids.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
//throw new UnsupportedOperationException();
return ids.containsAll(c);
}
@RayDisabled
@Deprecated
@Override
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@RayDisabled
@Deprecated
@Override
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
//throw new UnsupportedOperationException();
return ids.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
//throw new UnsupportedOperationException();
return ids.retainAll(c);
}
@Override
public void clear() {
//throw new UnsupportedOperationException();
ids.clear();
}
public List<E> get() {
List<UniqueID> objectIds = new ArrayList<>();
for (RayObject<E> id : ids) {
objectIds.add(id.getId());
}
return Ray.get(objectIds);
}
public <T> List<T> getMeta() {
List<UniqueID> objectIds = new ArrayList<>();
for (RayObject<E> id : ids) {
objectIds.add(id.getId());
}
return Ray.getMeta(objectIds);
}
@Override
public E get(int index) {
return ids.get(index).get();
}
public <TM> TM getMeta(int index) {
return ids.get(index).getMeta();
}
public RayObject<E> Get(int index) {
return ids.get(index);
}
@RayDisabled
@Deprecated
@Override
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public RayObject<E> set(int index, RayObject<E> element) {
return ids.set(index, element);
}
@RayDisabled
@Deprecated
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, RayObject<E> element) {
ids.add(index, element);
}
@RayDisabled
@Deprecated
@Override
public E remove(int index) {
throw new UnsupportedOperationException();
}
public RayObject<E> Remove(int index) {
return ids.remove(index);
}
@Override
public int indexOf(Object o) {
//throw new UnsupportedOperationException();
return ids.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
//throw new UnsupportedOperationException();
return ids.lastIndexOf(o);
}
@RayDisabled
@Deprecated
@Override
public ListIterator<E> listIterator() {
throw new UnsupportedOperationException();
}
@RayDisabled
@Deprecated
@Override
public ListIterator<E> listIterator(int index) {
throw new UnsupportedOperationException();
}
@RayDisabled
@Deprecated
@Override
public List<E> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
}
@@ -0,0 +1,138 @@
package org.ray.api;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* A RayMap&lt;K&gt; maintains a map from K to RayObject&lt;V&gt;,
* and serves as parameters and/or return values of Ray calls.
*/
public class RayMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = 7296072498584721265L;
private final HashMap<K, RayObject<V>> ids = new HashMap<>();
public HashMap<K, RayObject<V>> Objects() {
return ids;
}
@Override
public int size() {
// throw new UnsupportedOperationException();
return ids.size();
}
@Override
public boolean isEmpty() {
//throw new UnsupportedOperationException();
return ids.isEmpty();
}
@Override
public boolean containsKey(Object key) {
//throw new UnsupportedOperationException();
return ids.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
//throw new UnsupportedOperationException();
return ids.containsValue(value);
}
// TODO: try to use multiple get
public Map<K, V> get() {
Map<K, V> objs = new HashMap<>();
for (Map.Entry<K, RayObject<V>> id : ids.entrySet()) {
objs.put(id.getKey(), id.getValue().get());
}
return objs;
}
public <TM> Map<K, TM> getMeta() {
Map<K, TM> metas = new HashMap<>();
for (Map.Entry<K, RayObject<V>> id : ids.entrySet()) {
TM meta = id.getValue().getMeta();
metas.put(id.getKey(), meta);
}
return metas;
}
@Override
public V get(Object key) {
return ids.get(key).get();
}
public <TM> TM getMeta(K key) {
return ids.get(key).getMeta();
}
public RayObject<V> Get(K key) {
return ids.get(key);
}
@RayDisabled
@Deprecated
@Override
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public RayObject<V> put(K key, RayObject<V> value) {
return ids.put(key, value);
}
@RayDisabled
@Deprecated
@Override
public V remove(Object key) {
throw new UnsupportedOperationException();
}
public RayObject<V> Remove(K key) {
return ids.remove(key);
}
@RayDisabled
@Deprecated
@Override
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
//throw new UnsupportedOperationException();
ids.clear();
}
@Override
public Set<K> keySet() {
return ids.keySet();
}
@RayDisabled
@Deprecated
@Override
public Collection<V> values() {
throw new UnsupportedOperationException();
}
public Collection<RayObject<V>> Values() {
return ids.values();
}
@RayDisabled
@Deprecated
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
public Set<java.util.Map.Entry<K, RayObject<V>>> EntrySet() {
return ids.entrySet();
}
}
@@ -0,0 +1,35 @@
package org.ray.api;
import java.io.Serializable;
import org.ray.util.exception.TaskExecutionException;
/**
* RayObject&lt;T&gt; is a handle for T object, which may or may not be available now.
* That said, RayObject can be viewed as a Future object with metadata.
*/
public class RayObject<T> implements Serializable {
private static final long serialVersionUID = 3250003902037418062L;
UniqueID id;
public RayObject() {
}
public RayObject(UniqueID id) {
this.id = id;
}
public T get() throws TaskExecutionException {
return Ray.get(id);
}
public <TM> TM getMeta() throws TaskExecutionException {
return Ray.getMeta(id);
}
public UniqueID getId() {
return id;
}
}
@@ -0,0 +1,32 @@
package org.ray.api;
import org.apache.commons.lang3.ArrayUtils;
/**
* Real object or ray future proxy for multiple returns
*/
public class RayObjects {
protected RayObject[] objs;
public RayObjects(UniqueID[] ids) {
this.objs = new RayObject[ids.length];
for (int k = 0; k < ids.length; k++) {
this.objs[k] = new RayObject<>(ids[k]);
}
}
public RayObjects(RayObject[] objs) {
this.objs = objs;
}
public RayObject pop() {
RayObject lastObj = objs[objs.length - 1];
objs = ArrayUtils.subarray(objs, 0, objs.length - 1);
return lastObj;
}
public RayObject[] getObjs() {
return objs;
}
}
@@ -0,0 +1,20 @@
package org.ray.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* a ray remote function or class (as an actor)
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RayRemote {
/**
* whether to use external I/O pool to execute the function
*/
boolean externalIO() default false;
}
@@ -0,0 +1,10 @@
package org.ray.api;
/**
* a RPC service that represent the data processing services implemented in Ray
*
* it is programmed in other services but will be shipped and executed on ray machines at runtime
*/
public @interface RayService {
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
package org.ray.api;
import java.io.Serializable;
/**
* Represents a status of type T of a task.
*/
public class TaskStatus<T> implements Serializable {
private static final long serialVersionUID = -3382082416577683751L;
public T status;
}
@@ -0,0 +1,119 @@
package org.ray.api;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.Random;
/**
* Unique ID for task, worker, function...
*/
public class UniqueID implements Serializable {
private static final long serialVersionUID = 8588849129675565761L;
public static final int LENGTH = 20;
byte[] id;
public UniqueID(byte[] id) {
this.id = id;
}
public UniqueID(ByteBuffer bb) {
assert (bb.remaining() == LENGTH);
id = new byte[bb.remaining()];
bb.get(id);
}
public UniqueID(String optionValue) {
assert (optionValue.length() == 2 * LENGTH);
int j = 0;
id = new byte[LENGTH];
for (int i = 0; i < LENGTH; i++) {
char c1 = optionValue.charAt(j++);
char c2 = optionValue.charAt(j++);
int first = c1 <= '9' ? (c1 - '0') : (c1 - 'a' + 0xa);
int second = c2 <= '9' ? (c2 - '0') : (c2 - 'a' + 0xa);
id[i] = (byte) (first * 16 + second);
}
}
@Override
public String toString() {
String s = "";
String hex = "0123456789abcdef";
for (int i = 0; i < LENGTH; i++) {
int val = id[i] & 0xff;
s += hex.charAt(val >> 4);
s += hex.charAt(val & 0xf);
}
return s;
}
public byte[] getBytes() {
return id;
}
public ByteBuffer ToByteBuffer() {
return ByteBuffer.wrap(id);
}
public UniqueID copy() {
byte[] nid = Arrays.copyOf(id, id.length);
return new UniqueID(nid);
}
@Override
public int hashCode() {
int hash = 0xdeadbeef;
IntBuffer bb = ByteBuffer.wrap(id).asIntBuffer();
while (bb.hasRemaining()) {
hash ^= bb.get();
}
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof UniqueID)) {
return false;
}
UniqueID r = (UniqueID) obj;
return Arrays.equals(id, r.id);
}
public boolean isNil() {
for (byte b : id) {
if (b != (byte) 0xFF) {
return false;
}
}
return true;
}
public static final UniqueID nil = genNil();
public static UniqueID genNil() {
byte[] b = new byte[LENGTH];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) 0xFF;
}
return new UniqueID(b);
}
public static UniqueID randomID() {
byte[] b = new byte[LENGTH];
new Random().nextBytes(b);
return new UniqueID(b);
}
}
@@ -0,0 +1,25 @@
package org.ray.api;
/**
* The result of Ray.wait() distinguish the ready ones and the remain ones
*/
public class WaitResult<T> {
private final RayList<T> readyOnes;
private final RayList<T> remainOnes;
public WaitResult(RayList<T> readyOnes, RayList<T> remainOnes) {
this.readyOnes = readyOnes;
this.remainOnes = remainOnes;
}
public RayList<T> getReadyOnes() {
return readyOnes;
}
public RayList<T> getRemainOnes() {
return remainOnes;
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_0_1<R0> extends RayFunc {
R0 apply() throws Throwable;
static <R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_1<R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply();
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_0_2<R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply() throws Throwable;
static <R0, R1> MultipleReturns2<R0, R1> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_2<R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply();
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_0_3<R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply() throws Throwable;
static <R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_3<R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply();
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_0_4<R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply() throws Throwable;
static <R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_4<R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply();
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_0_n<R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids) throws Throwable;
static <R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_n<R, RID> f = SerializationUtils.deserialize(funcBytes);
return f.apply((Collection<RID>) args[0]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_0_n_list<R> extends RayFunc {
List<R> apply() throws Throwable;
static <R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_0_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_0_n_list<R> f = SerializationUtils.deserialize(funcBytes);
return f.apply();
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_1_1<T0, R0> extends RayFunc {
R0 apply(T0 t0) throws Throwable;
static <T0, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_1<T0, R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_1_2<T0, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0) throws Throwable;
static <T0, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_2<T0, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_1_3<T0, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0) throws Throwable;
static <T0, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_3<T0, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_1_4<T0, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0) throws Throwable;
static <T0, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_4<T0, R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_1_n<T0, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0) throws Throwable;
static <T0, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_n<T0, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f.apply((Collection<RID>) args[0], (T0) args[1]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_1_n_list<T0, R> extends RayFunc {
List<R> apply(T0 t0) throws Throwable;
static <T0, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_1_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_1_n_list<T0, R> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0]);
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_2_1<T0, T1, R0> extends RayFunc {
R0 apply(T0 t0, T1 t1) throws Throwable;
static <T0, T1, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_1<T0, T1, R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_2_2<T0, T1, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0, T1 t1) throws Throwable;
static <T0, T1, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_2<T0, T1, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_2_3<T0, T1, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0, T1 t1) throws Throwable;
static <T0, T1, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_3<T0, T1, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_2_4<T0, T1, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0, T1 t1) throws Throwable;
static <T0, T1, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_4<T0, T1, R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_2_n<T0, T1, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0, T1 t1) throws Throwable;
static <T0, T1, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_n<T0, T1, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f.apply((Collection<RID>) args[0], (T0) args[1], (T1) args[2]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_2_n_list<T0, T1, R> extends RayFunc {
List<R> apply(T0 t0, T1 t1) throws Throwable;
static <T0, T1, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_2_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_2_n_list<T0, T1, R> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1]);
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_3_1<T0, T1, T2, R0> extends RayFunc {
R0 apply(T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_1<T0, T1, T2, R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_3_2<T0, T1, T2, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_2<T0, T1, T2, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_3_3<T0, T1, T2, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_3<T0, T1, T2, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_3_4<T0, T1, T2, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_4<T0, T1, T2, R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_3_n<T0, T1, T2, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_n<T0, T1, T2, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f.apply((Collection<RID>) args[0], (T0) args[1], (T1) args[2], (T2) args[3]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_3_n_list<T0, T1, T2, R> extends RayFunc {
List<R> apply(T0 t0, T1 t1, T2 t2) throws Throwable;
static <T0, T1, T2, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_3_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_3_n_list<T0, T1, T2, R> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2]);
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_4_1<T0, T1, T2, T3, R0> extends RayFunc {
R0 apply(T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_1<T0, T1, T2, T3, R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_4_2<T0, T1, T2, T3, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_2<T0, T1, T2, T3, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_4_3<T0, T1, T2, T3, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_3<T0, T1, T2, T3, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_4_4<T0, T1, T2, T3, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_4<T0, T1, T2, T3, R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
}
}
@@ -0,0 +1,22 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_4_n<T0, T1, T2, T3, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_n<T0, T1, T2, T3, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((Collection<RID>) args[0], (T0) args[1], (T1) args[2], (T2) args[3], (T3) args[4]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_4_n_list<T0, T1, T2, T3, R> extends RayFunc {
List<R> apply(T0 t0, T1 t1, T2 t2, T3 t3) throws Throwable;
static <T0, T1, T2, T3, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_4_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_4_n_list<T0, T1, T2, T3, R> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3]);
}
}
@@ -0,0 +1,19 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_5_1<T0, T1, T2, T3, T4, R0> extends RayFunc {
R0 apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_1<T0, T1, T2, T3, T4, R0> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_5_2<T0, T1, T2, T3, T4, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_2<T0, T1, T2, T3, T4, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_5_3<T0, T1, T2, T3, T4, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_3<T0, T1, T2, T3, T4, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_5_4<T0, T1, T2, T3, T4, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(
Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_4<T0, T1, T2, T3, T4, R0, R1, R2, R3> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4]);
}
}
@@ -0,0 +1,23 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_5_n<T0, T1, T2, T3, T4, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_n<T0, T1, T2, T3, T4, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((Collection<RID>) args[0], (T0) args[1], (T1) args[2], (T2) args[3], (T3) args[4],
(T4) args[5]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_5_n_list<T0, T1, T2, T3, T4, R> extends RayFunc {
List<R> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
static <T0, T1, T2, T3, T4, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_5_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_5_n_list<T0, T1, T2, T3, T4, R> f = SerializationUtils.deserialize(funcBytes);
return f.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4]);
}
}
@@ -0,0 +1,20 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_6_1<T0, T1, T2, T3, T4, T5, R0> extends RayFunc {
R0 apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
static <T0, T1, T2, T3, T4, T5, R0> R0 execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_1.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_1<T0, T1, T2, T3, T4, T5, R0> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4], (T5) args[5]);
}
}
@@ -0,0 +1,22 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns2;
@FunctionalInterface
public interface RayFunc_6_2<T0, T1, T2, T3, T4, T5, R0, R1> extends RayFunc {
MultipleReturns2<R0, R1> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
static <T0, T1, T2, T3, T4, T5, R0, R1> MultipleReturns2<R0, R1> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_2.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_2<T0, T1, T2, T3, T4, T5, R0, R1> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4], (T5) args[5]);
}
}
@@ -0,0 +1,22 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns3;
@FunctionalInterface
public interface RayFunc_6_3<T0, T1, T2, T3, T4, T5, R0, R1, R2> extends RayFunc {
MultipleReturns3<R0, R1, R2> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
static <T0, T1, T2, T3, T4, T5, R0, R1, R2> MultipleReturns3<R0, R1, R2> execute(Object[] args)
throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_3.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_3<T0, T1, T2, T3, T4, T5, R0, R1, R2> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4], (T5) args[5]);
}
}
@@ -0,0 +1,23 @@
package org.ray.api.funcs;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
import org.ray.api.returns.MultipleReturns4;
@FunctionalInterface
public interface RayFunc_6_4<T0, T1, T2, T3, T4, T5, R0, R1, R2, R3> extends RayFunc {
MultipleReturns4<R0, R1, R2, R3> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
static <T0, T1, T2, T3, T4, T5, R0, R1, R2, R3> MultipleReturns4<R0, R1, R2, R3> execute(
Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_4.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_4<T0, T1, T2, T3, T4, T5, R0, R1, R2, R3> f = SerializationUtils
.deserialize(funcBytes);
return f
.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4], (T5) args[5]);
}
}
@@ -0,0 +1,24 @@
package org.ray.api.funcs;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_6_n<T0, T1, T2, T3, T4, T5, R, RID> extends RayFunc {
Map<RID, R> apply(Collection<RID> returnids, T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
throws Throwable;
static <T0, T1, T2, T3, T4, T5, R, RID> Map<RID, R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_n.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_n<T0, T1, T2, T3, T4, T5, R, RID> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((Collection<RID>) args[0], (T0) args[1], (T1) args[2], (T2) args[3], (T3) args[4],
(T4) args[5], (T5) args[6]);
}
}
@@ -0,0 +1,21 @@
package org.ray.api.funcs;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.ray.api.internal.RayFunc;
@FunctionalInterface
public interface RayFunc_6_n_list<T0, T1, T2, T3, T4, T5, R> extends RayFunc {
List<R> apply(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
static <T0, T1, T2, T3, T4, T5, R> List<R> execute(Object[] args) throws Throwable {
String name = (String) args[args.length - 2];
assert (name.equals(RayFunc_6_n_list.class.getName()));
byte[] funcBytes = (byte[]) args[args.length - 1];
RayFunc_6_n_list<T0, T1, T2, T3, T4, T5, R> f = SerializationUtils.deserialize(funcBytes);
return f
.apply((T0) args[0], (T1) args[1], (T2) args[2], (T3) args[3], (T4) args[4], (T5) args[5]);
}
}
@@ -0,0 +1,9 @@
package org.ray.api.internal;
/**
* hold the remote call
*/
public interface Callable {
void run() throws Throwable;
}
@@ -0,0 +1,26 @@
package org.ray.api.internal;
import java.lang.reflect.Method;
import org.ray.api.RayApi;
import org.ray.util.logger.RayLog;
/**
* Mediator, which pulls the {@code org.ray.api.RayApi} up to run.
*/
public class RayConnector {
private static final String className = "org.ray.core.RayRuntime";
public static RayApi run() {
try {
Method m = Class.forName(className).getDeclaredMethod("init");
m.setAccessible(true);
RayApi api = (RayApi) m.invoke(null);
m.setAccessible(false);
return api;
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
RayLog.core.error("Load " + className + " class failed.", e);
throw new Error("RayApi is not successfully initiated.");
}
}
}
@@ -0,0 +1,10 @@
package org.ray.api.internal;
import java.io.Serializable;
/**
* Base of the ray remote function
*/
public interface RayFunc extends Serializable {
}
@@ -0,0 +1,18 @@
package org.ray.api.returns;
/**
* Multiple return objects for user's method
*/
public class MultipleReturns {
protected final Object[] values;
public MultipleReturns(Object values[]) {
this.values = values;
}
public Object[] getValues() {
return values;
}
}
@@ -0,0 +1,17 @@
package org.ray.api.returns;
@SuppressWarnings("unchecked")
public class MultipleReturns2<R0, R1> extends MultipleReturns {
public MultipleReturns2(R0 r0, R1 r1) {
super(new Object[]{r0, r1});
}
public R0 get0() {
return (R0) this.values[0];
}
public R1 get1() {
return (R1) this.values[1];
}
}
@@ -0,0 +1,21 @@
package org.ray.api.returns;
@SuppressWarnings("unchecked")
public class MultipleReturns3<R0, R1, R2> extends MultipleReturns {
public MultipleReturns3(R0 r0, R1 r1, R2 r2) {
super(new Object[]{r0, r1, r2});
}
public R0 get0() {
return (R0) this.values[0];
}
public R1 get1() {
return (R1) this.values[1];
}
public R2 get2() {
return (R2) this.values[2];
}
}
@@ -0,0 +1,25 @@
package org.ray.api.returns;
@SuppressWarnings("unchecked")
public class MultipleReturns4<R0, R1, R2, R3> extends MultipleReturns {
public MultipleReturns4(R0 r0, R1 r1, R2 r2, R3 r3) {
super(new Object[]{r0, r1, r2, r3});
}
public R0 get0() {
return (R0) this.values[0];
}
public R1 get1() {
return (R1) this.values[1];
}
public R2 get2() {
return (R2) this.values[2];
}
public R3 get3() {
return (R3) this.values[3];
}
}
@@ -0,0 +1,25 @@
package org.ray.api.returns;
import org.ray.api.RayObject;
import org.ray.api.RayObjects;
import org.ray.api.UniqueID;
@SuppressWarnings({"rawtypes", "unchecked"})
public class RayObjects2<R0, R1> extends RayObjects {
public RayObjects2(UniqueID[] ids) {
super(ids);
}
public RayObjects2(RayObject objs[]) {
super(objs);
}
public RayObject<R0> r0() {
return objs[0];
}
public RayObject<R1> r1() {
return objs[1];
}
}
@@ -0,0 +1,29 @@
package org.ray.api.returns;
import org.ray.api.RayObject;
import org.ray.api.RayObjects;
import org.ray.api.UniqueID;
@SuppressWarnings({"rawtypes", "unchecked"})
public class RayObjects3<R0, R1, R2> extends RayObjects {
public RayObjects3(UniqueID[] ids) {
super(ids);
}
public RayObjects3(RayObject objs[]) {
super(objs);
}
public RayObject<R0> r0() {
return objs[0];
}
public RayObject<R1> r1() {
return objs[1];
}
public RayObject<R2> r2() {
return objs[2];
}
}
@@ -0,0 +1,33 @@
package org.ray.api.returns;
import org.ray.api.RayObject;
import org.ray.api.RayObjects;
import org.ray.api.UniqueID;
@SuppressWarnings({"rawtypes", "unchecked"})
public class RayObjects4<R0, R1, R2, R3> extends RayObjects {
public RayObjects4(UniqueID[] ids) {
super(ids);
}
public RayObjects4(RayObject objs[]) {
super(objs);
}
public RayObject<R0> r0() {
return objs[0];
}
public RayObject<R1> r1() {
return objs[1];
}
public RayObject<R2> r2() {
return objs[2];
}
public RayObject<R3> r3() {
return objs[3];
}
}
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
pushd ../thirdparty/build/arrow/java/plasma
mvn clean install -Dmaven.test.skip
popd
mvn clean install -Dmaven.test.skip
+8
View File
@@ -0,0 +1,8 @@
pkill -9 python
pkill -9 local_scheduler
pkill -9 plasma_manager
pkill -9 plasma_store
pkill -9 global_scheduler
pkill -9 redis-server
pkill -9 redis
ps aux | grep ray | awk '{system("kill "$2);}'
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.ray.parent</groupId>
<artifactId>ray-superpom</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.ray</groupId>
<artifactId>ray-common</artifactId>
<name>java common and util for ray</name>
<description>java common and util for ray</description>
<url></url>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,19 @@
package org.ray.util;
import java.util.Random;
/**
* Common utilities
*/
public class CommonUtil {
private static final Random seed = new Random();
/**
* Get random number between 0 and (max-1)
*/
public static int getRandom(int max) {
return Math.abs(seed.nextInt() % max);
}
}
@@ -0,0 +1,134 @@
package org.ray.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class FileUtil {
public static String getFilename(String logPath) {
if (logPath != null && !logPath.isEmpty()) {
int lastPos = logPath.lastIndexOf('/');
if (lastPos != -1) {
return logPath.substring(lastPos + 1);
} else {
return logPath;
}
}
return null;
}
public static boolean deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return true;
} else {
if (file.isFile()) {
return file.delete();
} else {
for (File f : file.listFiles()) {
deleteFile(f.getAbsolutePath());
}
return file.delete();
}
}
}
public static void mkDir(File dir) {
if (dir.exists()) {
return;
}
if (dir.getParentFile().exists()) {
dir.mkdir();
} else {
mkDir(dir.getParentFile());
dir.mkdir();
}
}
public static void mkDirAndFile(File file) throws IOException {
if (file.exists()) {
return;
}
if (!file.getParentFile().exists()) {
mkDir(file.getParentFile());
}
file.createNewFile();
}
public static String readResourceFile(String fileName) throws FileNotFoundException {
ClassLoader classLoader = FileUtil.class.getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
StringBuilder result = new StringBuilder();
try (Scanner scanner = new Scanner(file)) {
//Get file from resources folder
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
result.append(line).append("\n");
}
return result.toString();
}
}
public static void overrideFile(String file, String str) throws IOException {
try (FileWriter fw = new FileWriter(file)) {
fw.write(str);
}
}
public static boolean createDir(String dirName, boolean failIfExist) {
File wdir = new File(dirName);
if (wdir.isFile()) {
return false;
}
if (!wdir.exists()) {
wdir.mkdirs();
} else if (failIfExist) {
return false;
}
return true;
}
public static void bytesToFile(byte[] bytes, String name) throws IOException {
Path path = Paths.get(name);
Files.write(path, bytes);
}
public static byte[] fileToBytes(String name) throws IOException {
Path path = Paths.get(name);
return Files.readAllBytes(path);
}
/**
* If the given string is the empty string, then the result is the current directory.
*
* @param rawDir a path in any legal form, such as a relative path
* @return the absolute and unique path in String
*/
public static String getCanonicalDirectory(final String rawDir) throws IOException {
String dir = rawDir.length() == 0 ? "." : rawDir;
// create working dir if necessary
File dd = new File(dir);
if (!dd.exists()) {
dd.mkdirs();
}
if (!dir.startsWith("/")) {
dir = dd.getCanonicalPath();
}
return dir;
}
}
@@ -0,0 +1,30 @@
package org.ray.util;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import org.ray.util.logger.RayLog;
public class MD5Digestor {
private static final ThreadLocal<MessageDigest> md = ThreadLocal.withInitial(() -> {
try {
return MessageDigest.getInstance("MD5");
} catch (Exception e) {
RayLog.core.error("cannot get MD5 MessageDigest", e);
throw new RuntimeException("cannot get MD5 digest", e);
}
});
private static final ThreadLocal<ByteBuffer> longBuffer = ThreadLocal
.withInitial(() -> ByteBuffer.allocate(Long.SIZE / Byte.SIZE));
public static byte[] digest(byte[] src, long addIndex) {
MessageDigest dg = md.get();
longBuffer.get().clear();
dg.reset();
dg.update(src);
dg.update(longBuffer.get().putLong(addIndex).array());
return dg.digest();
}
}
@@ -0,0 +1,62 @@
package org.ray.util;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.util.Enumeration;
import org.ray.util.logger.RayLog;
public class NetworkUtil {
public static String getIpAddress(String interfaceName) {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface current = interfaces.nextElement();
if (!current.isUp() || current.isLoopback() || current.isVirtual()) {
continue;
}
if (!StringUtil.isNullOrEmpty(interfaceName) && !interfaceName
.equals(current.getDisplayName())) {
continue;
}
Enumeration<InetAddress> addresses = current.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr.isLoopbackAddress()) {
continue;
}
if (addr instanceof Inet6Address) {
continue;
}
return addr.getHostAddress();
}
}
RayLog.core.warn("you may need to correctly specify [ray.java] net_interface in config");
} catch (Exception e) {
RayLog.core.error("Can't get our ip address, use 127.0.0.1 as default.", e);
}
return "127.0.0.1";
}
public static boolean isPortAvailable(int port) {
if (port < 1 || port > 65535) {
throw new IllegalArgumentException("Invalid start port: " + port);
}
try (ServerSocket ss = new ServerSocket(port); DatagramSocket ds = new DatagramSocket(port)) {
ss.setReuseAddress(true);
ds.setReuseAddress(true);
return true;
} catch (IOException ignored) {
}
/* should not be thrown */
return false;
}
}
@@ -0,0 +1,24 @@
package org.ray.util;
import java.lang.reflect.InvocationTargetException;
public class ObjectUtil {
public static <T> T newObject(Class<T> cls) {
try {
return cls.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
public static boolean[] toBooleanArray(Object[] vs) {
boolean[] nvs = new boolean[vs.length];
for (int i = 0; i < vs.length; i++) {
nvs[i] = (boolean) vs[i];
}
return nvs;
}
}
@@ -0,0 +1,10 @@
package org.ray.util;
import java.io.Serializable;
import java.util.function.BiFunction;
@FunctionalInterface
public interface RemoteBiFunction<T1, T2, O> extends BiFunction<T1, T2, O>, Serializable {
}
@@ -0,0 +1,9 @@
package org.ray.util;
import java.io.Serializable;
import java.util.function.Function;
@FunctionalInterface
public interface RemoteFunction<I, O> extends Function<I, O>, Serializable {
}
@@ -0,0 +1,30 @@
package org.ray.util;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import org.ray.util.logger.RayLog;
public class Sha1Digestor {
private static final ThreadLocal<MessageDigest> md = ThreadLocal.withInitial(() -> {
try {
return MessageDigest.getInstance("SHA1");
} catch (Exception e) {
RayLog.core.error("cannot get SHA1 MessageDigest", e);
throw new RuntimeException("cannot get SHA1 digest", e);
}
});
private static final ThreadLocal<ByteBuffer> longBuffer = ThreadLocal
.withInitial(() -> ByteBuffer.allocate(Long.SIZE / Byte.SIZE));
public static byte[] digest(byte[] src, long addIndex) {
MessageDigest dg = md.get();
longBuffer.get().clear();
dg.reset();
dg.update(src);
dg.update(longBuffer.get().putLong(addIndex).array());
return dg.digest();
}
}
@@ -0,0 +1,134 @@
package org.ray.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Vector;
public class StringUtil {
// Holds the start of an element and which brace started it.
private static class Start {
// The brace number from the braces string in use.
final int brace;
// The position in the string it was seen.
final int pos;
// Constructor.
public Start(int brace, int pos) {
this.brace = brace;
this.pos = pos;
}
}
/**
* @param s input string
* @param splitters common splitters
* @param open open braces
* @param close close braces
* @return output array list
*/
public static Vector<String> Split(String s, String splitters, String open, String close) {
// The splits.
Vector<String> split = new Vector<>();
// The stack.
ArrayList<Start> stack = new ArrayList<>();
int lastPos = 0;
// Walk the string.
for (int i = 0; i < s.length(); i++) {
// Get the char there.
char ch = s.charAt(i);
// Is it an open brace?
int o = open.indexOf(ch);
// Is it a close brace?
int c = close.indexOf(ch);
// Is it a splitter?
int sp = splitters.indexOf(ch);
if (stack.size() == 0 && sp >= 0) {
if (i == lastPos) {
++lastPos;
continue;
}
split.add(s.substring(lastPos, i));
lastPos = i + 1;
} else if (o >= 0 && (c < 0 || stack.size() == 0)) {
// Its an open! Push it.
stack.add(new Start(o, i));
} else if (c >= 0 && stack.size() > 0) {
// Pop (if matches).
int tosPos = stack.size() - 1;
Start tos = stack.get(tosPos);
// Does the brace match?
if (tos.brace == c) {
// Done with that one.
stack.remove(tosPos);
}
}
}
if (lastPos < s.length()) {
split.add(s.substring(lastPos, s.length()));
}
// build removal filter set
HashSet<Character> removals = new HashSet<>();
for (int i = 0; i < splitters.length(); i++) {
removals.add(splitters.charAt(i));
}
for (int i = 0; i < open.length(); i++) {
removals.add(open.charAt(i));
}
for (int i = 0; i < close.length(); i++) {
removals.add(close.charAt(i));
}
// apply removal filter set
for (int i = 0; i < split.size(); i++) {
String cs = split.get(i);
// remove heading chars
int j;
for (j = 0; j < cs.length(); j++) {
if (!removals.contains(cs.charAt(j))) {
break;
}
}
cs = cs.substring(j);
// remove tail chars
for (j = cs.length() - 1; j >= 0; j--) {
if (!removals.contains(cs.charAt(j))) {
break;
}
}
cs = cs.substring(0, j + 1);
// reset cs
split.set(i, cs);
}
return split;
}
public static boolean isNullOrEmpty(String s) {
return s == null || s.length() == 0;
}
public static <T> String mergeArray(T[] objs, String concatenator) {
StringBuilder sb = new StringBuilder();
for (T obj : objs) {
sb.append(obj).append(concatenator);
}
return objs.length == 0 ? "" : sb.substring(0, sb.length() - concatenator.length());
}
}
@@ -0,0 +1,64 @@
package org.ray.util;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.concurrent.locks.ReentrantLock;
import org.ray.util.logger.RayLog;
/**
* some utilities for system process
*/
public class SystemUtil {
public static String userHome() {
return System.getProperty("user.home");
}
public static String userDir() {
return System.getProperty("user.dir");
}
public static boolean startWithJar(Class<?> cls) {
return cls.getResource(cls.getSimpleName() + ".class").getFile().split("!")[0].endsWith(".jar");
}
public static boolean startWithJar(String clsName) {
Class<?> cls;
try {
cls = Class.forName(clsName);
return cls.getResource(cls.getSimpleName() + ".class").getFile().split("!")[0]
.endsWith(".jar");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
RayLog.core.error("error at SystemUtil startWithJar", e);
return false;
}
}
static Integer pid;
static final ReentrantLock pidlock = new ReentrantLock();
public static int pid() {
if (pid == null) {
pidlock.lock();
try {
if (pid == null) {
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
String name = runtime.getName();
int index = name.indexOf("@");
if (index != -1) {
pid = Integer.parseInt(name.substring(0, index));
} else {
throw new RuntimeException("parse pid error:" + name);
}
}
} finally {
pidlock.unlock();
}
}
return pid;
}
}
@@ -0,0 +1,36 @@
package org.ray.util.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotate a field as a ray configuration item.
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AConfig {
/**
* comments for this configuration field
*/
String comment();
/**
* when the config is an array list, a splitter set is specified, e.g., " \t" to use ' ' and '\t'
* as possible splits
*/
String splitters() default ", \t";
/**
* indirect with value as the new section name, the field name remains the same
*/
String defaultIndirectSectionName() default "";
/**
* see ConfigReader.getIndirectStringArray this config tells which is the default
* indirectSectionName in that function
*/
String defaultArrayIndirectSectionName() default "";
}
@@ -0,0 +1,15 @@
package org.ray.util.config;
/**
* A ray configuration item of type {@code T}.
*/
public class ConfigItem<T> {
public String key;
public String oriValue;
public T defaultValue;
public String desc;
}
@@ -0,0 +1,385 @@
package org.ray.util.config;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Vector;
import org.ini4j.Config;
import org.ini4j.Ini;
import org.ini4j.Profile;
import org.ray.util.ObjectUtil;
import org.ray.util.StringUtil;
/**
* Loads configurations from a file.
*/
public class ConfigReader {
private final CurrentUseConfig currentUseConfig = new CurrentUseConfig();
private final Ini ini = new Ini();
private String file = "";
public ConfigReader(String filePath) throws Exception {
this(filePath, null);
}
public ConfigReader(String filePath, String updateConfigStr) throws Exception {
System.out.println("Build ConfigReader, the file path " + filePath + " ,the update config str "
+ updateConfigStr);
try {
loadConfigFile(filePath);
updateConfigFile(updateConfigStr);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public String filePath() {
return file;
}
private void loadConfigFile(String filePath) throws Exception {
this.currentUseConfig.filePath = filePath;
String configFileDir = (new File(filePath)).getAbsoluteFile().getParent();
byte[] encoded = Files.readAllBytes(Paths.get(filePath));
String content = new String(encoded, StandardCharsets.UTF_8);
content = content.replaceAll("%CONFIG_FILE_DIR%", configFileDir);
InputStream fis = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
Config config = new Config();
ini.setConfig(config);
ini.load(fis);
file = currentUseConfig.filePath;
}
private void updateConfigFile(String updateConfigStr) {
if (updateConfigStr == null) {
return;
}
String[] updateConfigArray = updateConfigStr.split(";");
for (String currentUpdateConfig : updateConfigArray) {
if (StringUtil.isNullOrEmpty(currentUpdateConfig)) {
continue;
}
String[] currentUpdateConfigArray = currentUpdateConfig.split("=");
String sectionAndItemKey;
String value = "";
if (currentUpdateConfigArray.length == 2) {
sectionAndItemKey = currentUpdateConfigArray[0];
value = currentUpdateConfigArray[1];
} else if (currentUpdateConfigArray.length == 1) {
sectionAndItemKey = currentUpdateConfigArray[0];
} else {
String errorMsg = "invalid config (must be of k=v or k or k=): " + currentUpdateConfig;
System.err.println(errorMsg);
throw new RuntimeException(errorMsg);
}
int splitOffset = sectionAndItemKey.lastIndexOf(".");
int len = sectionAndItemKey.length();
if (splitOffset < 1 || splitOffset == len - 1) {
String errorMsg =
"invalid config (no '.' found for section name and key):" + currentUpdateConfig;
System.err.println(errorMsg);
throw new RuntimeException(errorMsg);
}
String sectionKey = sectionAndItemKey.substring(0, splitOffset);
String itemKey = sectionAndItemKey.substring(splitOffset + 1);
if (ini.containsKey(sectionKey)) {
ini.get(sectionKey).put(itemKey, value);
} else {
ini.add(sectionKey, itemKey, value);
}
}
}
public CurrentUseConfig getCurrentUseConfig() {
return currentUseConfig;
}
private synchronized <T> String getOriValue(String sectionKey, String configKey, T defaultValue,
String deptr) {
if (null == deptr) {
throw new RuntimeException("desc must not be empty of the key:" + configKey);
}
Profile.Section section = ini.get(sectionKey);
String oriValue = null;
if (section != null && section.containsKey(configKey)) {
oriValue = section.get(configKey);
}
if (!currentUseConfig.sectionMap.containsKey(sectionKey)) {
ConfigSection configSection = new ConfigSection();
configSection.sectionKey = sectionKey;
updateConfigSection(configSection, configKey, defaultValue, deptr, oriValue);
currentUseConfig.sectionMap.put(sectionKey, configSection);
} else if (!currentUseConfig.sectionMap.get(sectionKey).itemMap.containsKey(configKey)) {
ConfigSection configSection = currentUseConfig.sectionMap.get(sectionKey);
updateConfigSection(configSection, configKey, defaultValue, deptr, oriValue);
}
return oriValue;
}
private <T> void updateConfigSection(ConfigSection configSection, String configKey,
T defaultValue, String deptr, String oriValue) {
ConfigItem<T> configItem = new ConfigItem<>();
configItem.defaultValue = defaultValue;
configItem.key = configKey;
configItem.oriValue = oriValue;
configItem.desc = deptr;
configSection.itemMap.put(configKey, configItem);
}
public String getStringValue(String sectionKey, String configKey, String defaultValue,
String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
if (value != null) {
return value;
} else {
return defaultValue;
}
}
public boolean getBooleanValue(String sectionKey, String configKey, boolean defaultValue,
String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
if (value != null) {
if (value.length() == 0) {
return defaultValue;
} else {
return Boolean.valueOf(value);
}
} else {
return defaultValue;
}
}
public int getIntegerValue(String sectionKey, String configKey, int defaultValue, String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
if (value != null) {
if (value.length() == 0) {
return defaultValue;
} else {
return Integer.valueOf(value);
}
} else {
return defaultValue;
}
}
public long getLongValue(String sectionKey, String configKey, long defaultValue, String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
if (value != null) {
if (value.length() == 0) {
return defaultValue;
} else {
return Long.valueOf(value);
}
} else {
return defaultValue;
}
}
public double getDoubleValue(String sectionKey, String configKey, double defaultValue,
String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
if (value != null) {
if (value.length() == 0) {
return defaultValue;
} else {
return Double.valueOf(value);
}
} else {
return defaultValue;
}
}
public int[] getIntegerArray(String sectionKey, String configKey, int[] defaultValue,
String dsptr) {
String value = getOriValue(sectionKey, configKey, defaultValue, dsptr);
int[] array = defaultValue;
if (value != null) {
String[] list = value.split(",");
array = new int[list.length];
for (int i = 0; i < list.length; i++) {
array[i] = Integer.valueOf(list[i]);
}
}
return array;
}
/**
* get a string list from a whole section as keys e.g., [core] data_dirs = local.dirs # or
* cluster.dirs
*
* [local.dirs] /home/xxx/1 /home/yyy/2
*
* [cluster.dirs] ...
*
* @param sectionKey e.g., core
* @param configKey e.g., data_dirs
* @param indirectSectionName e.g., cluster.dirs
* @return string list
*/
public String[] getIndirectStringArray(String sectionKey, String configKey,
String indirectSectionName, String dsptr) {
String s = getStringValue(sectionKey, configKey, indirectSectionName, dsptr);
Profile.Section section = ini.get(s);
if (section == null) {
return new String[]{};
} else {
return section.keySet().toArray(new String[]{});
}
}
public <T> void readObject(String sectionKey, T obj, T defaultValues) {
for (Field fld : obj.getClass().getFields()) {
Object defaultFldValue;
try {
defaultFldValue = defaultValues != null ? fld.get(defaultValues) : null;
} catch (IllegalArgumentException | IllegalAccessException e) {
defaultFldValue = null;
}
String section = sectionKey;
String comment;
String splitters = ", \t";
String defaultArrayIndirectSectionName;
AConfig[] anns = fld.getAnnotationsByType(AConfig.class);
if (anns.length > 0) {
comment = anns[0].comment();
if (!StringUtil.isNullOrEmpty(anns[0].splitters())) {
splitters = anns[0].splitters();
}
defaultArrayIndirectSectionName = anns[0].defaultArrayIndirectSectionName();
// redirect the section if necessary
if (!StringUtil.isNullOrEmpty(anns[0].defaultIndirectSectionName())) {
section = this
.getStringValue(sectionKey, fld.getName(), anns[0].defaultIndirectSectionName(),
comment);
}
} else {
throw new RuntimeException("unspecified comment, please use @AConfig(comment = xxxx) for "
+ obj.getClass().getName() + "." + fld.getName() + "'s configuration descriptions ");
}
try {
if (fld.getType().isPrimitive()) {
if (fld.getType().equals(boolean.class)) {
boolean v = getBooleanValue(section, fld.getName(), (boolean) defaultFldValue, comment);
fld.set(obj, v);
} else if (fld.getType().equals(float.class)) {
float v = (float) getDoubleValue(section, fld.getName(),
(double) (float) defaultFldValue, comment);
fld.set(obj, v);
} else if (fld.getType().equals(double.class)) {
double v = getDoubleValue(section, fld.getName(), (double) defaultFldValue, comment);
fld.set(obj, v);
} else if (fld.getType().equals(byte.class)) {
byte v = (byte) getLongValue(section, fld.getName(), (long) (byte) defaultFldValue,
comment);
fld.set(obj, v);
} else if (fld.getType().equals(char.class)) {
char v = (char) getLongValue(section, fld.getName(), (long) (char) defaultFldValue,
comment);
fld.set(obj, v);
} else if (fld.getType().equals(short.class)) {
short v = (short) getLongValue(section, fld.getName(), (long) (short) defaultFldValue,
comment);
fld.set(obj, v);
} else if (fld.getType().equals(int.class)) {
int v = (int) getLongValue(section, fld.getName(), (long) (int) defaultFldValue,
comment);
fld.set(obj, v);
} else if (fld.getType().equals(long.class)) {
long v = getLongValue(section, fld.getName(), (long) defaultFldValue, comment);
fld.set(obj, v);
} else {
throw new RuntimeException("unhandled type " + fld.getType().getName());
}
} else if (fld.getType().equals(String.class)) {
String v = getStringValue(section, fld.getName(), (String) defaultFldValue, comment);
fld.set(obj, v);
} else if (fld.getType().isEnum()) {
String sv = getStringValue(section, fld.getName(), defaultFldValue.toString(), comment);
@SuppressWarnings({"unchecked", "rawtypes"})
Object v = Enum.valueOf((Class<Enum>) fld.getType(), sv);
fld.set(obj, v);
// TODO: this is a hack and needs to be resolved later
} else if (fld.getType().getName().equals("org.ray.api.UniqueID")) {
String sv = getStringValue(section, fld.getName(), defaultFldValue.toString(), comment);
Object v;
try {
v = fld.getType().getConstructor(new Class<?>[]{String.class}).newInstance(sv);
} catch (NoSuchMethodException | SecurityException | InstantiationException | InvocationTargetException e) {
System.err.println(
section + "." + fld.getName() + "'s format (" + sv + ") is invalid, default to "
+ defaultFldValue.toString());
v = defaultFldValue;
}
fld.set(obj, v);
} else if (fld.getType().isArray()) {
Class<?> ccls = fld.getType().getComponentType();
String ss = getStringValue(section, fld.getName(), null, comment);
if (null == ss) {
fld.set(obj, defaultFldValue);
} else {
Vector<String> ls = StringUtil.Split(ss, splitters, "", "");
if (ccls.equals(boolean.class)) {
boolean[] v = ObjectUtil
.toBooleanArray(ls.stream().map(Boolean::parseBoolean).toArray());
fld.set(obj, v);
} else if (ccls.equals(double.class)) {
double[] v = ls.stream().mapToDouble(Double::parseDouble).toArray();
fld.set(obj, v);
} else if (ccls.equals(int.class)) {
int[] v = ls.stream().mapToInt(Integer::parseInt).toArray();
fld.set(obj, v);
} else if (ccls.equals(long.class)) {
long[] v = ls.stream().mapToLong(Long::parseLong).toArray();
fld.set(obj, v);
} else if (ccls.equals(String.class)) {
String[] v;
if (StringUtil.isNullOrEmpty(defaultArrayIndirectSectionName)) {
v = ls.toArray(new String[]{});
} else {
v = this
.getIndirectStringArray(section, fld.getName(),
defaultArrayIndirectSectionName,
comment);
}
fld.set(obj, v);
} else {
throw new RuntimeException(
"Array with component type " + ccls.getName() + " is not supported yet");
}
}
} else {
Object fldObj = ObjectUtil.newObject(fld.getType());
fld.set(obj, fldObj);
readObject(section + "." + fld.getName(), fldObj, defaultFldValue);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("set fld " + fld.getName() + " failed, err = " + e.getMessage(),
e);
}
}
}
}
@@ -0,0 +1,14 @@
package org.ray.util.config;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* A configuration section of related items.
*/
public class ConfigSection {
public String sectionKey;
public final Map<String, ConfigItem<?>> itemMap = new ConcurrentHashMap<>();
}
@@ -0,0 +1,16 @@
package org.ray.util.config;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* The configuration which is currently in use.
*/
public class CurrentUseConfig {
public String filePath;
public final Map<String, ConfigSection> sectionMap = new ConcurrentHashMap<>();
}
@@ -0,0 +1,15 @@
package org.ray.util.exception;
/**
* An exception which is thrown when a ray task encounters an error when executing.
*/
public class TaskExecutionException extends RuntimeException {
public TaskExecutionException(Throwable cause) {
super(cause);
}
public TaskExecutionException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,38 @@
package org.ray.util.generator;
import java.util.ArrayList;
import java.util.List;
/**
* Calculate all compositions for Parameter's count + Return's count, this class is used by code
* generators.
*/
public class Composition {
public static class TR {
public final int Tcount;
public final int Rcount;
public TR(int tcount, int rcount) {
super();
Tcount = tcount;
Rcount = rcount;
}
}
public static List<TR> calculate(int maxT, int maxR) {
List<TR> ret = new ArrayList<>();
for (int t = 0; t <= maxT; t++) {
// <= 0 for dynamic return count
// 0 for call_n returns RayMap<RID, x>
// -1 for call_n returns RayObject<>[N]
for (int r = -1; r <= maxR; r++) {
ret.add(new TR(t, r));
}
}
return ret;
}
}
@@ -0,0 +1,87 @@
package org.ray.util.generator;
import java.io.IOException;
import org.ray.util.FileUtil;
import org.ray.util.generator.Composition.TR;
/**
* Generate all classes in org.ray.api.funcs
*/
public class FuncsGenerator {
public static void main(String[] args) throws IOException {
String rootdir = System.getProperty("user.dir") + "/../api/src/main/java";
rootdir += "/org/ray/api/funcs";
generate(rootdir);
}
private static void generate(String rootdir) throws IOException {
for (TR tr : Composition.calculate(Share.MAX_T, Share.MAX_R)) {
String str = build(tr.Tcount, tr.Rcount);
String file = rootdir + "/RayFunc_" + tr.Tcount + "_"
+ (tr.Rcount <= 0 ? (tr.Rcount == 0 ? "n" : "n_list") : tr.Rcount) + ".java";
FileUtil.overrideFile(file, str);
System.err.println("override " + file);
}
}
/*
* package org.ray.api.funcs;
*
* @FunctionalInterface
* public interface RayFunc_4_1<T0, T1, T2, T3, R0> extends RayFunc { R0
* apply();
*
* public static <R0> R0 execute(Object[] args) throws Throwable { String name =
* (String)args[args.length - 2]; assert (name.equals(RayFunc_0_1.class.getName())); byte[]
* funcBytes = (byte[])args[args.length - 1]; RayFunc_0_1<R0> f = (RayFunc_0_1<R0>)SerializationUtils.deserialize(funcBytes);
* return f.apply(); } }
*/
private static String build(int Tcount, int Rcount) {
StringBuilder sb = new StringBuilder();
String tname =
"Ray" + "Func_" + Tcount + "_" + (Rcount <= 0 ? (Rcount == 0 ? "n" : "n_list") : Rcount);
String gname = tname + "<" + Share.buildClassDeclare(Tcount, Rcount) + ">";
sb.append("package org.ray.api.funcs;").append("\n");
if (Rcount > 1) {
sb.append("import org.ray.api.returns.*;").append("\n");
}
if (Rcount <= 0) {
sb.append("import java.util.Collection;").append("\n");
sb.append("import java.util.List;").append("\n");
sb.append("import java.util.Map;").append("\n");
}
sb.append("import org.ray.api.*;").append("\n");
sb.append("import org.ray.api.internal.*;").append("\n");
sb.append("import org.apache.commons.lang3.SerializationUtils;").append("\n");
sb.append("\n");
sb.append("@FunctionalInterface").append("\n");
sb.append("public interface ").append(gname).append(" extends RayFunc {")
.append("\n");
sb.append("\t").append(Share.buildFuncReturn(Rcount)).append(" apply(")
.append(Rcount == 0 ? ("Collection<RID> returnids" + (Tcount > 0 ? ", " : "")) : "")
.append(Share.buildParameter(Tcount, "T", null)).append(") throws Throwable;")
.append("\n");
sb.append("\t\n");
sb.append("\tpublic static " + "<").append(Share.buildClassDeclare(Tcount, Rcount))
.append(">").append(" ").append(Share.buildFuncReturn(Rcount))
.append(" execute(Object[] args) throws Throwable {").append("\n");
sb.append("\t\tString name = (String)args[args.length - 2];").append("\n");
sb.append("\t\tassert (name.equals(").append(tname).append(".class.getName()));").append("\n");
sb.append("\t\tbyte[] funcBytes = (byte[])args[args.length - 1];").append("\n");
sb.append("\t\t").append(gname).append(" f = SerializationUtils.deserialize(funcBytes);")
.append("\n");
sb.append("\t\treturn f.apply(")
.append(Rcount == 0 ? ("(Collection<RID>)args[0]" + (Tcount > 0 ? ", " : "")) : "")
.append(Share.buildParameterUse2(Tcount, Rcount == 0 ? 1 : 0, "T", "args[", "]"))
.append(");").append("\n");
sb.append("\t}").append("\n");
sb.append("\t\n");
sb.append("}").append("\n");
return sb.toString();
}
}
@@ -0,0 +1,68 @@
package org.ray.util.generator;
import java.io.IOException;
import org.ray.util.FileUtil;
/**
* Generate all classes in org.ray.api.returns.MultipleReturnsX
*/
public class MultipleReturnGenerator {
public static void main(String[] args) throws IOException {
String rootdir = System.getProperty("user.dir") + "/../api/src/main/java";
rootdir += "/org/ray/api/returns";
for (int r = 2; r <= Share.MAX_R; r++) {
String str = build(r);
String file = rootdir + "/MultipleReturns" + r + ".java";
FileUtil.overrideFile(file, str);
System.err.println("override " + file);
}
}
/**
* package org.ray.api.returns;
*
* public class MultipleReturns2<R0, R1> extends MultipleReturns {
*
* public MultipleReturns2(R0 r0, R1 r1) { super(new Object[] { r0, r1 }); }
*
* public R0 get0() { return (R0) this.values[0]; }
*
* public R1 get1() { return (R1) this.values[1]; }
*
* }
*/
private static String build(int Rcount) {
StringBuilder sb = new StringBuilder();
sb.append("package org.ray.api.returns;").append("\n");
sb.append("import org.ray.api.*;").append("\n");
sb.append("@SuppressWarnings(\"unchecked\")");
sb.append("public class MultipleReturns").append(Rcount).append("<")
.append(Share.buildClassDeclare(0, Rcount)).append("> extends MultipleReturns {")
.append("\n");
sb.append("\tpublic MultipleReturns").append(Rcount).append("(")
.append(Share.buildParameter(Rcount, "R", null)).append(") {")
.append("\n");
sb.append("\t\tsuper(new Object[] { ").append(Share.buildParameterUse(Rcount, "R"))
.append(" });")
.append("\n");
sb.append("\t}").append("\n");
for (int k = 0; k < Rcount; k++) {
sb.append(buildGetter(k));
}
sb.append("}").append("\n");
return sb.toString();
}
/*
* @SuppressWarnings("unchecked") public R1 get1() { return (R1) this.values[1]; }
*/
private static String buildGetter(int index) {
return ("\tpublic R" + index + " get" + index + "() {\n")
+ "\t\treturn (R" + index + ") this.values[" + index + "];\n"
+ "\t}\n";
}
}
@@ -0,0 +1,71 @@
package org.ray.util.generator;
import java.io.IOException;
import org.ray.util.FileUtil;
/**
* Generate all classes in org.ray.api.returns.RayObjectsX
*/
public class RayObjectsGenerator {
public static void main(String[] args) throws IOException {
String rootdir = System.getProperty("user.dir") + "/../api/src/main/java";
rootdir += "/org/ray/api/returns";
for (int r = 2; r <= Share.MAX_R; r++) {
String str = build(r);
String file = rootdir + "/RayObjects" + r + ".java";
FileUtil.overrideFile(file, str);
System.err.println("override " + file);
}
}
/*
* package org.ray.api.returns;
*
* import org.ray.api.RayObject; import org.ray.spi.model.UniqueID;
*
* @SuppressWarnings({"rawtypes", "unchecked"}) public class RayObjects2<R0, R1> extends
* RayObjects {
*
* public RayObjects2(UniqueID[] ids) { super(ids); }
*
* public RayObjects2(RayObject objs[]) { super(objs); }
*
* public RayObject<R0> r0() { return objs[0]; }
*
* public RayObject<R1> r1() { return objs[1]; } }
*/
private static String build(int Rcount) {
StringBuilder sb = new StringBuilder();
sb.append("package org.ray.api.returns;\n");
sb.append("import org.ray.api.*;\n");
sb.append("import org.ray.spi.model.UniqueID;\n");
sb.append("@SuppressWarnings({\"rawtypes\", \"unchecked\"})");
sb.append("public class RayObjects").append(Rcount).append("<")
.append(Share.buildClassDeclare(0, Rcount)).append("> extends RayObjects {")
.append("\n");
sb.append("\tpublic RayObjects").append(Rcount).append("(UniqueID[] ids) {").append("\n");
sb.append("\t\tsuper(ids);").append("\n");
sb.append("\t}").append("\n");
sb.append("\tpublic RayObjects").append(Rcount).append("(RayObject objs[]) {").append("\n");
sb.append("\t\tsuper(objs);").append("\n");
sb.append("\t}").append("\n");
for (int k = 0; k < Rcount; k++) {
sb.append(buildGetter(k));
}
sb.append("}").append("\n");
return sb.toString();
}
/**
* public RayObject<R0> r0() { return objs[0]; }
*/
private static String buildGetter(int index) {
return "\tpublic RayObject<R" + index + "> r" + index + "() {\n"
+ "\t\treturn objs[" + index + "];\n"
+ "\t}\n";
}
}
@@ -0,0 +1,175 @@
package org.ray.util.generator;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.ray.util.FileUtil;
import org.ray.util.generator.Composition.TR;
/**
* Generate Rpc.java
*/
public class RpcGenerator {
public static void main(String[] args) throws IOException {
String rootdir = System.getProperty("user.dir") + "/../api/src/main/java";
rootdir += "/org/ray/api/Rpc.java";
FileUtil.overrideFile(rootdir, build());
}
private static String build() {
StringBuilder sb = new StringBuilder();
sb.append("package org.ray.api.internal;\n");
sb.append("import org.ray.api.funcs.*;\n");
sb.append("import org.ray.api.returns.*;\n");
sb.append("import org.ray.api.*;\n");
sb.append("import java.util.Collection;\n");
sb.append("import java.util.Map;\n");
sb.append("@SuppressWarnings({\"rawtypes\", \"unchecked\"})\n");
sb.append("class Rpc {\n");
for (TR tr : Composition.calculate(Share.MAX_T, Share.MAX_R)) {
buildCall(sb, tr.Tcount, tr.Rcount);
}
sb.append("}\n");
return sb.toString();
}
private static void buildCall(StringBuilder sb, int Tcount, int Rcount) {
for (Set<Integer> whichTisFuture : whichTisFutureComposition(Tcount)) {
sb.append(buildCall(Tcount, Rcount, whichTisFuture));
}
}
/**
* public static <T0, R0> RayObject<R0> call(RayFunc_1_1<T0, R0> f, RayObject<T0> arg) { return
* Ray.runtime().rpc(() -> f.apply(null), arg).objs[0]; }
*/
private static String buildCall(int Tcount, int Rcount, Set<Integer> whichTisFuture) {
StringBuilder sb = new StringBuilder();
String parameter = (Tcount == 0 ? ""
: ", " + Share.buildParameter(Tcount, "T", whichTisFuture));
sb.append("\tpublic static <").append(Share.buildClassDeclare(Tcount, Rcount)).append("> ")
.append(Share.buildRpcReturn(Rcount)).append(" call")
.append(Rcount == 1 ? "" : (Rcount <= 0 ? "_n" : ("_" + Rcount))).append("(RayFunc_")
.append(Tcount).append("_")
.append(Rcount <= 0 ? (Rcount == 0 ? "n" : "n_list") : Rcount).append("<")
.append(Share.buildClassDeclare(Tcount, Rcount)).append("> f").append(
Rcount <= 0 ? (Rcount == 0 ? ", Collection<RID> returnids" : ", Integer returnCount")
: "").append(parameter).append(") {\n");
/*
* public static <R0> RayObject<R0> call(RayFunc_0_1<R0> f) {
if (Ray.Parameters().remoteLambda()) {
return Ray.internal().call(RayFunc_0_1.class, f, 1).objs[0];
}
else {
return Ray.internal().call(() -> f.apply(), 1).objs[0];
}
}
*/
String nulls = Share.buildRepeat("null",
Tcount + (Rcount == 0 ? 1/*for first arg map*/ : 0));
String parameterUse = (Tcount == 0 ? "" : (", " + Share.buildParameterUse(Tcount, "T")));
String labmdaUse = "RayFunc_"
+ Tcount + "_" + (Rcount <= 0 ? (Rcount == 0 ? "n" : "n_list") : Rcount)
+ ".class, f";
sb.append("\t\tif (Ray.Parameters().remoteLambda()) {\n");
if (Rcount == 1) {
sb.append("\t\t\treturn Ray.internal().call(null, ").append(labmdaUse).append(", 1")
.append(parameterUse).append(").objs[0];")
.append("\n");
} else if (Rcount == 0) {
sb.append("\t\t\treturn Ray.internal().callWithReturnLabels(null, ")
.append(labmdaUse).append(", returnids").append(parameterUse).append(");")
.append("\n");
} else if (Rcount < 0) {
sb.append("\t\t\treturn Ray.internal().callWithReturnIndices(null, ")
.append(labmdaUse).append(", returnCount").append(parameterUse).append(");")
.append("\n");
} else {
sb.append("\t\t\treturn new RayObjects").append(Rcount)
.append("(Ray.internal().call(null, ").append(labmdaUse).append(", ").append(Rcount)
.append(parameterUse).append(").objs);")
.append("\n");
}
sb.append("\t\t} else {\n");
if (Rcount == 1) {
sb.append("\t\t\treturn Ray.internal().call(null, () -> f.apply(").append(nulls)
.append("), 1").append(parameterUse).append(").objs[0];")
.append("\n");
} else if (Rcount == 0) {
sb.append("\t\t\treturn Ray.internal().callWithReturnLabels(null, () -> f.apply(")
.append(nulls).append("), returnids").append(parameterUse).append(");")
.append("\n");
} else if (Rcount < 0) {
sb.append("\t\t\treturn Ray.internal().callWithReturnIndices(null, () -> f.apply(")
.append(nulls).append("), returnCount").append(parameterUse).append(");")
.append("\n");
} else {
sb.append("\t\t\treturn new RayObjects").append(Rcount)
.append("(Ray.internal().call(null, () -> f.apply(").append(nulls).append("), ")
.append(Rcount).append(parameterUse).append(").objs);")
.append("\n");
}
sb.append("\t\t}\n");
sb.append("\t}\n");
return sb.toString();
}
private static Set<Set<Integer>> whichTisFutureComposition(int Tcount) {
Set<Set<Integer>> ret = new HashSet<>();
Set<Integer> N = new HashSet<>();
for (int k = 0; k < Tcount; k++) {
N.add(k);
}
for (int k = 0; k <= Tcount; k++) {
ret.addAll(CNn(N, k));
}
return ret;
}
//pick n numbers in N
private static Set<Set<Integer>> CNn(Set<Integer> N, int n) {
C c = new C();
for (int k = 0; k < n; k++) {
c.mul(N);
}
return c.v;
}
static class C {
Set<Set<Integer>> v;
public C() {
v = new HashSet<>();
v.add(new HashSet<>());
}
void mul(Set<Integer> ns) {
Set<Set<Integer>> ret = new HashSet<>();
for (int n : ns) {
ret.addAll(mul(n));
}
this.v = ret;
}
Set<Set<Integer>> mul(int n) {
Set<Set<Integer>> ret = new HashSet<>();
for (Set<Integer> s : v) {
if (s.contains(n)) {
continue;
}
Set<Integer> ns = new HashSet<>(s);
ns.add(n);
ret.add(ns);
}
return ret;
}
}
}
@@ -0,0 +1,139 @@
package org.ray.util.generator;
import java.util.Set;
/**
* Share util for generators
*/
public class Share {
public static final int MAX_T = 6;
public static final int MAX_R = 4;
/**
* T0, T1, T2, T3, R
*/
public static String buildClassDeclare(int Tcount, int Rcount) {
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Tcount; k++) {
sb.append("T").append(k).append(", ");
}
if (Rcount == 0) {
sb.append("R, RID");
} else if (Rcount < 0) {
assert (Rcount == -1);
sb.append("R");
} else {
for (int k = 0; k < Rcount; k++) {
sb.append("R").append(k).append(", ");
}
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* T0 t0, T1 t1, T2 t2, T3 t3
*/
public static String buildParameter(int Tcount, String TR, Set<Integer> whichTisFuture) {
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Tcount; k++) {
sb.append(whichTisFuture != null && whichTisFuture.contains(k)
? "RayObject<" + (TR + k) + ">" : (TR + k)).append(" ").append(TR.toLowerCase())
.append(k).append(", ");
}
if (Tcount > 0) {
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* t0, t1, t2
*/
public static String buildParameterUse(int Tcount, String TR) {
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Tcount; k++) {
sb.append(TR.toLowerCase()).append(k).append(", ");
}
if (Tcount > 0) {
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
public static String buildParameterUse2(int Tcount, int startIndex, String TR, String pre,
String post) {
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Tcount; k++) {
sb.append("(").append(TR).append(k).append(")").append(pre).append(k + startIndex)
.append(post).append(", ");
}
if (Tcount > 0) {
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* MultipleReturns2<R0, R1> apply(); R0
*/
public static String buildFuncReturn(int Rcount) {
if (Rcount == 0) {
return "Map<RID, R>";
} else if (Rcount < 0) {
assert (-1 == Rcount);
return "List<R>";
}
if (Rcount == 1) {
return "R0";
}
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Rcount; k++) {
sb.append("R").append(k).append(", ");
}
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
return "MultipleReturns" + Rcount + "<" + sb.toString() + ">";
}
/**
*/
public static String buildRpcReturn(int Rcount) {
if (Rcount == 0) {
return "RayMap<RID, R>";
} else if (Rcount < 0) {
assert (Rcount == -1);
return "RayList<R>";
}
if (Rcount == 1) {
return "RayObject<R0>";
}
StringBuilder sb = new StringBuilder();
for (int k = 0; k < Rcount; k++) {
sb.append("R").append(k).append(", ");
}
sb.deleteCharAt(sb.length() - 1);
sb.deleteCharAt(sb.length() - 1);
return "RayObjects" + Rcount + "<" + sb.toString() + ">";
}
public static String buildRepeat(String toRepeat, int count) {
StringBuilder ret = new StringBuilder();
for (int k = 0; k < count; k++) {
ret.append(toRepeat).append(", ");
}
if (count > 0) {
ret.deleteCharAt(ret.length() - 1);
ret.deleteCharAt(ret.length() - 1);
}
return ret.toString();
}
}
@@ -0,0 +1,46 @@
package org.ray.util.logger;
import org.apache.log4j.Logger;
/**
* A logger which prints output to console
*/
public class ConsoleLogger extends Logger {
final Logger realLogger;
protected ConsoleLogger(String name, Logger realLogger) {
super(name);
this.realLogger = realLogger;
}
@Override
public void info(Object log) {
realLogger.info("(" + this.getName() + ") " + log);
}
@Override
public void warn(Object log) {
realLogger.warn("(" + this.getName() + ") " + log);
}
@Override
public void warn(Object log, Throwable e) {
realLogger.warn("(" + this.getName() + ") " + log, e);
}
@Override
public void debug(Object log) {
realLogger.debug("(" + this.getName() + ") " + log);
}
@Override
public void error(Object log) {
realLogger.error("(" + this.getName() + ") " + log);
}
@Override
public void error(Object log, Throwable e) {
realLogger.error("(" + this.getName() + ") " + log, e);
}
}
@@ -0,0 +1,260 @@
package org.ray.util.logger;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import org.ray.util.CommonUtil;
/**
* Dynamic logger without properties configuration file
*/
public class DynamicLog {
static final ThreadLocal<String> PREFIX = new ThreadLocal<>();
private static LogLevel logLevel = LogLevel.DEBUG;
private static Boolean logLevelSetFlag = false;
/**
* set the context prefix for all logs
*/
public static void setContextPrefix(String prefix) {
PREFIX.set(prefix);
}
public static String getContextPrefix() {
return PREFIX.get();
}
/**
* set the level for all logs
*/
public static void setLogLevel(String level) {
if (logLevelSetFlag) { /* one shot, avoid the risk of multithreading */
return;
}
logLevelSetFlag = true;
logLevel = LogLevel.of(level);
}
private static LogLevel getenumLogLevel() {
return logLevel;
}
@Override
public String toString() {
return this.getKey();
}
@Override
public boolean equals(Object o) {
return this.toString().equals(o.toString());
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
private String wrap(String level, String log) {
StackTraceElement stes[] = Thread.currentThread().getStackTrace();
String ret = "[" + level + "]" + "[" + stes[3].getFileName() + ":" + stes[3].getLineNumber()
+ "] - " + (log == null ? "" : log);
String prefix = PREFIX.get();
if (prefix != null) {
ret = "[" + prefix + "]" + ret;
}
return ret;
}
public void debug(String log) {
if (!getenumLogLevel().needLog(LogLevel.DEBUG)) {
return;
}
log = wrap("debug", log);
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.debug(log);
}
}
public void info(String log) {
if (!getenumLogLevel().needLog(LogLevel.INFO)) {
return;
}
log = wrap("info", log);
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.info(log);
}
}
public void warn(String log) {
if (!getenumLogLevel().needLog(LogLevel.WARN)) {
return;
}
log = wrap("warn", log);
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.warn(log);
}
}
public void warn(String log, Throwable e) {
if (!getenumLogLevel().needLog(LogLevel.WARN)) {
return;
}
log = wrap("warn", log);
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.warn(log, e);
}
}
public void error(String log) {
if (!getenumLogLevel().needLog(LogLevel.ERROR)) {
return;
}
log = wrap("error", log);
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.error(log);
}
}
public void error(String log, Throwable e) {
if (!getenumLogLevel().needLog(LogLevel.ERROR)) {
return;
}
log = wrap("error", log);
if (e == null) {
error(log);
return;
}
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.error(log, e);
}
}
public void error(Throwable e) {
if (!getenumLogLevel().needLog(LogLevel.ERROR)) {
return;
}
String log = wrap("error", e == null ? null : e.getMessage());
if (e == null) {
error(log);
return;
}
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
logger.error(log, e);
}
}
//statistic for sampling
private static class SampleStatis {
int total;
public boolean gamble() {
int randomRange;
if (total < 100) {
randomRange = 1;
} else if (total < 1000) {
randomRange = 1000;
} else if (total < 100000) {
randomRange = 10000;
} else if (total < 1000000) {
randomRange = 100000;
} else {
total = 0;
randomRange = 1;
}
if (CommonUtil.getRandom(randomRange) == 0) {
total++;
return true;
} else {
total++;
return false;
}
}
}
private static Map<String/*Samplekey*/, SampleStatis> sampleStatis = new ConcurrentHashMap<>();
/**
* Print sample error log
*/
public boolean sampleError(Object sampleKeyO, String log, Throwable e) {
String sampleKey = sampleKeyO.toString();
try {
SampleStatis ss = sampleStatis.computeIfAbsent(sampleKey, k -> new SampleStatis());
if (ss.gamble()) {
Logger loggers[] = DynamicLogManager.getLogs(this);
for (Logger logger : loggers) {
if (e != null) {
logger.error("[" + sampleKey + "] - " + log, e);
} else {
logger.error("[" + sampleKey + "] - " + log);
}
}
return true;
} else {
return false;
}
} finally {
if (sampleStatis.size() > 100000) {
sampleStatis = new ConcurrentHashMap<>();
}
}
}
private final String key;
private DynamicLog(String key) {
this.key = key;
}
public String getKey() {
return this.key;
}
public String getDefaultLogFileName() {
return this.key + ".log";
}
public static DynamicLog registerName(String name) {
return DynamicLogNameRegister.registerName(name);
}
public static Collection<DynamicLog> values() {
return DynamicLogNameRegister.names.values();
}
public static class DynamicLogNameRegister {
static final Map<String, DynamicLog> names = new ConcurrentHashMap<>();
public static DynamicLog registerName(String name) {
DynamicLog ret = names.get(name);
if (ret != null) {
return ret;
}
synchronized (names) {
ret = names.get(name);
if (ret != null) {
return ret;
}
ret = new DynamicLog(name);
names.put(name, ret);
return ret;
}
}
}
}
@@ -0,0 +1,161 @@
package org.ray.util.logger;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.ray.util.SystemUtil;
/**
* Manager for dynamic loggers
*/
public class DynamicLogManager {
//whether to print the log on std(ie. console)
public static boolean printOnStd = false;
//the root directory of log files
public static String logsDir;
public static String logsSuffix;
public static Level level = Level.DEBUG; //Level.INFO;
/** */
private static final int LOG_CACHE_SIZE = 32 * 1024;
protected final static String DAY_DATE_PATTERN = "'.'yyyy-MM-dd";
// private final static String HOUR_DATE_PATTERN = "'.'yyyy-MM-dd_HH";
// private final static String GBK = "GBK";
private final static String DAILY_APPENDER_NAME = "_DAILY_APPENDER_NAME";
// private final static String CONSOLE_APPENDER_NAME = "_CONSOLE_APPENDER_NAME";
private final static String LAYOUT_PATTERN = "%d [%t]%m%n";
private static final ConcurrentHashMap<DynamicLog, Logger> loggers = new ConcurrentHashMap<>();
private static int MAX_FILE_NUM = 10;
private static String MAX_FILE_SIZE = "500MB";
private static boolean initFinished = false;
/**
* init from system properties
* -DlogOutput=console/file_path
* if file_path contains *pid*, it will be replaced with real PID of this JAVA process
* if file_path contains *pid_suffix*, all log file will append the suffix -> xxx-pid.log
*/
static {
String logOutput = System.getProperty("logOutput");
if (null == logOutput
|| logOutput.equalsIgnoreCase("console")
|| logOutput.equalsIgnoreCase("std")
|| logOutput.equals("")) {
DynamicLogManager.printOnStd = true;
System.out.println("config log output as std");
} else {
if (logOutput.contains("*pid*")) {
logOutput = logOutput.replaceAll("\\*pid\\*", String.valueOf(SystemUtil.pid()));
}
if (logOutput.contains("*pid_suffix*")) {
logOutput = logOutput.replaceAll("\\*pid_suffix\\*", "");
if (logOutput.endsWith("/")) {
logOutput = logOutput.substring(0, logOutput.length() - 1);
}
DynamicLogManager.logsSuffix = String.valueOf(SystemUtil.pid());
}
System.out.println("config log output as " + logOutput);
DynamicLogManager.logsDir = logOutput;
}
String logLevel = System.getProperty("logLevel");
if (logLevel != null && logLevel.equals("debug")) {
level = Level.DEBUG;
}
}
public static synchronized void init(int maxFileNum, String maxFileSize) {
if (initFinished) {
return;
}
initFinished = true;
System.out.println(
"DynamicLogManager init with maxFileNum:" + maxFileNum + " maxFileSize:" + maxFileSize);
if (loggers.size() > 0) {
System.err
.println("already have logger be maked before init log file system, please check it");
}
MAX_FILE_NUM = maxFileNum;
MAX_FILE_SIZE = maxFileSize;
}
public static Logger[] getLogs(DynamicLog dynLog) {
Logger logger = loggers.get(dynLog);
if (logger == null) {
synchronized (loggers) {
logger = loggers.get(dynLog);
if (logger == null) {
logger = initLogger(dynLog);
}
}
}
return new Logger[]{logger};
}
private static Logger initLogger(DynamicLog dynLog) {
if (printOnStd) {
Logger reallogger = Logger.getLogger(dynLog.getKey());
ConsoleLogger logger = new ConsoleLogger(dynLog.getKey(), reallogger);
PatternLayout layout = new PatternLayout(LAYOUT_PATTERN);
ConsoleAppender appender = new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT);
reallogger.removeAllAppenders();
reallogger.addAppender(appender);
reallogger.setLevel(level);
reallogger.setAdditivity(false);
loggers.putIfAbsent(dynLog, logger);
return logger;
} else {
Logger logger = makeLogger(dynLog.getKey(), dynLog.getDefaultLogFileName());
loggers.putIfAbsent(dynLog, logger);
return logger;
}
}
protected static Logger makeLogger(String loggerName, String filename) {
Logger logger = Logger.getLogger(loggerName);
PatternLayout layout = new PatternLayout(LAYOUT_PATTERN);
File dir = new File(logsDir);
if (!dir.exists()) {
dir.mkdirs();
}
String logFileName = logsDir + "/" + filename;
if (logsSuffix != null) {
logFileName = logFileName.substring(0, logFileName.length() - 4) + "-" + logsSuffix
+ ".log";
}
System.out.println("new_log_path:" + logFileName);
RollingFileAppender appender;
try {
appender = new TimedFlushDailyRollingFileAppender(layout, logFileName);
appender.setAppend(true);
appender.setEncoding("UTF-8");
appender.setName(DAILY_APPENDER_NAME);
appender.setBufferSize(LOG_CACHE_SIZE);
appender.setBufferedIO(true);
appender.setImmediateFlush(false);
appender.setMaxBackupIndex(MAX_FILE_NUM);
appender.setMaxFileSize(MAX_FILE_SIZE);
appender.activateOptions();
} catch (IOException e) {
throw new RuntimeException(e);
}
logger.removeAllAppenders();
logger.addAppender(appender);
logger.setLevel(level);
logger.setAdditivity(false);
return logger;
}
}
@@ -0,0 +1,29 @@
package org.ray.util.logger;
public enum LogLevel {
ERROR("error", 0),
WARN("warn", 1),
INFO("info", 2),
DEBUG("debug", 3);
private final String name;
private final int index;
LogLevel(String name, int index) {
this.name = name;
this.index = index;
}
public static LogLevel of(String name) {
for (LogLevel level : values()) {
if (level.name.equals(name)) {
return level;
}
}
return null;
}
public Boolean needLog(LogLevel level) {
return level.index <= this.index;
}
}
@@ -0,0 +1,17 @@
package org.ray.util.logger;
/**
* Dynamic loggers in Ray
*/
public class RayLog {
/**
* for ray itself
*/
public static final DynamicLog core = DynamicLog.registerName("core");
/**
* for ray's app's log
*/
public static DynamicLog rapp = core; //DynamicLog.registerName("rapp");
}
@@ -0,0 +1,68 @@
package org.ray.util.logger;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Layout;
import org.apache.log4j.RollingFileAppender;
/**
* Normal log appender
*/
public class TimedFlushDailyRollingFileAppender extends RollingFileAppender {
private final static Set<TimedFlushDailyRollingFileAppender> all = new HashSet<>();
public TimedFlushDailyRollingFileAppender() {
super();
synchronized (all) {
all.add(this);
}
}
public TimedFlushDailyRollingFileAppender(Layout layout, String filename) throws IOException {
super(layout, filename);
synchronized (all) {
all.add(this);
}
}
static {
new TimedFlushLogThread().start();
}
private void flush() {
try {
if (!checkEntryConditions()) {
return;
}
qw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
private static class TimedFlushLogThread extends Thread {
public TimedFlushLogThread() {
super();
setName("TimedFlushLogThread");
setDaemon(true);
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (all) {
for (TimedFlushDailyRollingFileAppender appender : all) {
appender.flush();
}
}
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.ray.parent</groupId>
<artifactId>ray-superpom</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.ray</groupId>
<artifactId>ray-example</artifactId>
<name>java example for ray</name>
<description>java example for ray</description>
<url></url>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-runtime-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-runtime-native</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-runtime-dev</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.ray</groupId>
<artifactId>ray-hook</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<environmentVariables>
<RAY_CONFIG>${basedir}/../ray.config.ini</RAY_CONFIG>
</environmentVariables>
<argLine>-ea
-Djava.library.path=${basedir}/../../build/src/plasma:${basedir}/../../build/src/local_scheduler
-noverify
-DlogOutput=console
</argLine>
<testSourceDirectory>${basedir}/src/main/java/</testSourceDirectory>
<testClassesDirectory>${project.build.directory}/classes/</testClassesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Some files were not shown because too many files have changed in this diff Show More