@@ -19,7 +19,12 @@ package org.apache.spark.scheduler
1919
2020import java .nio .ByteBuffer
2121
22- import org .scalatest .{BeforeAndAfter , BeforeAndAfterAll , FunSuite }
22+ import scala .concurrent .duration ._
23+ import scala .language .postfixOps
24+ import scala .util .control .NonFatal
25+
26+ import org .scalatest .{BeforeAndAfter , FunSuite }
27+ import org .scalatest .concurrent .Eventually ._
2328
2429import org .apache .spark .{LocalSparkContext , SparkConf , SparkContext , SparkEnv }
2530import org .apache .spark .storage .TaskResultBlockId
@@ -34,6 +39,8 @@ class ResultDeletingTaskResultGetter(sparkEnv: SparkEnv, scheduler: TaskSchedule
3439 extends TaskResultGetter (sparkEnv, scheduler) {
3540 var removedResult = false
3641
42+ @ volatile var removeBlockSuccessfully = false
43+
3744 override def enqueueSuccessfulTask (
3845 taskSetManager : TaskSetManager , tid : Long , serializedData : ByteBuffer ) {
3946 if (! removedResult) {
@@ -42,6 +49,15 @@ class ResultDeletingTaskResultGetter(sparkEnv: SparkEnv, scheduler: TaskSchedule
4249 serializer.get().deserialize[TaskResult [_]](serializedData) match {
4350 case IndirectTaskResult (blockId, size) =>
4451 sparkEnv.blockManager.master.removeBlock(blockId)
52+ // removeBlock is asynchronous. Need to wait it's removed successfully
53+ try {
54+ eventually(timeout(3 seconds), interval(200 milliseconds)) {
55+ assert(! sparkEnv.blockManager.master.contains(blockId))
56+ }
57+ removeBlockSuccessfully = true
58+ } catch {
59+ case NonFatal (e) => removeBlockSuccessfully = false
60+ }
4561 case directResult : DirectTaskResult [_] =>
4662 taskSetManager.abort(" Internal error: expect only indirect results" )
4763 }
@@ -92,10 +108,12 @@ class TaskResultGetterSuite extends FunSuite with BeforeAndAfter with LocalSpark
92108 assert(false , " Expect local cluster to use TaskSchedulerImpl" )
93109 throw new ClassCastException
94110 }
95- scheduler.taskResultGetter = new ResultDeletingTaskResultGetter (sc.env, scheduler)
111+ val resultGetter = new ResultDeletingTaskResultGetter (sc.env, scheduler)
112+ scheduler.taskResultGetter = resultGetter
96113 val akkaFrameSize =
97114 sc.env.actorSystem.settings.config.getBytes(" akka.remote.netty.tcp.maximum-frame-size" ).toInt
98115 val result = sc.parallelize(Seq (1 ), 1 ).map(x => 1 .to(akkaFrameSize).toArray).reduce((x, y) => x)
116+ assert(resultGetter.removeBlockSuccessfully)
99117 assert(result === 1 .to(akkaFrameSize).toArray)
100118
101119 // Make sure two tasks were run (one failed one, and a second retried one).
0 commit comments