Search in sources :

Example 1 with TaskContextMetadata

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;
}
Also used : TaskContextMetadata(org.dkpro.lab.task.TaskContextMetadata) TaskContext(org.dkpro.lab.engine.TaskContext)

Example 2 with TaskContextMetadata

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);
}
Also used : Task(org.dkpro.lab.task.Task) BatchTask(org.dkpro.lab.task.BatchTask) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) TaskContextMetadata(org.dkpro.lab.task.TaskContextMetadata) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashSet(java.util.HashSet) BatchTask(org.dkpro.lab.task.BatchTask) LinkedList(java.util.LinkedList) UnresolvedImportException(org.dkpro.lab.storage.UnresolvedImportException) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Example 3 with TaskContextMetadata

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);
        }
    }
}
Also used : Task(org.dkpro.lab.task.Task) BatchTask(org.dkpro.lab.task.BatchTask) BatchTask(org.dkpro.lab.task.BatchTask) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) UnresolvedImportException(org.dkpro.lab.storage.UnresolvedImportException) TaskContextMetadata(org.dkpro.lab.task.TaskContextMetadata) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 4 with TaskContextMetadata

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();
    }
}
Also used : TaskContextMetadata(org.dkpro.lab.task.TaskContextMetadata) InputStreamReader(java.io.InputStreamReader) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) BufferedReader(java.io.BufferedReader)

Example 5 with TaskContextMetadata

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;
}
Also used : TaskContextMetadata(org.dkpro.lab.task.TaskContextMetadata) PropertiesAdapter(org.dkpro.lab.storage.impl.PropertiesAdapter) HashMap(java.util.HashMap) URI(java.net.URI) StorageService(org.dkpro.lab.storage.StorageService)

Aggregations

TaskContextMetadata (org.dkpro.lab.task.TaskContextMetadata)15 File (java.io.File)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 StorageService (org.dkpro.lab.storage.StorageService)4 PropertiesAdapter (org.dkpro.lab.storage.impl.PropertiesAdapter)4 IOException (java.io.IOException)3 InputStream (java.io.InputStream)3 Map (java.util.Map)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 URI (java.net.URI)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 AnalysisEngineDescription (org.apache.uima.analysis_engine.AnalysisEngineDescription)2 TaskExecutionEngine (org.dkpro.lab.engine.TaskExecutionEngine)2 StreamReader (org.dkpro.lab.storage.StreamReader)2 UnresolvedImportException (org.dkpro.lab.storage.UnresolvedImportException)2 FileSystemStorageService (org.dkpro.lab.storage.filesystem.FileSystemStorageService)2 BatchTask (org.dkpro.lab.task.BatchTask)2