Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

take can silently drop a pooled resource when cancelled

Open
#708 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
scala
Domain
backend

Research direction

Start at KeyPool.take, particularly the kpVar.modify(go), Resource.makeFull, and Resource.fold sequence described in the issue. Run the linked takecancelspec.scala reproduction and verify that cancellation cannot lose the pooled resource or skip its destroy hook, while permit release and idle-count behavior remain correct.

Written by the indexing model from the issue text.

Description

KeyPool.take can lose a pooled resource entirely if the caller is cancelled at the wrong moment. The resource is neither destroyed nor returned to the pool, so whatever it wraps leaks.

The resource comes out of the pool map here:

optR <- Resource.eval(kp.kpVar.modify(go))
releasedState <- Resource.eval(Ref[F].of[Reusable](kp.kpDefaultReuseState))
resource <- Resource.makeFull[F, (B, F[Unit])] { poll => ... }

Resource.fold interprets Eval as a plain fa.flatMap(...), no bracket and no mask, and all of this sits in the permit's polled use position. So between modify(go) committing and makeFull entering its uncancelable region, the resource exists only in a flatMap continuation. Cancel there and it's gone.

The annoying part is that nothing looks broken afterwards. The permit is released correctly and the idle count is decremented correctly, so pool state stays consistent. You just lose the resource without the destroy hook ever running, which is why this shows up as leaked file descriptors with nothing in the pool metrics to explain it.

Repro: https://gist.github.com/stasimus/3d9b0d6eedcae885b410cac0a7e040dd#file-takecancelspec-scala

Not reachable under TestControl. take is straight-line between the modify and the bracket, so a deterministic single-threaded scheduler never interleaves a cancel there. 500 replications, zero hits.

Dominant language
Scala
Stars
39
Forks
18
Avg merge
8h 26m
Merged PRs (30d)
4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from typelevel/keypool

All issues in typelevel/keypool

Similar issues

More Scala issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.