java.lang.IllegalArgumentException: requirement failed from the concurrency library in Scala 2.12

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

java.lang.IllegalArgumentException: requirement failed from the concurrency library in Scala 2.12

glapark
Hello,

I have some issue with the concurrency library in Scala 2.12. To be specific:

1) We would like to rethrow RejectedExecutionException if a Future fails to start because the ExecutionContext has been shut down already. For example,
def initialize(): Unit = {
  Future { 
    /* body */
  } (executionContext)
}
If executionContext has been shut down already and the body fails to run, initialize() should raise RejectedExecutionException.

2) We would like to swallow RejectedExecutionException if callbacks fail to start because the ExecutionContext has been shut down already. For example,
  intializeTask.future.foreach { 
    /* body */
  } (executionContext)
If executionContext has been shut down already and the body is not executed, it will be reported to RejectedExecutionHandler, which will swallow it.

Previously our code was running fine with Scala 2.11.8. We passed RejectedExecutionHandler as an argument to ThreadPoolExecutor, and rejectedExecutionReporter of type Throwable => Unit to ExecutionContext.fromExecutorService().

Now with Scala 2.12, I see the following error message occasionally, which should be due to rethrowing RejectedExecutionException in the ExecutionContext. 

Exception in thread "initializer-838-1" java.lang.IllegalStateException: problem in scala.concurrent internal callback
at scala.concurrent.Future$InternalCallbackExecutor$.reportFailure(Future.scala:866)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1$adapted(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
at scala.concurrent.Promise.complete(Promise.scala:49)
at scala.concurrent.Promise.complete$(Promise.scala:48)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:183)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:264)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:51)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor$Batch.processBatch$1(BatchingExecutor.scala:72)
at scala.concurrent.BatchingExecutor$Batch.$anonfun$run$1(BatchingExecutor.scala:78)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:55)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor.execute(BatchingExecutor.scala:106)
at scala.concurrent.BatchingExecutor.execute$(BatchingExecutor.scala:103)
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:862)
... 12 more

So, I wonder how I can implement the above 1) and 2) in Scala 2.12. I noticed that Scala 2.12 starts Future by passing the computation as a callback to unit, and is this the reason for all this?

Thanks a lot!

-- Gla Park

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: java.lang.IllegalArgumentException: requirement failed from the concurrency library in Scala 2.12

Viktor Klang
Hi Gla,

I don't really have time today to have any look at this at the moment, but I'll try to explain what could be happening.

With 2.12 the creation of Future via Future.apply has been streamlined to be equivalent of creating a new future through a transformation, ex:

Future("foo") == someSuccessfulFuture.map(_ => "foo")

The reason for this is important: there should be no semantical difference between the two.

Now, this means that handling errors the way you did with try-catch around "Future.apply" shouldn't have worked in the first place, but for some reason it used to.

Now, I haven't had a chance to have a look, but *ideally* the failure to submit a Runnable to the ExecutionContext should result in a failed downstream future, but I think/suspect that what is happening is that the context whether the callback is creating another promise or not is lost (type-wise at least) at the point where the callback is scheduled to be added to the ExecutionContext.

Does that make sense?

Cheers,

On Thursday, November 17, 2016 at 10:53:23 AM UTC+1, glapark wrote:
Hello,

I have some issue with the concurrency library in Scala 2.12. To be specific:

1) We would like to rethrow RejectedExecutionException if a Future fails to start because the ExecutionContext has been shut down already. For example,
def initialize(): Unit = {
  Future { 
    /* body */
  } (executionContext)
}
If executionContext has been shut down already and the body fails to run, initialize() should raise RejectedExecutionException.

2) We would like to swallow RejectedExecutionException if callbacks fail to start because the ExecutionContext has been shut down already. For example,
  intializeTask.future.foreach { 
    /* body */
  } (executionContext)
If executionContext has been shut down already and the body is not executed, it will be reported to RejectedExecutionHandler, which will swallow it.

Previously our code was running fine with Scala 2.11.8. We passed RejectedExecutionHandler as an argument to ThreadPoolExecutor, and rejectedExecutionReporter of type Throwable => Unit to ExecutionContext.fromExecutorService().

