加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 将隐式ExecutionContext传递给包含的对象/被调用的方法

发布时间:2020-12-16 09:27:17 所属栏目:安全 来源:网络整理
导读:我正在使用Scala 2.10期货创建一个异步库.库的构造函数采用一系列实现特定特征的用户定义对象,然后库类上的方法将一些数据逐个发送到用户定义的对象中.我希望用户在设置主实例时为异步操作提供ExecutionContext,然后根据需要将该上下文传递给用户定义的对象.
我正在使用Scala 2.10期货创建一个异步库.库的构造函数采用一系列实现特定特征的用户定义对象,然后库类上的方法将一些数据逐个发送到用户定义的对象中.我希望用户在设置主实例时为异步操作提供ExecutionContext,然后根据需要将该上下文传递给用户定义的对象.简化(伪?)代码:

case class Response(thing: String)

class LibraryObject(stack: Seq[Processor])(implicit context: ExecutionContext) {
  def entryPoint(data: String): Future[Response] = {
    val response = Future(Response(""))
    stack.foldLeft(response) { (resp,proc) => proc.process(data,resp) }
  }
}

trait Processor {
  def process(data: String,resp: Future[Response]): Future[Response]
}

可能会使用这样的东西:

class ThingProcessor extends Processor {
  override def process(data: String,response: Future[Response]) = {
    response map { _.copy(thing = "THE THING") }
  }
}

class PassThroughProcessor extends Processor {
  override def process(request: Request,response: Future[Response]) = {
    response
  }
}

object TheApp extends App {
  import ExecutionContext.Implicits.global

  val stack = List(
    new ThingProcessor,new PassThroughProcessor
  )
  val libObj = new LibraryObject(stack)

  val futureResponse = libObj.entryPoint("http://some/url")

  // ...
}

我收到ThingProcessor的编译错误:

Cannot find an implicit ExecutionContext,either require one yourself or import ExecutionContext.Implicits.global

我的问题是,我如何隐式地将LibraryObject所具有的ExecutionContext提供给用户定义的对象(ThingProcessor和PassThroughProcessor)或他们的方法而不让用户(谁将编写类)担心它 – 也就是说,我希望用户不必键入:

class MyFirstProcessor(implicit context: ExecutionContext)

要么

override def process(...)(implicit context: ExecutionContext) = { ... }

解决方法

隐式作用域包括伴随对象和基类的类型参数.

或者,library.submit(new library.Processor {def process()…}).

这是有效的,但不是我的第一个想法,这是更聪明的:

import concurrent._
import concurrent.duration._

class Library(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object Test extends App {
  val library = new Library
  val p = new library.Processor {
    def process(i: Future[Int]) = for (x <- i) yield 2 * x
  }
  val res = library submit p
  val z = Await result (res,10.seconds)
  Console println z
}

更新:

import concurrent._
import concurrent.duration._
import java.util.concurrent.Executors

class Library()(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object library1 extends Library
object library2 extends Library()(ctx.xc)
object p extends library1.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 2 * x
}
object q extends library2.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 3 * x
}

object Test extends App {
  val res = library1 submit p
  //val oops = library2 submit p
  //val oops = library1 submit q
  val z = Await result (res,10.seconds)
  Console println z
  Console println (Await result (library2 submit q,10.seconds))
  ctx.xc.shutdownNow()
}

它不是一件容易的事:

class Library(implicit xc: ExecutionContext = ExecutionContext.global) {

  def submit(p: Processor): Future[Int] = p dueProcess future(7)
}
trait Processor {
  implicit var myxc: ExecutionContext = _
  def dueProcess(i: Future[Int])(implicit xc: ExecutionContext) = {
    myxc = xc
    process(i)
  }
  protected def process(i: Future[Int]): Future[Int]
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object Test extends App {
  def db() = Console println (new Throwable().getStackTrace mkString ("TRACE [n  ","n  ","n]"))
  val library = new Library()(ctx.xc)
  val p = new Processor {
    protected def process(i: Future[Int]) = for (x <- i) yield { db(); 2 * x }
  }
  val res = library submit p
  val z = Await result (res,10.seconds)
  Console println z
  ctx.xc.shutdownNow()
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读