簡體   English   中英

如何在期貨中使用Scala ARM?

[英]How to use Scala ARM with Futures?

我想實現ARM(自動資源管理)模式,其中資源是異步使用的。

問題

假設我的資源看起來像:

class MyResource { 
  def foo() : Future[MyResource] = ???
  // Other methods returning various futures
  def close() : Unit = ???
}
object MyResource { 
  def open(name: String): Future[MyResource] = ???
} 

所需的使用模式是:

val r : Future[MyResource] = MyResource.open("name")
r flatMap (r => {
  r.foo() /* map ... */ andThen {
    case _ => r.close()
  }
})

省略的映射函數可能很復雜,涉及分支和鏈接期貨,這些期貨會重復調用返回期貨的r方法。

我想確保在所有未來的延續完成(或失敗)之后調用r.close() )。 在每個呼叫站點手動執行此操作非常容易出錯。 這需要ARM解決方案。

試圖解決方案

scala-arm庫通常是同步的。 這段代碼不會做正確的事情,因為在塊內的期貨完成之前會調用close():

for (r <- managed(MyResource.open("name"))) {
  r map (_.foo()) // map ...
}

我雖然使用這個包裝器:

def usingAsync[T](opener: => Future[MyResource]) (body: MyResource => Future[T]) : Future[T] =
  opener flatMap { 
    myr => body(myr) andThen { case _ => myr.close() } }

然后呼叫站點看起來像:

usingAsync(MyResource.open("name")) ( myr => {
  myr.foo // map ...
})

但是,塊中的代碼將負責返回在該塊創建的所有其他期貨完成時完成的Future。 如果它意外沒有,那么資源將在所有使用它的期貨完成之前關閉。 並且沒有靜態驗證來捕獲此錯誤。 例如,這將是一個運行時錯誤:

usingAsync(MyResource.open("name")) ( myr => {
  myr.foo() // Do one thing
  myr.bar() // Do another
})

怎么解決這個?

顯然,我可以使用scala-arm的分隔連續支持(CPS)。 它看起來有點復雜,我害怕弄錯。 它需要啟用編譯器插件。 此外,我的團隊對scala非常陌生,我不想要求他們使用CPS。

CPS是前進的唯一途徑嗎? 是否有一個圖書館或設計模式可以更簡單地使用Futures,或者使用scala-arm執行此操作的示例?

Reactive Extensions(Rx)可能是另一種解決方案。 圍繞這種編程范式的勢頭越來越大,現在有許多語言可供使用,包括Scala。

Rx的基礎是創建一個Observable,它是異步事件的來源。 Observable可以用復雜的方式鏈接,這就是它的力量。 您訂閱了一個Observable來監聽onNext,onError和onComplete事件。 您還會收到允許您取消訂閱的訂閱。

我想你可能會在onCompleted和/或onError處理程序中添加一個resource.close()調用。

請參閱RxScala文檔:

Observable.subscribe(
    onNext: (T) ⇒ Unit, 
    onError: (Throwable) ⇒ Unit, 
    onCompleted: () ⇒ Unit): Subscription

更多信息:

  • RxScala網站: http ://rxscala.github.io/
  • RxScala Observable: http ://rxscala.github.io/scaladoc/index.html#rx.lang.scala.Observable
  • Ben Christensen在NetFlix上的簡介: http//www.infoq.com/presentations/netflix-functional-rx
  • Erik Meijer提供了鏈式Observable的代碼示例,以及Martin Odersky,Erik Meijer和Roland Kuhn在Coursera課程中的反應式編程原理

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM