From fd3c703e5a31b4194ce32a8ef651bc13a3d03cf1 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 27 Jan 2015 15:48:22 +0100 Subject: Make taskmanager an instance, add callback for finished jobs, improve parent dependency handling --- .../org/openslx/taskmanager/api/AbstractTask.java | 65 ++++++++++++++-------- .../openslx/taskmanager/api/FinishCallback.java | 11 ++++ .../org/openslx/taskmanager/api/TaskStatus.java | 4 +- 3 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 api/src/main/java/org/openslx/taskmanager/api/FinishCallback.java (limited to 'api') diff --git a/api/src/main/java/org/openslx/taskmanager/api/AbstractTask.java b/api/src/main/java/org/openslx/taskmanager/api/AbstractTask.java index cc837ba..a1c81e8 100644 --- a/api/src/main/java/org/openslx/taskmanager/api/AbstractTask.java +++ b/api/src/main/java/org/openslx/taskmanager/api/AbstractTask.java @@ -21,19 +21,19 @@ public abstract class AbstractTask implements Runnable * The id of the task instance. */ @Expose - private String id = null; + private volatile String id = null; /** * Parent task. This task won't be started as long as the parent task currently * waiting for execution or is being executed. Otherwise this task is available for execution. * Note that MAX_INSTANCES is still being taken into account. Set to null to ignore. */ @Expose - private String parentTask = null; + private volatile String parentTask = null; /** * If the parent task failed to execute, don't run this task and fail immediately. */ @Expose - private boolean failOnParentFail = true; + private volatile boolean failOnParentFail = true; /* * Variables we're working with - these should never be set from incoming (json) data @@ -57,11 +57,16 @@ public abstract class AbstractTask implements Runnable /** * Status of Task */ - private TaskStatus status = TaskStatus.ts_waiting; + private volatile TaskStatus status = TaskStatus.ts_waiting; /** * Reference to parent task */ - private AbstractTask parent = null; + private volatile AbstractTask parent = null; + /** + * Reference to "owner" so we can tell it to check for more + * work when we're done. + */ + private volatile FinishCallback finishCallback = null; /** * Default constructor which should not be overridden @@ -79,12 +84,24 @@ public abstract class AbstractTask implements Runnable * Initialize the task; method used by the {@link Taskmanager}. * Put your own initialization code in initTask() */ - public final boolean init( AbstractTask parent ) + public final boolean init( AbstractTask parent, FinishCallback finishCallback ) { if ( this.initDone ) { LOG.fatal( "init() called twice on " + this.getClass().getSimpleName() ); System.exit( 1 ); } + if ( this.parentTask != null && this.parentTask.isEmpty() ) + this.parentTask = null; + if ( this.parentTask != null && parent == null ) { + if ( this.failOnParentFail ) { + this.status = new TaskStatus( StatusCode.PARENT_FAILED, this.id ); + return false; + } + this.parentTask = null; + } + if ( this.parentTask == null && parent != null ) + parent = null; + this.finishCallback = finishCallback; this.parent = parent; this.status = new TaskStatus( StatusCode.TASK_WAITING, this.id ); this.initDone = true; @@ -116,6 +133,19 @@ public abstract class AbstractTask implements Runnable */ protected abstract boolean execute(); + /** + * This is called when a client requests the status of this task. In case you + * want to return complex structures like Lists, which are not thread safe, you + * might want to keep that list outside the status class you return, and only + * create a copy of it for the status class in this function. + * If you only return more or less atomic data, you don't need to override + * this function + */ + protected void updateStatus() + { + + } + /* * Final methods */ @@ -126,7 +156,7 @@ public abstract class AbstractTask implements Runnable * @return id of parent task, null if no parent set * */ - public String getParentTaskId() + public final String getParentTaskId() { return this.parentTask; } @@ -151,7 +181,7 @@ public abstract class AbstractTask implements Runnable */ public final TaskStatus getStatus() { - if ( this.initDone && this.parentTask != null ) { + if ( this.initDone && this.parent != null ) { final StatusCode parentStatus = parent.getStatusCode(); switch ( parentStatus ) { case DUPLICATE_ID: @@ -160,8 +190,10 @@ public abstract class AbstractTask implements Runnable case NO_SUCH_CONSTRUCTOR: case PARENT_FAILED: case TASK_ERROR: - if ( this.failOnParentFail ) + if ( this.failOnParentFail ) { this.status.statusCode = StatusCode.PARENT_FAILED; + LOG.debug( "Parent " + this.parentTask + " of " + this.id + " failed." ); + } this.parentTask = null; break; default: @@ -267,18 +299,7 @@ public abstract class AbstractTask implements Runnable } else { this.status.statusCode = StatusCode.TASK_ERROR; } - } - - /** - * This is called when a client requests the status of this task. In case you - * want to return complex structures like Lists, which are not thread safe, you - * might want to keep that list outside the status class you return, and only - * create a copy of it for the status class in this function. - * If you only return more or less atomic data, you don't need to override - * this function - */ - protected void updateStatus() - { - + if ( this.finishCallback != null ) + this.finishCallback.taskFinished(); } } diff --git a/api/src/main/java/org/openslx/taskmanager/api/FinishCallback.java b/api/src/main/java/org/openslx/taskmanager/api/FinishCallback.java new file mode 100644 index 0000000..a265595 --- /dev/null +++ b/api/src/main/java/org/openslx/taskmanager/api/FinishCallback.java @@ -0,0 +1,11 @@ +package org.openslx.taskmanager.api; + +public interface FinishCallback +{ + + /** + * Called by a task after execution finished or failed. + */ + public void taskFinished(); + +} diff --git a/api/src/main/java/org/openslx/taskmanager/api/TaskStatus.java b/api/src/main/java/org/openslx/taskmanager/api/TaskStatus.java index f01ccc4..0aa9ef7 100644 --- a/api/src/main/java/org/openslx/taskmanager/api/TaskStatus.java +++ b/api/src/main/java/org/openslx/taskmanager/api/TaskStatus.java @@ -26,11 +26,11 @@ public final class TaskStatus /** * Overall status of the task. Only set by base methods of the AbstractTask class. */ - protected StatusCode statusCode; + protected volatile StatusCode statusCode; /** * Custom data a task might want to return on status requests. */ - private Object data = null; + private volatile Object data = null; @SuppressWarnings( "unused" ) private final String id; -- cgit v1.2.3-55-g7522