6

Scala 2.10 futures を使用して非同期ライブラリを作成しています。ライブラリのコンストラクターは、特定の特性を実装する一連のユーザー定義オブジェクトを受け取り、ライブラリ クラスのメソッドがデータをユーザー定義オブジェクトに 1 つずつ送信します。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

暗黙の ExecutionContext が見つかりません。自分で必要とするか、インポートしてくださいExecutionContext.Implicits.global

私の質問は、ユーザー (クラスを作成する予定のユーザー) に心配させることなく、ユーザー定義オブジェクト ( and ) またはそれらのメソッドに必要ExecutionContextなを暗黙のうちに指定するにはどうすればよいかということです。ユーザーは次のように入力する必要はありませんでした。LibraryObjectThingProcessorPassThroughProcessor

class MyFirstProcessor(implicit context: ExecutionContext)

また

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

1 に答える 1

5

暗黙的なスコープには、基本クラスのコンパニオン オブジェクトと型パラメーターが含まれます。

または、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()
}
于 2013-07-25T06:00:47.003 に答える