A borrowed resource can postpone its termination
評価
調査の方向性
まず、keypool リポジトリでプールのファイナライズと借用リソースのライフサイクルに関するコードを見つけます。IO.never のケースを含め、issue の Scala 例を再現し、プールが閉じられた後に借用リソースがどのように追跡されるかを調べます。プールのファイナライズが完了する前に借用された接続が破棄およびクローズされ、期待される出力と一致すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
keypool version: 0.4.7
When a resource is borrowed from the pool, it's not a part of the PoolMap anymore. Hence it will not be destroyed during the finalization of the pool.
The resource will be open until it's not completed itself. Thus IO.never as a part of the operation with the resource can hang the whole system.
Example:
sealed trait Key
case object Key extends Key
class Connection(val isOpen: Ref[IO, Boolean])
val pool = KeyPool
.Builder(
(_: Key) => IO.ref(true).map(new Connection(_)),
(conn: Connection) => conn.isOpen.set(false)
)
.doOnCreate(conn => IO.println(s"created $conn"))
.doOnDestroy(conn => IO.println(s"destroyed $conn"))
.build
.onFinalize(IO.println("pool was closed"))
def example(outerAwait: Deferred[IO, Unit]): IO[FiberIO[(Boolean, Boolean)]] =
pool.use { p =>
def job(innerAwait: Deferred[IO, Unit]): IO[(Boolean, Boolean)] =
p.take(Key).use { managed =>
val connection = managed.value
for {
status1 <- connection.isOpen.get
_ <- IO.println("awaiting inner")
_ <- innerAwait.complete(())
_ <- IO.println("awaiting outer")
_ <- outerAwait.get // wait for the signal from the outside
_ <- IO.println("after awaits")
status2 <- connection.isOpen.get // isOpen should be 'false' there
// _ <- IO.never[Unit] // once uncommented the program will hang
} yield (status1, status2)
}
for {
await <- IO.deferred[Unit]
fiber <- job(await).start
_ <- await.get // make sure first part happens inside of the open pool
} yield fiber
}
for {
await <- IO.deferred[Unit]
fiber <- example(await)
_ <- await.complete(()) // pool is closed and we continue execution of the job
outcome <- fiber.join
(status1, status2) <- outcome.embedNever
_ <- IO.println(s"(pool open): is connection open $status1")
_ <- IO.println(s"(pool closed): is connection open $status2")
} yield ()
Output:
created Connection@76426537
awaiting inner
awaiting outer
pool was closed
after awaits
destroyed Connection@76426537
(pool open): is connection open true
(pool closed): is connection open true
Expected output:
created Connection@76426537
awaiting inner
awaiting outer
destroyed Connection@76426537
pool was closed
after awaits
(pool open): is connection open true
(pool closed): is connection open false
- 主要言語
- Scala
- スター
- 40
- フォーク
- 19
- 平均マージ
- 15日 2時間
- マージ済み PR(30日)
- 3
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
typelevel/keypool のほかの issue
-
PoolSpec flakeオープン
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
-
commons-pool2 parity
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
commons-pool2 parity
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
bug
難易度 3/5 1〜2日 初心者へのやさしさ 42/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
typelevel/keypool の issue をすべて見る
似ている issue
-
Module: Form Builder
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
orbeon/orbeon-forms#7943 ·
メンテナーはふだん 2 日以内に返信
-
module: core
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
bigbluebutton/bigbluebutton#26028 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Philippus/sbt-dotenv#355 ·
-
LFSR.tapsMaxPeriod: 17 second tap sets (widths 725 to 755) are a single number larger than the widthオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
chipsalliance/chisel#5512 ·
メンテナーはふだん 2 日以内に返信
-
難易度 1/5 1〜3時間 初心者へのやさしさ 86/100
lunduniversity/introprog#995 ·
メンテナーはふだん 1 日以内に返信