Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to Recover Remaining Tasks in BatchExecutor #8689

Closed
scabug opened this issue Jun 29, 2014 · 10 comments
Closed

Fail to Recover Remaining Tasks in BatchExecutor #8689

scabug opened this issue Jun 29, 2014 · 10 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Jun 29, 2014

In scala.concurrent.BatchExecutor$Batch.run() of Scala 2.11.1.

If head.run() BatchingExecutor.scala(63) throws a exception, remaining tasks will attempt to execute. But require(_tasksLocal.get eq null) at the beginning of the Batch.run() that is called recursively from unbatchedExecute() will always fail because it set the Nil to _tasksLocal here.
This hides the original cause. _tasksLocal should remove() because the remaining tasks are passed as an argument.

java.lang.IllegalStateException: problem in scala.concurrent internal callback
at scala.concurrent.Future$InternalCallbackExecutor$.reportFailure(Future.scala:601)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
at scala.concurrent.Promise$class.complete(Promise.scala:55)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153)
at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:207)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:51)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:599)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:72)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:78)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:55)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:55)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:54)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:599)
at scala.concurrent.BatchingExecutor$class.execute(BatchingExecutor.scala:106)
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:597)
... 13 more

@scabug
Copy link
Author

scabug commented Jun 29, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8689?orig=1
Reporter: Takami Torao (torao)
Affected Versions: 2.11.0, 2.11.1
Other Milestones: 2.11.6
Attachments:

@scabug
Copy link
Author

scabug commented Oct 10, 2014

Viktor Klang (viktorklang) said (edited on Oct 10, 2014 9:27:40 AM UTC):
Hi,

Isn't the only way to get that requirement failure is if you execute the new Batch synchronously in unbatchedExecute?

Do you have a reproducer for this issue?

@scabug
Copy link
Author

scabug commented Dec 17, 2014

satyagraha said:
The attached program when run under 2.10.4 generates a stack trace on stderr similar to that reported.

I think the expected program effects are correct in this case, it's more that the thread attempting to complete the previously completed promise gets broken.

BTW it does something similar with the Akka execution context, though the traceback is slightly different.

@scabug
Copy link
Author

scabug commented Dec 17, 2014

Viktor Klang (viktorklang) said:
Hi @satyagraha,

may I ask you minimize the reproducer? (i.e. removing all code that isn't needed to reproduce the problem)

Thank you!

@scabug
Copy link
Author

scabug commented Dec 17, 2014

satyagraha said:
Now simplified to one future and one promise.

@scabug
Copy link
Author

scabug commented Dec 17, 2014

Viktor Klang (viktorklang) said (edited on Dec 17, 2014 9:00:16 PM UTC):
Thanks @satyagraha,

I managed to minimize it a bit further, I can reproduce your problem locally.

package org.anomaly
object AnomalyApp3 extends App {
  import scala.concurrent._
  import ExecutionContext.Implicits.global
  val source1 = Promise[Int]()
  val source2 = Promise[Int]()
  source2.completeWith(source1.future).future.onComplete {
    case completion => print(s"source2 completed with: ${completion}")
  }
  source2.tryFailure(new TimeoutException)
  source1.success(123)
}

@scabug
Copy link
Author

scabug commented Dec 17, 2014

Viktor Klang (viktorklang) said:
Submitted a PR that solves the problem (completeWith): scala/scala#4215

@scabug
Copy link
Author

scabug commented Dec 18, 2014

satyagraha said:
Delighted with the prompt response and proposed solution! That substitution of tryCompleteWith for completeWith fixes the AnomalyApp examples. I can't see much difference in practical semantics between these methods.

@scabug
Copy link
Author

scabug commented Dec 18, 2014

Viktor Klang (viktorklang) said:
Thanks!

I just added some more tests to completeWith and tryCompleteWith to the PR, and introduced a new commit which deprecates completeWith in favor of tryCompleteWith as well as applies an optimization in the form of root linking for DefaultPromise.

@scabug
Copy link
Author

scabug commented Feb 15, 2015

@gkossakowski said:
scala/scala#4289

@scabug scabug closed this as completed Feb 15, 2015
@scabug scabug added the library label Apr 7, 2017
@scabug scabug added this to the 2.10.5 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants