【问题标题】:Synchronous and Asynchronous client code in ScalaScala 中的同步和异步客户端代码
【发布时间】:2015-02-08 11:22:52
【问题描述】:

这是我以前的question 的后续。假设我需要同步和异步调用一个 REST 服务。在同步情况下,我想在调用者线程上执行此操作,而不从池中获取其他线程。

我只想编写我的业务逻辑一次并在这两种情况下重用它。业务逻辑包括构建请求和处理响应。

我还想编写 REST 调用,就像在“调用服务 A,然后是服务 B,然后是服务 C”中一样

你会如何在 Scala 中做到这一点?

【问题讨论】:

  • 您想通过 Akka 还是使用 Java 并发工具来实现它?你也考虑过玩吗?
  • stackoverflow.com/questions/6581188/… 可能会提供一些见解。然后,您可以为同步案例传递“当前线程”执行器,并为异步传递一个带有其他线程的真正执行器。
  • @I.K.我更喜欢 Scala 而不是 Java。 Akka 和 Play 应该没问题。
  • @RichHenry 是的,我可以使用ExecutorRunnableCallable,但我担心生成的代码会看起来很丑,不值得。
  • 好吧,我以为您会将其提供给 ExecutionContext.fromExecutorService 而不是使用全局上下文,并且仍然使用 Future 等。我不建议直接使用 Java 类型。

标签: multithreading scala rest


【解决方案1】:

这应该在当前线程中运行...

{
  val currentThreadEx = new AbstractExecutorService {
    override def execute(r: Runnable) { r.run }
    override def shutdownNow(): java.util.List[Runnable] = new java.util.ArrayList[Runnable]()
    override def shutdown() {}
    override def isTerminated = false
    override def isShutdown = false
    override def awaitTermination(timeout: Long, unit: TimeUnit) = false
  }
  implicit val exContext = ExecutionContext.fromExecutor(currentThreadEx)

  val f = Future {
    10 + 1
  } 

  println(Await.result(f, 1 seconds))
}

这将在默认执行器上运行...

{
  import ExecutionContext.Implicits.global

  val f = Future {
    10 + 1
  } 

  println(Await.result(f, 1 seconds))
}

如您所见,您可以使用 ExecutorService 作为抽象点。

或者你可以使用一个用 Monads 编写的函数,然后你可以将这些操作绑定在一起而不需要处理上下文(即 Future)。

  def op1[M[_]: Monad](i: Int)(j: Int): M[Int] = {
    Monad[M].point { i * j }
  }

  println(Monad[Id].point(10) >>= op1[Id](10))
  println((Future { 10 } >>= op1[Future](10)).run)

【讨论】:

  • 谢谢。因此,您建议将业务逻辑实现为Future,并对同步和异步情况使用不同的Executors。由于Futures 是可组合的,我可能可以组合以Futures 实现的不同服务的调用。对吗?
  • 这是一种方法。你可以编写期货。 Scalaz monads 也可以帮助在 Id 和 Future 作为 monadic 类型之间切换,但我认为根据您的要求,这会使解决方案复杂化。
  • 您能否详细说明scalaz monads 可能有什么帮助?我知道scalaz 一点,知道什么是单子。
  • 我在上面贴一个简单的例子,基本上你用 monads 编写你的操作,然后你可以切换你使用的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多