14
14
*/
15
15
package ubic .gemma .core .job .executor .common ;
16
16
17
+ import org .springframework .security .core .Authentication ;
17
18
import org .springframework .security .core .context .SecurityContextHolder ;
18
19
import ubic .gemma .core .job .TaskCommand ;
19
20
import ubic .gemma .core .job .TaskResult ;
@@ -31,10 +32,9 @@ public class ExecutingTask<T extends TaskResult> implements Callable<T> {
31
32
private final Task <T , ?> task ;
32
33
private final String taskId ;
33
34
private final TaskCommand taskCommand ;
35
+
34
36
// Does not survive serialization.
35
- private transient TaskLifecycleHandler statusCallback ;
36
- private transient ProgressUpdateAppender progressAppender ;
37
- private Throwable taskExecutionException ;
37
+ private transient TaskLifecycleHandler lifecycleHandler ;
38
38
39
39
public ExecutingTask ( Task <T , ?> task , TaskCommand taskCommand ) {
40
40
this .task = task ;
@@ -45,58 +45,72 @@ public ExecutingTask( Task<T, ?> task, TaskCommand taskCommand ) {
45
45
@ SuppressWarnings ("unchecked" )
46
46
@ Override
47
47
public final T call () {
48
- this .setup ();
49
- // From here we are running as user who submitted the task.
48
+ T result ;
49
+
50
+ if ( lifecycleHandler == null ) {
51
+ throw new IllegalStateException ( "No lifecycle handler has been configured for this executing task." );
52
+ }
53
+
54
+ lifecycleHandler .onStart ();
50
55
51
- statusCallback . onStart ();
56
+ Authentication previousAuthentication = SecurityContextHolder . getContext (). getAuthentication ();
52
57
53
- T result = null ;
54
- try {
58
+ try ( ProgressUpdateAppender .ProgressUpdateContext progressUpdateContext = new ProgressUpdateAppender .ProgressUpdateContext ( lifecycleHandler ::onProgress ) ) {
59
+ // From here we are running as user who submitted the task.
60
+ SecurityContextHolder .getContext ().setAuthentication ( taskCommand .getAuthentication () );
55
61
result = this .task .execute ();
56
62
} catch ( Throwable e ) {
57
- statusCallback .onFailure ( e );
58
- taskExecutionException = e ;
63
+ // result is an exception
64
+ result = ( T ) new TaskResult ( taskId );
65
+ result .setException ( e );
59
66
} finally {
60
- this .cleanup ();
67
+ // restore the previous security context
68
+ SecurityContextHolder .getContext ().setAuthentication ( previousAuthentication );
61
69
}
62
- // SecurityContext is cleared at this point.
63
70
64
- if ( taskExecutionException == null ) {
65
- statusCallback .onFinish ();
66
- return result ;
71
+ if ( result .getException () == null ) {
72
+ lifecycleHandler .onSuccess ();
73
+ } else {
74
+ lifecycleHandler .onFailure ( result .getException () );
67
75
}
68
- result = ( T ) new TaskResult ( taskId );
69
- result .setException ( taskExecutionException );
70
- return result ;
71
76
72
- }
77
+ lifecycleHandler . onComplete ();
73
78
74
- public void setProgressAppender ( ProgressUpdateAppender progressAppender ) {
75
- this .progressAppender = progressAppender ;
79
+ return result ;
76
80
}
77
81
78
- public void setStatusCallback ( TaskLifecycleHandler statusCallback ) {
79
- this .statusCallback = statusCallback ;
82
+ public void setLifecycleHandler ( TaskLifecycleHandler lifecycleHandler ) {
83
+ this .lifecycleHandler = lifecycleHandler ;
80
84
}
81
85
82
- private void cleanup () {
83
- SecurityContextHolder .clearContext ();
84
-
85
- progressAppender .tearDown ();
86
- }
86
+ // These hooks are used to update status of the running task.
87
+ public interface TaskLifecycleHandler {
87
88
88
- private void setup () {
89
- progressAppender .initialize ();
89
+ /**
90
+ * Whenever the task execution begins.
91
+ */
92
+ void onStart ();
90
93
91
- SecurityContextHolder .setContext ( taskCommand .getSecurityContext () );
92
- }
94
+ /**
95
+ * When progress is made on the task.
96
+ * @param message
97
+ */
98
+ void onProgress ( String message );
93
99
94
- // These hooks are used to update status of the running task.
95
- public interface TaskLifecycleHandler {
100
+ /**
101
+ * On failure.
102
+ * @param e
103
+ */
96
104
void onFailure ( Throwable e );
97
105
98
- void onFinish ();
106
+ /**
107
+ * On successful completion.
108
+ */
109
+ void onSuccess ();
99
110
100
- void onStart ();
111
+ /**
112
+ * On completion, regardless of failure.
113
+ */
114
+ void onComplete ();
101
115
}
102
116
}
0 commit comments