
oracle.kv.impl.admin.plan.TaskRun Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oracle-nosql-server Show documentation
Show all versions of oracle-nosql-server Show documentation
NoSQL Database Server - supplies build and runtime support for the server (store) side of the Oracle NoSQL Database.
The newest version!
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.impl.admin.plan;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.kv.impl.admin.IllegalCommandException;
import oracle.kv.impl.admin.plan.ExecutionState.ExceptionTransfer;
import oracle.kv.impl.admin.plan.task.Task;
import oracle.kv.impl.util.FormatUtils;
import oracle.kv.impl.util.server.LoggerUtils;
import oracle.kv.util.ErrorMessage;
import com.sleepycat.persist.model.Persistent;
/**
* Captures status of a single task execution. Tasks may be executed repeatedly
* as the plan is re-executed.
*
* Note that any caller who modifies the TaskRun must synchronize against its
* owning plan. This coordinates between threads that are:
* - concurrently updating the different tasks, because of parallel task
* execution
* - PlanExecutor threads that are saving the plan instance to the persistent
* DPL store.
*
* Readers of the task may not necessarily need to synchronize on the plan. It
* may not be important that the reader get the latest task information, if
* it's only needed for logging and reporting.
*/
@Persistent(version=1)
public class TaskRun implements Serializable {
private static final long serialVersionUID = 1L;
private String taskName;
private long startTime;
private long endTime;
private Task.State state;
/*
* An identifier for the task, used to locate per-task status stored in the
* PlanRun.
*/
private int taskNum;
/*
* ExceptionTransfer packages a Throwable and an exception message. It
* is used to propagate the exception across thread boundaries, and also
* PlanWaiter, and need not be stored persistently.
*/
private transient ExceptionTransfer transfer;
private long cleanupStartTime;
private long cleanupEndTime;
private String cleanupFailure;
private Task task;
/*
* Task and details were added in AdminSchemaVersion 3, for plan status
* report support. CustomInfo holds key->value pairs that can be store
* metrics that pertain only to a particular type of task. See
* PartitionMigrationStatus for an example of how to encapsulate the
* information in the map, and its creation and extraction.
* Note that modifications of the details map, like all other modifications
* to the plan instance, must be synchronized on the plan instance.
*/
private Map details;
TaskRun(Task task, Logger logger, int taskNum) {
this.task = task;
/* To be compatible with versions before AdminSchemaVersion 3 */
this.taskName = task.getName();
setState(Task.State.RUNNING, logger);
startTime = System.currentTimeMillis();
this.taskNum = taskNum;
details = new HashMap<>();
}
/** For DPL */
public TaskRun() {
}
/**
* Change the status of this task. Should only be called when synchronized
* on the owning plan.
*
* @param newState the new status of this task.
*/
void setState(Task.State newState, Logger logger) {
if (state == null) {
logger.log(Level.FINE, "TaskRun {0} starting in {1}",
new Object[] {taskName, newState});
} else {
logger.log(Level.FINE, "TaskRun {0} transitioning from {1} to {2}",
new Object[] {taskName, state, newState});
/*
* An assertion against a state transition that should never
* happen.
*/
if ((state == Task.State.ERROR) &&
(newState != Task.State.ERROR)) {
throw new IllegalStateException
("Illegal transition from " + state + " to " +
newState + " for " + taskName);
}
}
state = newState;
endTime = System.currentTimeMillis();
}
/**
* Save a information about a task failure. Only call when synchronized on
* the owning plan. Note that failures can be detected from two types of
* threads: the thread executing the task and the PlanExecutor, when it is
* examining the future.
*/
void saveFailure(Plan plan,
Throwable t,
String problem,
ErrorMessage errorMsg,
String[] cleanupJobs,
Logger logger) {
transfer = ExceptionTransfer.newInstance(t, problem, errorMsg,
cleanupJobs);
if (t == null) {
logger.log(Level.WARNING,
"{0} of plan {1} ended in state {2} with {3}",
new Object[] {task, plan.getId(), state, problem});
} else if (t instanceof IllegalCommandException) {
logger.log(Level.INFO,
"{0} of plan {1} ended in state {2} with {3}",
new Object[] {task, plan.getId(),
state, t.getMessage()});
} else {
logger.log(Level.WARNING,
"{0} of plan {1} ended in state {2} with {3} {4}\n{5}",
new Object[] {task, plan.getId(), state, t, problem,
LoggerUtils.getStackTrace(t)});
}
}
ExceptionTransfer getTransfer() {
return transfer;
}
String getFailureDescription() {
final ExceptionTransfer et = getTransfer();
if (et == null) {
return null;
}
/* et.getStackTrace may return null */
if (et.getStackTrace() != null) {
return et.getDescription() + ": " + et.getStackTrace();
}
return et.getDescription();
}
@Override
public String toString() {
String ret = taskName + " [" + state + "]";
final String failure = getFailureDescription();
if (failure != null) {
ret += " " + failure;
}
if (cleanupStartTime != 0) {
ret += " cleanup started at " +
FormatUtils.formatDateAndTime(cleanupStartTime);
}
if (cleanupEndTime != 0) {
ret += " cleanup ended at " +
FormatUtils.formatDateAndTime(cleanupEndTime);
}
if (cleanupFailure != null) {
ret += "cleanup failure:" + cleanupFailure;
}
return ret;
}
String getTaskName() {
return taskName;
}
Task.State getState() {
return state;
}
int getTaskNum() {
return taskNum;
}
void cleanupStarted() {
cleanupStartTime = System.currentTimeMillis();
}
void cleanupEnded() {
cleanupEndTime = System.currentTimeMillis();
}
void saveCleanupFailure(String failureInfo) {
cleanupFailure = failureInfo;
}
long getStartTime() {
return startTime;
}
Task getTask() {
return task;
}
Map getDetails() {
return details;
}
long getEndTime() {
return endTime;
}
/*
* On upgrade, fill in these new fields.
*/
void upgradeToV3(int tnum, Task t) {
taskNum = tnum;
task = t;
}
/*
* Provide a customized display of task execution for this task, if it
* collected extra info, and supports such a display.
* @return null if there is no detailed information.
*/
public String displayTaskDetails(String displayPrefix) {
return task.displayExecutionDetails(details, displayPrefix);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy