use of org.dkpro.lab.task.TaskContextMetadata in project dkpro-lab by dkpro.
the class DefaultTaskContextFactory method createContext.
@Override
public TaskContext createContext(Task aConfiguration) {
TaskContextMetadata metadata = new TaskContextMetadata();
metadata.setId(nextId(aConfiguration));
metadata.setType(aConfiguration.getType());
metadata.setImports(aConfiguration.getImports());
TaskContext ctx = createContext(metadata);
resolveImports(ctx);
registerContext(ctx);
return ctx;
}
use of org.dkpro.lab.task.TaskContextMetadata in project dkpro-lab by dkpro.
the class MultiThreadBatchTaskEngine method executeConfiguration.
@Override
protected void executeConfiguration(BatchTask aConfiguration, TaskContext aContext, Map<String, Object> aConfig, Set<String> aExecutedSubtasks) throws ExecutionException, LifeCycleException {
if (log.isTraceEnabled()) {
// Show all subtasks executed so far
for (String est : aExecutedSubtasks) {
log.trace("-- Already executed: " + est);
}
}
// Set up initial scope used by sub-batch-tasks using the inherited scope. The scope is
// extended as the subtasks of this batch are executed with the present configuration.
// FIXME: That means that sub-batch-tasks in two different configurations cannot see
// each other. Is that intended? Mind that the "executedSubtasks" set is intentionally
// maintained *across* configurations, so maybe the scope should also be maintained
// *across* configurations? - REC 2014-06-15
Set<String> scope = new HashSet<>();
if (aConfiguration.getScope() != null) {
scope.addAll(aConfiguration.getScope());
}
// Configure subtasks
for (Task task : aConfiguration.getTasks()) {
// Now the setup is complete
aContext.getLifeCycleManager().configure(aContext, task, aConfig);
}
Queue<Task> queue = new LinkedList<>(aConfiguration.getTasks());
// keeps track of the execution threads;
// TODO MW: do we really need this or can we work with the futures list only?
Map<Task, ExecutionThread> threads = new HashMap<>();
// keeps track of submitted Futures and their associated tasks
Map<Future<?>, Task> futures = new HashMap<Future<?>, Task>();
// will be instantiated with all exceptions from current loop
ConcurrentMap<Task, Throwable> exceptionsFromLastLoop = null;
ConcurrentMap<Task, Throwable> exceptionsFromCurrentLoop = new ConcurrentHashMap<>();
int outerLoopCounter = 0;
// main loop
do {
outerLoopCounter++;
threads.clear();
futures.clear();
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
// set the exceptions from the last loop
exceptionsFromLastLoop = new ConcurrentHashMap<>(exceptionsFromCurrentLoop);
// Fix MW: Clear exceptionsFromCurrentLoop; otherwise the loop with run at most twice.
exceptionsFromCurrentLoop.clear();
// process all tasks from the queue
while (!queue.isEmpty()) {
Task task = queue.poll();
TaskContextMetadata execution = getExistingExecution(aConfiguration, aContext, task, aConfig, aExecutedSubtasks);
// does already exist ...
if (execution == null) {
// ... otherwise execute it with the present configuration
log.info("Executing task [" + task.getType() + "]");
// set scope here so that the inherited scopes are considered
if (task instanceof BatchTask) {
((BatchTask) task).setScope(scope);
}
ExecutionThread thread = new ExecutionThread(aContext, task, aConfig, aExecutedSubtasks);
threads.put(task, thread);
futures.put(executor.submit(thread), task);
} else {
log.debug("Using existing execution [" + execution.getId() + "]");
// Record new/existing execution
aExecutedSubtasks.add(execution.getId());
scope.add(execution.getId());
}
}
// try and get results from all futures to check for failed executions
for (Map.Entry<Future<?>, Task> entry : futures.entrySet()) {
try {
entry.getKey().get();
} catch (java.util.concurrent.ExecutionException ex) {
Task task = entry.getValue();
// TODO MW: add a retry-counter here to prevent endless loops?
log.info("Task exec failed for [" + task.getType() + "]");
// record the failed task, so that it can be re-added to the queue
exceptionsFromCurrentLoop.put(task, ex);
} catch (InterruptedException ex) {
// thread interrupted, exit
throw new RuntimeException(ex);
}
}
log.debug("Calling shutdown");
executor.shutdown();
log.debug("All threads finished");
// collect the results
for (Map.Entry<Task, ExecutionThread> entry : threads.entrySet()) {
Task task = entry.getKey();
ExecutionThread thread = entry.getValue();
TaskContextMetadata execution = thread.getTaskContextMetadata();
// probably failed
if (execution == null) {
Throwable exception = exceptionsFromCurrentLoop.get(task);
if (!(exception instanceof UnresolvedImportException) && !(exception instanceof java.util.concurrent.ExecutionException)) {
throw new RuntimeException(exception);
}
exceptionsFromCurrentLoop.put(task, exception);
// re-add to the queue
queue.add(task);
} else {
// Record new/existing execution
aExecutedSubtasks.add(execution.getId());
scope.add(execution.getId());
}
}
} while (// finish if the same tasks failed again
!exceptionsFromCurrentLoop.keySet().equals(exceptionsFromLastLoop.keySet()));
if (!exceptionsFromCurrentLoop.isEmpty()) {
// collect all details
StringBuilder details = new StringBuilder();
for (Throwable throwable : exceptionsFromCurrentLoop.values()) {
details.append("\n -");
details.append(throwable.getMessage());
}
// we re-throw the first exception
Throwable next = exceptionsFromCurrentLoop.values().iterator().next();
if (next instanceof RuntimeException) {
throw (RuntimeException) next;
}
// otherwise wrap it
throw new RuntimeException(details.toString(), next);
}
log.info("MultiThreadBatchTask completed successfully. Total number of outer loop runs: " + outerLoopCounter);
}
use of org.dkpro.lab.task.TaskContextMetadata in project dkpro-lab by dkpro.
the class BatchTaskEngine method executeConfiguration.
/**
* Locate the latest task execution compatible with the given task configuration.
*
* @param aContext
* the context of the current batch task.
* @param aConfig
* the current parameter configuration.
* @param aExecutedSubtasks
* already executed subtasks.
*/
protected void executeConfiguration(BatchTask aConfiguration, TaskContext aContext, Map<String, Object> aConfig, Set<String> aExecutedSubtasks) throws ExecutionException, LifeCycleException {
if (log.isTraceEnabled()) {
// Show all subtasks executed so far
for (String est : aExecutedSubtasks) {
log.trace("-- Already executed: " + est);
}
}
// Set up initial scope used by sub-batch-tasks using the inherited scope. The scope is
// extended as the subtasks of this batch are executed with the present configuration.
// FIXME: That means that sub-batch-tasks in two different configurations cannot see
// each other. Is that intended? Mind that the "executedSubtasks" set is intentionally
// maintained *across* configurations, so maybe the scope should also be maintained
// *across* configurations? - REC 2014-06-15
Set<String> scope = new HashSet<String>();
if (aConfiguration.getScope() != null) {
scope.addAll(aConfiguration.getScope());
}
// Configure subtasks
for (Task task : aConfiguration.getTasks()) {
aContext.getLifeCycleManager().configure(aContext, task, aConfig);
}
Queue<Task> queue = new LinkedList<Task>(aConfiguration.getTasks());
Set<Task> loopDetection = new HashSet<Task>();
List<UnresolvedImportException> deferralReasons = new ArrayList<UnresolvedImportException>();
while (!queue.isEmpty()) {
Task task = queue.poll();
try {
// Check if a subtask execution compatible with the present configuration has
// does already exist ...
TaskContextMetadata execution = getExistingExecution(aConfiguration, aContext, task, aConfig, aExecutedSubtasks);
if (execution == null) {
// ... otherwise execute it with the present configuration
log.info("Executing task [" + task.getType() + "]");
// set scope here so that tasks added to scope in this loop are considered
if (task instanceof BatchTask) {
((BatchTask) task).setScope(scope);
}
execution = runNewExecution(aContext, task, aConfig, aExecutedSubtasks);
} else {
log.debug("Using existing execution [" + execution.getId() + "]");
}
// Record new/existing execution
aExecutedSubtasks.add(execution.getId());
scope.add(execution.getId());
loopDetection.clear();
deferralReasons.clear();
} catch (UnresolvedImportException e) {
// Add task back to queue
log.debug("Deferring execution of task [" + task.getType() + "]: " + e.getMessage());
queue.add(task);
// Detect endless loop
if (loopDetection.contains(task)) {
StringBuilder details = new StringBuilder();
for (UnresolvedImportException r : deferralReasons) {
details.append("\n -");
details.append(r.getMessage());
}
// needs to be executed first
throw new UnresolvedImportException(e, details.toString());
}
// Record failed execution
loopDetection.add(task);
deferralReasons.add(e);
}
}
}
use of org.dkpro.lab.task.TaskContextMetadata in project dkpro-lab by dkpro.
the class Lab method runAsking.
public String runAsking(Task aConfiguration) throws Exception {
boolean found;
TaskContextMetadata meta = null;
try {
meta = getStorageService().getLatestContext(aConfiguration.getType(), aConfiguration.getDescriminators());
found = true;
} catch (DataAccessResourceFailureException e) {
found = false;
}
boolean execute = true;
if (found) {
InputStreamReader converter = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(converter);
String line = "";
while (line != null) {
System.out.println("[" + aConfiguration.getType() + "] has already been executed in" + " this configuration. Do you wish to execute it again? (y/n)");
line = in.readLine().toLowerCase();
if ("y".equals(line)) {
execute = true;
break;
}
if ("n".equals(line)) {
execute = false;
break;
}
}
}
if (execute) {
return getTaskExecutionService().run(aConfiguration);
} else {
return meta.getId();
}
}
use of org.dkpro.lab.task.TaskContextMetadata in project dkpro-lab by dkpro.
the class TaskBase method getResolvedDescriminators.
@Override
public Map<String, String> getResolvedDescriminators(TaskContext aContext) {
StorageService storageService = aContext.getStorageService();
Map<String, String> descs = new HashMap<String, String>();
descs.putAll(getDescriminators());
// defined in this task
for (String rawUri : aContext.getMetadata().getImports().values()) {
URI uri = URI.create(rawUri);
if (isStaticImport(uri)) {
continue;
}
final TaskContextMetadata meta = aContext.resolve(uri);
Map<String, String> prerequisiteDiscriminators = storageService.retrieveBinary(meta.getId(), DISCRIMINATORS_KEY, new PropertiesAdapter()).getMap();
for (Entry<String, String> e : prerequisiteDiscriminators.entrySet()) {
if (descs.containsKey(e.getKey()) && !descs.get(e.getKey()).equals(e.getValue())) {
throw new IllegalStateException("Discriminator [" + e.getKey() + "] in task [" + getType() + "] conflicts with dependency [" + meta.getType() + "]");
}
descs.put(e.getKey(), e.getValue());
}
}
return descs;
}
Aggregations