package water.api.schemas3;
import water.*;
import water.api.API;
import water.api.schemas3.KeyV3.JobKeyV3;
import water.util.PojoUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
/** Schema for a single Job. */
public class JobV3 extends SchemaV3<Job, JobV3> {
// Input fields
@API(help="Job Key")
public JobKeyV3 key;
@API(help="Job description")
public String description;
// Output fields
@API(help="job status", direction=API.Direction.OUTPUT)
public String status;
@API(help="progress, from 0 to 1", direction=API.Direction.OUTPUT)
public float progress; // A number from 0 to 1
@API(help="current progress status description", direction=API.Direction.OUTPUT)
public String progress_msg;
@API(help="Start time", direction=API.Direction.OUTPUT)
public long start_time;
@API(help="Runtime in milliseconds", direction=API.Direction.OUTPUT)
public long msec;
@API(help="destination key", direction=API.Direction.INOUT)
public KeyV3 dest;
@API(help="exception", direction=API.Direction.OUTPUT)
public String [] warnings;
@API(help="exception", direction=API.Direction.OUTPUT)
public String exception;
@API(help="stacktrace", direction=API.Direction.OUTPUT)
public String stacktrace;
@API(help="ready for view", direction=API.Direction.OUTPUT)
public boolean ready_for_view;
//==========================
// Custom adapters go here
public JobV3() {}
public JobV3(Job impl) { super(impl); }
// Version&Schema-specific filling into the impl
@SuppressWarnings("unchecked")
@Override public Job createImpl( ) { throw H2O.fail(); } // Cannot make a new Job directly via REST
// Version&Schema-specific filling from the impl
@Override public JobV3 fillFromImpl( Job job ) {
if( job == null ) return this;
// Handle fields in subclasses:
PojoUtils.copyProperties(this, job, PojoUtils.FieldNaming.ORIGIN_HAS_UNDERSCORES);
PojoUtils.copyProperties(this, job, PojoUtils.FieldNaming.CONSISTENT); // TODO: make consistent and remove
key = new JobKeyV3(job._key);
description = job._description;
warnings = job.warns();
progress = job.progress();
progress_msg = job.progress_msg();
// Bogus status; Job no longer has these states, but we fake it for /3/Job poller's.
// Notice state "CREATED" no long exists and is never returned.
// Notice new state "CANCEL_PENDING".
if( job.isRunning() )
if( job.stop_requested() ) status = "CANCEL_PENDING";
else status = "RUNNING";
else
if( job.stop_requested() ) status = "CANCELLED";
else status = "DONE";
Throwable ex = job.ex();
if( ex != null ) status = "FAILED";
exception = ex == null ? null : ex.toString();
if (ex!=null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
stacktrace = sw.toString();
}
msec = job.msec();
ready_for_view = job.readyForView();
Keyed dest_type = (Keyed)TypeMap.theFreezable(job._typeid);
dest = job._result == null ? null : KeyV3.make(dest_type.makeSchema(),job._result);
return this;
}
//==========================
// Helper so Jobs can link to JobPoll
public static String link(Key key) { return "/Jobs/"+key; }
}