blob: 7fb66dcce75954ed0d6b7ef4acbfb34b8b0d191b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 University of Illinois All rights reserved. This program
* and the accompanying materials are made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Albert L. Rossi - design and implementation
******************************************************************************/
package org.eclipse.ptp.rm.jaxb.core.runnable.command;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.ptp.remote.core.IRemoteProcess;
import org.eclipse.ptp.rm.jaxb.core.ICommandJobStatus;
import org.eclipse.ptp.rm.jaxb.core.ICommandJobStreamMonitor;
import org.eclipse.ptp.rm.jaxb.core.ICommandJobStreamsProxy;
import org.eclipse.ptp.rm.jaxb.core.data.PropertyType;
import org.eclipse.ptp.rm.jaxb.core.variables.RMVariableMap;
import org.eclipse.ptp.rmsystem.IJobStatus;
/**
* Extension of the IJobStatus class to handle resource manager command jobs.
*
* @author arossi
*
*/
public class CommandJobStatus implements ICommandJobStatus {
private String jobId;
private ILaunchConfiguration launchConfig;
private String state;
private String stateDetail;
private ICommandJobStreamsProxy proxy;
private IRemoteProcess process;
private final RMVariableMap rmVarMap;
private boolean waitEnabled;
private long lastUpdateRequest;
public CommandJobStatus() {
jobId = null;
state = IJobStatus.UNDETERMINED;
rmVarMap = RMVariableMap.getActiveInstance();
waitEnabled = true;
lastUpdateRequest = 0;
}
/**
* @param jobId
* either internal UUID or resource-specific id
* @param state
*/
public CommandJobStatus(String jobId, String state) {
this.jobId = jobId;
setState(state);
rmVarMap = RMVariableMap.getActiveInstance();
waitEnabled = false;
}
/**
* Closes the proxy and calls destroy on the process. Used for interactive
* jobs cancellation.
*/
public synchronized void cancel() {
if (proxy != null) {
proxy.close();
}
if (process != null) {
process.destroy();
}
}
/**
* Notifies all callers of <code>waitForId</code> to exit wait.
*/
public void cancelWait() {
synchronized (this) {
waitEnabled = false;
notifyAll();
}
}
/**
* @return jobId either internal UUID or resource-specific id
*/
public synchronized String getJobId() {
return jobId;
}
public synchronized long getLastUpdateRequest() {
return lastUpdateRequest;
}
/**
* @return configuration used for this submission.
*/
public ILaunchConfiguration getLaunchConfiguration() {
return launchConfig;
}
/**
* @return state of the job (not of the submission process).
*/
public synchronized String getState() {
return state;
}
/**
* @return more specific state identifier.
*/
public synchronized String getStateDetail() {
return stateDetail;
}
/**
* Wrapper containing monitoring functionality for the associated output and
* error streams.
*/
public IStreamsProxy getStreamsProxy() {
return proxy;
}
/**
* @return whether a process object has been attached to this status object
* (in which case the submission is not through an asynchronous job
* scheduler).
*/
public boolean isInteractive() {
return process != null;
}
/**
* @param launchConfig
* configuration used for this submission.
*/
public void setLaunchConfig(ILaunchConfiguration launchConfig) {
this.launchConfig = launchConfig;
}
/**
* @param process
* object (used for interactive cancellation)
*/
public void setProcess(IRemoteProcess process) {
this.process = process;
}
/**
* We also immediately dereference any paths associated withthe proxy
* monitors by calling intialize, as the jobId property may not be in the
* environment after this initial call returns. We also start the monitors
* here, as tail -F will retry until the file appears.
*
* @param proxy
* Wrapper containing monitoring functionality for the associated
* output and error streams.
*/
public void setProxy(ICommandJobStreamsProxy proxy) {
this.proxy = proxy;
ICommandJobStreamMonitor m = (ICommandJobStreamMonitor) proxy.getOutputStreamMonitor();
if (m != null) {
m.initializeFilePath(jobId);
m.startMonitoring();
}
m = (ICommandJobStreamMonitor) proxy.getErrorStreamMonitor();
if (m != null) {
m.initializeFilePath(jobId);
m.startMonitoring();
}
}
/**
* @param state
* of the job (not of the submission process).
*/
public synchronized void setState(String state) {
if (UNDETERMINED.equals(state)) {
this.state = UNDETERMINED;
stateDetail = UNDETERMINED;
} else if (SUBMITTED.equals(state)) {
this.state = SUBMITTED;
stateDetail = SUBMITTED;
} else if (RUNNING.equals(state)) {
this.state = RUNNING;
stateDetail = RUNNING;
} else if (SUSPENDED.equals(state)) {
this.state = SUSPENDED;
stateDetail = SUSPENDED;
} else if (COMPLETED.equals(state)) {
this.state = COMPLETED;
stateDetail = COMPLETED;
} else if (QUEUED_ACTIVE.equals(state)) {
this.state = SUBMITTED;
stateDetail = QUEUED_ACTIVE;
} else if (SYSTEM_ON_HOLD.equals(state)) {
this.state = SUBMITTED;
stateDetail = SYSTEM_ON_HOLD;
} else if (USER_ON_HOLD.equals(state)) {
this.state = SUBMITTED;
stateDetail = USER_ON_HOLD;
} else if (USER_SYSTEM_ON_HOLD.equals(state)) {
this.state = SUBMITTED;
stateDetail = USER_SYSTEM_ON_HOLD;
} else if (SYSTEM_SUSPENDED.equals(state)) {
this.state = SUSPENDED;
stateDetail = SYSTEM_SUSPENDED;
} else if (USER_SUSPENDED.equals(state)) {
this.state = SUSPENDED;
stateDetail = USER_SUSPENDED;
} else if (USER_SYSTEM_SUSPENDED.equals(state)) {
this.state = SUSPENDED;
stateDetail = USER_SYSTEM_SUSPENDED;
} else if (FAILED.equals(state)) {
this.state = COMPLETED;
stateDetail = FAILED;
}
}
/**
* @param time
* in milliseconds of last update request issued to remote
* resource
*/
public synchronized void setUpdateRequestTime(long update) {
lastUpdateRequest = update;
}
/**
* Wait until the jobId has been set on the job id property in the
* environment.
*
* @param uuid
* key for the property containing as its name the
* resource-specific jobId and as its value its initial state
* (SUBMITTED)
*/
public void waitForJobId(String uuid) {
synchronized (this) {
while (waitEnabled && jobId == null) {
try {
wait(1000);
} catch (InterruptedException ignored) {
}
PropertyType p = (PropertyType) rmVarMap.get(uuid);
if (p != null) {
jobId = p.getName();
String v = (String) p.getValue();
if (v != null) {
state = v;
}
}
}
}
}
}