Flaky futures test

60 views
Skip to first unread message

Lukas Rytz

unread,
Mar 27, 2015, 8:26:19 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
Hi,

The test jvm/t8689.scala fails from time to time (for example, see here: https://scala-ci.typesafe.com/job/scala-2.11.x-validate-test/481/console)

Any ideas?

Lukas

Jason Zaugg

unread,
Mar 27, 2015, 8:37:33 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
I can reproduce the failure locally:

scala> object Test {
     |   def main(args: Array[String]): Unit = {
     |     import scala.concurrent._
     |     import ExecutionContext.Implicits.global
     |     val source1 = Promise[Int]()
     |     val source2 = Promise[Int]()
     |     var done = new java.util.concurrent.atomic.AtomicBoolean(false)
     |     source2.completeWith(source1.future).future.onComplete {
     |       case _ => done.set(true)
     |     }
     |     source2.tryFailure(new TimeoutException)
     |     source1.success(123)
     |     assert(done.get())
     |   }
     | }
defined object Test

scala> (1 to 1000) foreach {i => print("."); Test.main(null)}
.....................................java.lang.AssertionError: assertion failed
  at scala.Predef$.assert(Predef.scala:151)
  at Test$.main(<console>:19)
  at $anonfun$1.apply$mcVI$sp(<console>:9)
  at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:166)
  ... 33 elided

scala> (1 to 1000) foreach {i => print("."); Test.main(null)}
...............java.lang.AssertionError: assertion failed
  at scala.Predef$.assert(Predef.scala:151)
  at Test$.main(<console>:19)
  at $anonfun$1.apply$mcVI$sp(<console>:9)
  at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:166)
  ... 33 elided

-jason

Lukas Rytz

unread,
Mar 27, 2015, 8:41:26 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
thanks. i also tried with a loop, but could not reproduce
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Viktor Klang

unread,
Mar 27, 2015, 8:54:25 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
The problem is the lack of HB edge between the onComplete callback executing the `done.set(true)` and the assertion that it is true.

--
Cheers,

Viktor Klang

unread,
Mar 27, 2015, 8:55:12 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
Or rather, that was a bit misworded: There's no guarantee that the callback has executed within the Implicits.globals by the time the current thread executes that assertion.
--
Cheers,

Viktor Klang

unread,
Mar 27, 2015, 8:56:20 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
So, since Implicits.global uses Daemon threads the main thread may exit before the thread pool has a chance to output the success-printout.
--
Cheers,

Viktor Klang

unread,
Mar 27, 2015, 9:02:03 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
However, the important part of the test is to verify that that callback is executed, so we need to augment it to something like:

+object Test {
+  def main(args: Array[String]): Unit = {
+    import scala.concurrent._
+    import ExecutionContext.Implicits.global
+    val source1 = Promise[Int]()
+    val source2 = Promise[Int]()
+    val done = Promise[Unit]()
+    source2.completeWith(source1.future).future.onComplete {
+      case _ =>
+         print("success")
+         done.success(())
+    }
+    source2.tryFailure(new TimeoutException)
+    source1.success(123)
+    import duration._
+    Await.result(done.future, 30.seconds)
+  }
+}

--
Cheers,

Jason Zaugg

unread,
Mar 27, 2015, 9:03:23 AM3/27/15
to scala-i...@googlegroups.com, viktor...@typesafe.com
Great minds think alike :)

-jason
Reply all
Reply to author
Forward
0 new messages