3

FS2でオブジェクト プール パターンを実装する最良の方法を確認しようとしています。

次のMyPrinter定義があるとします。

class MyPrinter {
  import scala.util.Random.nextInt
  Thread.sleep(5000 + nextInt(1000))
  def doStuff(s: String): Unit = {
    println(s)
    Thread.sleep(1000 + nextInt(1000))
  }
  def releaseResources(): Unit =
    println("Releasing resources")
}

プリンターStream[Task, MyPrinter]のプールでバッキングを作成する最良の方法は何ですか? nストリームが終了したら、すべての基になるリソースを を呼び出して適切に解放する必要がありますreleaseResources

おまけの質問: プリンターが何らかの理由で終了した場合、プールに新しいプリンターを作成することは可能ですか?

4

1 に答える 1

4

よくわからない質問ですが、これはどうですか?

implicit val S = Strategy.fromFixedDaemonPool(10, "pooling")

val queue = new LinkedBlockingDeque[MyPrinter]()
queue.add(new MyPrinter)
queue.add(new MyPrinter)

Stream.repeatEval(Task.delay(queue.take()))
  .map(p => try p.doStuff("test") finally {
    p.releaseResources()
    queue.put(p)
  })
  .take(10)
  .runLog
  .unsafeRun()

キューはhttps://commons.apache.org/proper/commons-pool/に置き換えることができます

更新:

各「リソース」を同時に処理する場合:

concurrent.join(10)(
  Stream
    .repeatEval(Task.delay(queue.take()))
    .map(p => Stream.eval(Task.delay(p.doStuff("test"))
    .map(_ => p /* done with this resource */)))
).map(p => { p.releaseResources(); queue.put(p) /* release resource */})
 .take(10).runLog.unsafeRun()
于 2016-07-13T00:12:50.280 に答える