在规范中播放Slick异常“从java.util.concurrent.ThreadPoolExecutor中拒绝的任务slick.backend.DatabaseComponent”

时间:2016-01-13 18:41:48

标签: scala playframework slick specs2 threadpoolexecutor

我在运行我的Spec测试时使用Play从Slick获得ThreadPoolException,这是使用Play 2.4.x,Slick 3,Specs 2?

我的测试看起来像:

.carousel-inner > .item > img {
    margin: 0 auto;
}

调用端点:

val jsonHeaders = FakeHeaders(Seq((CONTENT_TYPE, MimeTypes.JSON)))
def fakeApp: FakeApplication = FakeApplication(additionalConfiguration = Map(
  "slick.dbs.default.driver" -> "slick.driver.H2Driver$",
  "slick.dbs.default.db.driver" -> "org.h2.Driver",
  "slick.dbs.default.db.url" -> "jdbc:h2:mem:test;MODE=PostgreSQL;DATABASE_TO_UPPER=FALSE"
))

"Add new group" in new WithApplication(FakeApp.fakeApp){
  val vg = new ViewGroup(0, "Test", "Tests")
  val add = route(FakeRequest(POST, "/api/new-group", jsonHeaders, vg.toJson())).get

  status(add) must equalTo(OK)
  contentType(add) must beSome.which(_ == MimeTypes.JSON)
}

反过来调用DAO:

def newGroup = AuthenticatedAction(authType).async(parse.json) { request =>
  request.body.validate[ViewGroup].fold(
    errors => {
      Future { BadRequest(JsError.toJson(errors)) }
    }, viewGroup => {
      Groups.add(new Group(viewGroup.Name, viewGroup.Description)).map( i => Ok(i.toString) )
    }
  )
}

当我运行测试时,我收到以下错误:

object Groups {
  val groups = TableQuery[GroupTableDef]
  val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)

  def add(group: Group): Future[Int] = {
    dbConfig.db.run(groups += group)
  }
}

这可能与以下方面有关: Slick 3.0-RC3 fails with java.util.concurrent.RejectedExecutionException https://github.com/slick/slick/issues/1183

然而,这些都没有任何解决方案(至少可以工作) 我已经尝试将“顺序”标志添加到我的规格但是没有做任何事情

1 个答案:

答案 0 :(得分:0)

问题很可能是由于为每个测试套件(规范)重新创建了播放应用程序,如here所述。简而言之,对象不会被重新创建,因此dbConfig内的Groups仍然存在,但在第二次测试期间是“陈旧的”。

一个快速而肮脏的解决方法是最初不会获得dbConfig,但是为每次操作重新抓取它:

object Groups {
  val groups = TableQuery[GroupTableDef]

  // note this is a function now
  def dbConfig() = DatabaseConfigProvider.get[JdbcProfile](Play.current)

  def add(group: Group): Future[Int] = {
    dbConfig().db.run(groups += group)
  }
}

这显然不是理想的性能,但是由于数据库操作往往价格昂贵,这种重新获取的成本可能不会带来太多的重量。