File tree Expand file tree Collapse file tree 2 files changed +22
-2
lines changed
main/scala/org/apache/spark
test/scala/org/apache/spark/scheduler Expand file tree Collapse file tree 2 files changed +22
-2
lines changed Original file line number Diff line number Diff line change @@ -77,6 +77,8 @@ class TaskContext(
77
77
/**
78
78
* Add a listener in the form of a Scala closure to be executed on task completion.
79
79
* This will be called in all situation - success, failure, or cancellation.
80
+ * Exceptions in callbacks are however not thrown back upstream, i.e. tasks won't marked as
81
+ * failed even if completion callbacks fail to execute.
80
82
*
81
83
* An example use is for HadoopRDD to register a callback to close the input stream.
82
84
*/
@@ -104,7 +106,14 @@ class TaskContext(
104
106
private [spark] def markTaskCompleted (): Unit = {
105
107
completed = true
106
108
// Process complete callbacks in the reverse order of registration
107
- onCompleteCallbacks.reverse.foreach { _.onTaskCompletion(this ) }
109
+ onCompleteCallbacks.reverse.foreach { listener =>
110
+ try {
111
+ listener.onTaskCompletion(this )
112
+ } catch {
113
+ case e : Throwable =>
114
+ logError(" Error in TaskCompletionListener" , e)
115
+ }
116
+ }
108
117
}
109
118
110
119
/** Marks the task for interruption, i.e. cancellation. */
Original file line number Diff line number Diff line change @@ -26,7 +26,7 @@ import org.apache.spark.util.Utils
26
26
27
27
class TaskContextSuite extends FunSuite with BeforeAndAfter with LocalSparkContext {
28
28
29
- test(" Calls executeOnCompleteCallbacks after failure" ) {
29
+ test(" calls TaskCompletionListener after failure" ) {
30
30
TaskContextSuite .completed = false
31
31
sc = new SparkContext (" local" , " test" )
32
32
val rdd = new RDD [String ](sc, List ()) {
@@ -45,10 +45,21 @@ class TaskContextSuite extends FunSuite with BeforeAndAfter with LocalSparkConte
45
45
}
46
46
assert(TaskContextSuite .completed === true )
47
47
}
48
+
49
+ test(" all TaskCompletionListeners should be called even if some fail" ) {
50
+ val context = new TaskContext (0 , 0 , 0 )
51
+ context.addTaskCompletionListener(_ => throw new Exception (" blah" ))
52
+ context.addTaskCompletionListener(_ => TaskContextSuite .callbackInvoked = true )
53
+ context.addTaskCompletionListener(_ => throw new Exception (" blah" ))
54
+ context.markTaskCompleted()
55
+ assert(TaskContextSuite .callbackInvoked === true )
56
+ }
48
57
}
49
58
50
59
private object TaskContextSuite {
51
60
@ volatile var completed = false
61
+
62
+ var callbackInvoked = false
52
63
}
53
64
54
65
private case class StubPartition (index : Int ) extends Partition
You can’t perform that action at this time.
0 commit comments