Scala future及其回调在同一个执行上下文中工作

Int*_*tio 1 concurrency multithreading scala future callback

我通过Akka actor调用def activateReward并执行OracleClient.rewardActivate(用户)有时非常慢(数据库不在我的责任范围内,属于另一家公司).

当数据库很慢时,线程池耗尽,并且无法有效地分配更多线程来运行回调future.onComplete,因为回调和期货在同一个执行上下文中工作.

请告知如何从为日期OracleClient.rewardActivate(用户)分配的线程异步执行回调中的代码

class RewardActivatorHelper {

  private implicit val ec = new ExecutionContext {
    val threadPool = Executors.newFixedThreadPool(1000)
    def execute(runnable: Runnable) {threadPool.submit(runnable)}
    def reportFailure(t: Throwable) {throw t}
  }

  case class FutureResult(spStart:Long, spFinish:Long)

  def activateReward(msg:Msg, time:Long):Unit = {
    msg.users.foreach {
      user =>
        val future:Future[FutureResult] = Future {
          val (spStart, spFinish) = OracleClient.rewardActivate(user)
          FutureResult(spStart, spFinish)
        }

        future.onComplete {
          case Success(futureResult:FutureResult) =>
            futureResult match {
              case res:FutureResult => Logger.writeToLog(Logger.LogLevel.DEBUG,s"started:${res.spStart}finished:${res.spFinish}")
              case _ => Logger.writeToLog(Logger.LogLevel.DEBUG, "some error")
            }

          case Failure(e:Throwable) => Logger.writeToLog(Logger.LogLevel.DEBUG, e.getMessage)    
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Rik*_*ard 5

您可以通过执行以下操作来显式指定执行上下文而不是隐式地为onComplete回调指定:

import java.util.concurrent.Executors
import scala.concurrent.duration.Duration

object Example extends App {
  import scala.concurrent._

  private implicit val ec = new ExecutionContext {
    val threadPool = Executors.newFixedThreadPool(1000)
    def execute(runnable: Runnable) {threadPool.submit(runnable)}
    def reportFailure(t: Throwable) {throw t}
  }

  val f = Future {
    println("from future")
  }

  f.onComplete { _ =>
    println("I'm done.")
  }(scala.concurrent.ExecutionContext.Implicits.global)

  Await.result(f, Duration.Inf)
}
Run Code Online (Sandbox Code Playgroud)

这当然不能解决数据库无法跟上的根本问题,但无论如何都可能很好.

澄清一下:我让onComplete回调由标准global执行上下文处理.您可能想要创建一个单独的.