package com.asgow.ciel.executor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashSet;
import com.asgow.ciel.references.CielFuture;
import com.asgow.ciel.references.Reference;
import com.asgow.ciel.references.WritableReference;
import com.asgow.ciel.rpc.WorkerRpc;
import com.asgow.ciel.tasks.ConstantNumOutputsTask;
import com.asgow.ciel.tasks.FirstClassJavaTask;
import com.asgow.ciel.tasks.FirstClassJavaTaskInformation;
import com.asgow.ciel.tasks.SingleOutputTask;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public final class Ciel {
/**
* A convenience method for accessing the worker RPC bindings. This must
* be configured in the Java2Executor setup phase.
*/
public static WorkerRpc RPC = null;
/**
* This is the classloader used to load the user-supplied classes. Any
* reflective calls inside user-code should use this classloader.
*/
public static ClassLoader CLASSLOADER = null;
public static HashSet<URL> seenJars = new HashSet<URL>();
/**
* This is the array of references that comprise the classpath for this task. It
* is inherited when spawning further tasks.
*/
public static Reference[] jarLib = null;
/**
* This is the argument vector that may be supplied for externally-invoked tasks.
*/
public static String[] args = null;
/**
* The soft cache, for users to potentially persist useful objects derived of references.
*/
public static SoftCache softCache = null;
private static Charset CHARSET = Charset.forName("UTF-8");
public static void log(String logMessage) {
Ciel.RPC.log(logMessage);
}
public static Reference[] spawn(FirstClassJavaTask taskObject, String[] args, int numOutputs) throws IOException {
WritableReference objOut = Ciel.RPC.getNewObjectFilename("obj");
ObjectOutputStream oos = new ObjectOutputStream(objOut.open());
oos.writeObject(taskObject);
oos.close();
Reference objRef = objOut.getCompletedRef();
FirstClassJavaTaskInformation fcjti = new FirstClassJavaTaskInformation(objRef, Ciel.jarLib, args, numOutputs);
for (Reference dependency : taskObject.getDependencies()) {
if (dependency != null) {
fcjti.addDependency(dependency);
}
}
return Ciel.RPC.spawnTask(fcjti);
}
public static Reference[] spawn(Class<? extends FirstClassJavaTask> taskClass, String[] args, int numOutputs) {
FirstClassJavaTaskInformation fcjti = new FirstClassJavaTaskInformation(taskClass, Ciel.jarLib, args, numOutputs);
return Ciel.RPC.spawnTask(fcjti);
}
public static Reference[] spawn(ConstantNumOutputsTask taskObject) throws IOException {
return Ciel.spawn(taskObject, new String[0], taskObject.getNumOutputs());
}
public static <T> CielFuture<T> spawn(Class<? extends SingleOutputTask<T>> taskClass, String[] args) {
return new CielFuture<T>(Ciel.spawn(taskClass, args, 1)[0]);
}
public static <T> CielFuture<T> spawnSingle(SingleOutputTask<T> taskObject) throws IOException {
return new CielFuture<T>(Ciel.spawn(taskObject, null, 1)[0]);
}
public static void tailSpawn(FirstClassJavaTask taskObject) throws IOException {
Ciel.tailSpawn(taskObject, new String[0]);
}
public static void tailSpawn(FirstClassJavaTask taskObject, String[] args) throws IOException {
WritableReference objOut = Ciel.RPC.getNewObjectFilename("obj");
ObjectOutputStream oos = new ObjectOutputStream(objOut.open());
oos.writeObject(taskObject);
oos.close();
Reference objRef = objOut.getCompletedRef();
FirstClassJavaTaskInformation fcjti = new FirstClassJavaTaskInformation(objRef, Ciel.jarLib, args);
for (Reference dependency : taskObject.getDependencies()) {
if (dependency != null) {
fcjti.addDependency(dependency);
}
}
Ciel.RPC.tailSpawnTask(fcjti);
}
public static <T> void returnObject(T result) throws IOException {
WritableReference out = Ciel.RPC.getOutputFilename(0);
ObjectOutputStream oos = new ObjectOutputStream(out.open());
oos.writeObject(result);
oos.close();
}
public static void returnInt(int value) throws IOException {
Ciel.returnInt(value, 0);
}
public static void returnInt(int value, int index) throws IOException {
WritableReference retOut = Ciel.RPC.getOutputFilename(index);
ObjectOutputStream oos = new ObjectOutputStream(retOut.open());
oos.write(value);
oos.close();
}
public static void returnPlainString(String value) throws IOException {
Ciel.returnPlainString(value, 0);
}
public static void returnPlainString(String value, int index) throws IOException {
WritableReference retOut = Ciel.RPC.getOutputFilename(index);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(retOut.open(), Ciel.CHARSET));
pw.print(value);
pw.close();
}
public static void blockOn(Reference... refs) {
JsonArray deps = new JsonArray();
for (Reference ref : refs) {
deps.add(ref.toJson());
}
JsonObject args = new JsonObject();
args.addProperty("executor_name", "java2");
args.add("extra_dependencies", deps);
args.addProperty("is_fixed", true);
Ciel.RPC.tailSpawnRaw(args);
Ciel.RPC.exit(true);
Ciel.RPC.getFixedContinuationTask();
}
public static String stringOfRef(Reference ref) {
String filename = Ciel.RPC.getFilenameForReference(ref);
FileInputStream stream = null;
try {
stream = new FileInputStream(filename);
}
catch(FileNotFoundException e) {
// Can't happen
}
try {
byte[] buffer = new byte[1024];
StringBuilder builder = new StringBuilder();
int this_read;
while((this_read = stream.read(buffer)) != -1) {
String new_str = new String(buffer, 0, this_read);
builder.append(new_str);
}
stream.close();
return builder.toString();
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
public static Reference[] getRefsFromPackage(String key) {
Reference indexRef = Ciel.RPC.tryPackageLookup(key);
if (indexRef == null) {
return null;
}
JsonArray indexJsonArray = new JsonParser().parse(Ciel.stringOfRef(indexRef)).getAsJsonArray();
Reference[] ret = new Reference[indexJsonArray.size()];
for (int i = 0; i < ret.length; ++i) {
ret[i] = Reference.fromJson(indexJsonArray.get(i).getAsJsonObject());
}
return ret;
}
}