Slick 3.0-RC3 fails with java.util.concurrent.RejectedExecutionException

匿名 (未验证) 提交于 2019-12-03 01:58:03

问题:

I'm trying to get familiar with Slick 3.0 and Futures (using Scala 2.11.6). I use simple code based on Slick's Multi-DB Cake Pattern example. Why does the following code terminate with an exception and how to fix it?

import scala.concurrent.Await import scala.concurrent.duration._ import slick.jdbc.JdbcBackend.Database import scala.concurrent.ExecutionContext.Implicits.global  class Dispatcher(db: Database, dal: DAL) {   import dal.driver.api._    def init() = {     db.run(dal.create)     try db.run(dal.stuffTable += Stuff(23,"hi"))     finally db.close      val x = {       try db.run(dal.stuffTable.filter(_.serial === 23).result)       finally db.close     }     // This crashes:     val result = Await.result(x, 2 seconds)   } } 

Execution fails with:

java.util.concurrent.RejectedExecutionException: Task slick.backend.DatabaseComponent$DatabaseDef$$anon$2@5c73f637 rejected from java.util.concurrent.ThreadPoolExecutor@4129c44c[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 2]     at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)     at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)     at scala.concurrent.impl.ExecutionContextImpl$$anon$1.execute(ExecutionContextImpl.scala:136)     at slick.backend.DatabaseComponent$DatabaseDef$class.runSynchronousDatabaseAction(DatabaseComponent.scala:224)     at slick.jdbc.JdbcBackend$DatabaseDef.runSynchronousDatabaseAction(JdbcBackend.scala:38)     at slick.backend.DatabaseComponent$DatabaseDef$class.runInContext(DatabaseComponent.scala:201)     at slick.jdbc.JdbcBackend$DatabaseDef.runInContext(JdbcBackend.scala:38)     at slick.backend.DatabaseComponent$DatabaseDef$class.runInternal(DatabaseComponent.scala:75)     at slick.jdbc.JdbcBackend$DatabaseDef.runInternal(JdbcBackend.scala:38)     at slick.backend.DatabaseComponent$DatabaseDef$class.run(DatabaseComponent.scala:72)     at slick.jdbc.JdbcBackend$DatabaseDef.run(JdbcBackend.scala:38)     at Dispatcher.init(Dispatcher.scala:15)     at SlickDemo$.main(SlickDemo.scala:16)     at SlickDemo.main(SlickDemo.scala)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:606) 

回答1:

I think that something is not correct in what you are trying to do: Slick's run method doesn't return Unit and doesn't fail with an exception - as it used to in previous versions. run now returns a Future, so if you want to run actions in sequence you need to flatMap the steps, or use a for-comprehension:

def init() = {   val = results for {     _ 

I am not sure that you really need to use db.close that way: that is actually what may be causing the error (i.e. the db is closed in concurrence with the future that runs the actual queries so the execution can't happen).

If you want to handle errors use Future's capabilities, e.g.:

result.onFailure { case NonFatal(ex) => // do something with the exception } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!