Now with Scala 2.12, I see the following error message occasionally, which should be due to rethrowing RejectedExecutionException in the ExecutionContext. 

Exception in thread "initializer-838-1" java.lang.IllegalStateException: problem in scala.concurrent internal callback
at scala.concurrent.Future$InternalCallbackExecutor$.reportFailure(Future.scala:866)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1$adapted(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
at scala.concurrent.Promise.complete(Promise.scala:49)
at scala.concurrent.Promise.complete$(Promise.scala:48)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:183)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:264)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:51)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor$Batch.processBatch$1(BatchingExecutor.scala:72)
at scala.concurrent.BatchingExecutor$Batch.$anonfun$run$1(BatchingExecutor.scala:78)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:55)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor.execute(BatchingExecutor.scala:106)
at scala.concurrent.BatchingExecutor.execute$(BatchingExecutor.scala:103)
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:862)
... 12 more

So, I wonder how I can implement the above 1) and 2) in Scala 2.12. I noticed that Scala 2.12 starts Future by passing the computation as a callback to unit, and is this the reason for all this?

Thanks a lot!

-- Gla Park

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: java.lang.IllegalArgumentException: requirement failed from the concurrency library in Scala 2.12

glapark
Thank you for your reply. As you pointed out, it is perhaps due to the use of the unit in creating Future and the ExecutionContext associated with unit.

Cheers,

--- Gla Park

On Monday, November 21, 2016 at 10:12:33 PM UTC+9, √iktor Klang wrote:
Hi Gla,

I don't really have time today to have any look at this at the moment, but I'll try to explain what could be happening.

With 2.12 the creation of Future via Future.apply has been streamlined to be equivalent of creating a new future through a transformation, ex:

Future("foo") == someSuccessfulFuture.map(_ => "foo")

The reason for this is important: there should be no semantical difference between the two.

Now, this means that handling errors the way you did with try-catch around "Future.apply" shouldn't have worked in the first place, but for some reason it used to.

Now, I haven't had a chance to have a look, but *ideally* the failure to submit a Runnable to the ExecutionContext should result in a failed downstream future, but I think/suspect that what is happening is that the context whether the callback is creating another promise or not is lost (type-wise at least) at the point where the callback is scheduled to be added to the ExecutionContext.

Does that make sense?

Cheers,

On Thursday, November 17, 2016 at 10:53:23 AM UTC+1, glapark wrote:
Hello,

I have some issue with the concurrency library in Scala 2.12. To be specific:

1) We would like to rethrow RejectedExecutionException if a Future fails to start because the ExecutionContext has been shut down already. For example,
def initialize(): Unit = {
  Future { 
    /* body */
  } (executionContext)
}
If executionContext has been shut down already and the body fails to run, initialize() should raise RejectedExecutionException.

2) We would like to swallow RejectedExecutionException if callbacks fail to start because the ExecutionContext has been shut down already. For example,
  intializeTask.future.foreach { 
    /* body */
  } (executionContext)
If executionContext has been shut down already and the body is not executed, it will be reported to RejectedExecutionHandler, which will swallow it.

Previously our code was running fine with Scala 2.11.8. We passed RejectedExecutionHandler as an argument to ThreadPoolExecutor, and rejectedExecutionReporter of type Throwable => Unit to ExecutionContext.fromExecutorService().

Now with Scala 2.12, I see the following error message occasionally, which should be due to rethrowing RejectedExecutionException in the ExecutionContext. 

Exception in thread "initializer-838-1" java.lang.IllegalStateException: problem in scala.concurrent internal callback
at scala.concurrent.Future$InternalCallbackExecutor$.reportFailure(Future.scala:866)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1$adapted(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
at scala.concurrent.Promise.complete(Promise.scala:49)
at scala.concurrent.Promise.complete$(Promise.scala:48)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:183)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:264)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:51)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor$Batch.processBatch$1(BatchingExecutor.scala:72)
at scala.concurrent.BatchingExecutor$Batch.$anonfun$run$1(BatchingExecutor.scala:78)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:55)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor.execute(BatchingExecutor.scala:106)
at scala.concurrent.BatchingExecutor.execute$(BatchingExecutor.scala:103)
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:862)
... 12 more

