光滑的AsyncExecutor异常

时间:2018-01-27 12:41:10

标签: scala playframework threadpool slick-3.0

我有一个用Scala 2.11编写的 Play 2.5 + Slick 3.2 应用程序,该应用程序使用 play-slick 2.1.1 插件。

播放线程池的配置是默认设置。我知道它是Akka调度员。配置 Slick 线程池:

slick.dbs.data.db.numThreads=75
slick.dbs.data.db.queueSize=1000

HikariCP连接池的配置也是默认配置。

Play异步操作,它按组ID检索主题(数据库中约8000个主题),并且每个检索到的主题从其他两个引用的表中组装其DTO:

def getSubjects(groupId: Int) : Future[Seq[SubjectDTO]] = Action.async { request =>
  db.run(retrieveSubjects(request.groupId).withPinnedSession).flatMap { subjects => 
    Future.traverse(subjects)(subjectDTOBuilder())
  }
}

private def subjectDTOBuilder() =
  (subject: Subject) => {
    for {
      subjData <- db.run(getSubjectsAdditionalData(subject.id).withPinnedSession)
      subjInfo <- db.run(getSubjectsMoreInfo(subject.id).withPinnedSession)
    } yield SubjectDTO(subject, subjData, subjInfo)
  }

当执行此Action时,它会在某些时候失败:

Task slick.basic.BasicBackend$DatabaseDef$$anon$2@286a41fb rejected from slick.util.AsyncExecutor$$anon$2$$anon$1@46d9be94[Running, pool size = 75, active threads = 75, queued tasks = 1000, completed tasks = 55419]"

当我将subjectDTOBuilder重写为:

时,异常消失了
private def subjectDTOBuilder() =
  (subject: Subject) => {
    val future = db.run(getSubjectsAdditionalData(subject.id).withPinnedSession)
    val future2 = db.run(getSubjectsMoreInfo(subject.id).withPinnedSession)
    for {
      subjData <- future
      subjInfo <- future2
    } yield SubjectDTO(subject, subjData, subjInfo)
  }

我知道现在这些&#34;无关&#34;期货并行执行,但我没有得到 Slick 异常的实际原因。 Slick 线程池的问题是什么?有人可以解释这种异常可能发生的原因吗?

1 个答案:

答案 0 :(得分:0)

错误消息显示“排队的任务= 1000”。默认任务队列长度也是1000.这意味着您可能一次调度了太多任务,因此任务执行程序的输入队列溢出。此队列包含已调度但仍在等待执行的所有任务。

因此解决方案可能是同时安排较少数量的任务或增加队列长度。您可以通过提供自己的隐式ExecutionContext实例来配置此行为。