So, I wonder how I can implement the above 1) and 2) in Scala 2.12. I noticed that Scala 2.12 starts Future by passing the computation as a callback to unit, and is this the reason for all this?

Thanks a lot!

-- Gla Park

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: java.lang.IllegalArgumentException: requirement failed from the concurrency library in Scala 2.12

Viktor Klang
I think there was a bit of a discrepancy how Future.apply was behaving in comparison to the transformations in version before 2.12.
As mentioned the new behavior is consistent and there shouldn't exist any observable difference between the two.

On Mon, Nov 21, 2016 at 2:41 PM, glapark <[hidden email]> wrote:
Thank you for your reply. As you pointed out, it is perhaps due to the use of the unit in creating Future and the ExecutionContext associated with unit.

Cheers,

--- Gla Park


On Monday, November 21, 2016 at 10:12:33 PM UTC+9, √iktor Klang wrote:
Hi Gla,

I don't really have time today to have any look at this at the moment, but I'll try to explain what could be happening.

With 2.12 the creation of Future via Future.apply has been streamlined to be equivalent of creating a new future through a transformation, ex:

Future("foo") == someSuccessfulFuture.map(_ => "foo")

The reason for this is important: there should be no semantical difference between the two.

Now, this means that handling errors the way you did with try-catch around "Future.apply" shouldn't have worked in the first place, but for some reason it used to.

Now, I haven't had a chance to have a look, but *ideally* the failure to submit a Runnable to the ExecutionContext should result in a failed downstream future, but I think/suspect that what is happening is that the context whether the callback is creating another promise or not is lost (type-wise at least) at the point where the callback is scheduled to be added to the ExecutionContext.

Does that make sense?

Cheers,

On Thursday, November 17, 2016 at 10:53:23 AM UTC+1, glapark wrote:
Hello,

I have some issue with the concurrency library in Scala 2.12. To be specific:

1) We would like to rethrow RejectedExecutionException if a Future fails to start because the ExecutionContext has been shut down already. For example,
def initialize(): Unit = {
  Future { 
    /* body */
  } (executionContext)
}
If executionContext has been shut down already and the body fails to run, initialize() should raise RejectedExecutionException.

2) We would like to swallow RejectedExecutionException if callbacks fail to start because the ExecutionContext has been shut down already. For example,
  intializeTask.future.foreach { 
    /* body */
  } (executionContext)
If executionContext has been shut down already and the body is not executed, it will be reported to RejectedExecutionHandler, which will swallow it.

Previously our code was running fine with Scala 2.11.8. We passed RejectedExecutionHandler as an argument to ThreadPoolExecutor, and rejectedExecutionReporter of type Throwable => Unit to ExecutionContext.fromExecutorService().

Now with Scala 2.12, I see the following error message occasionally, which should be due to rethrowing RejectedExecutionException in the ExecutionContext. 

Exception in thread "initializer-838-1" java.lang.IllegalStateException: problem in scala.concurrent internal callback
at scala.concurrent.Future$InternalCallbackExecutor$.reportFailure(Future.scala:866)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1$adapted(Promise.scala:284)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
at scala.concurrent.Promise.complete(Promise.scala:49)
at scala.concurrent.Promise.complete$(Promise.scala:48)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:183)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:264)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:51)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor$Batch.processBatch$1(BatchingExecutor.scala:72)
at scala.concurrent.BatchingExecutor$Batch.$anonfun$run$1(BatchingExecutor.scala:78)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at scala.concurrent.BatchingExecutor$Batch.run(BatchingExecutor.scala:55)
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:864)
at scala.concurrent.BatchingExecutor.execute(BatchingExecutor.scala:106)
at scala.concurrent.BatchingExecutor.execute$(BatchingExecutor.scala:103)
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:862)
... 12 more

So, I wonder how I can implement the above 1) and 2) in Scala 2.12. I noticed that Scala 2.12 starts Future by passing the computation as a callback to unit, and is this the reason for all this?

Thanks a lot!

-- Gla Park

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
Cheers,

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.