typelevel / typelevel/cats-effect
"`cedeMap`" and "`intercede`" combinators
@biuld is already working on this.
Since Jan 8, 2023.
- Dominant language
- Scala
- Stars
- 2.2k
- Forks
- 576
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 18
Description
Explicitly cede-ing between expensive compute-bound operations is one of the strategies for addressing CPU-starvation and is suggested in the warning.
How to do this is described in the scaladocs for cede.
Implementing that correctly is not completely trivial (*cough* https://github.com/typelevel/cats-effect/pull/3166 😜) and noisy enough that it probably deserves its own combinator.
In fact I think we need a couple combinators, depending on whether or not the expensiveWork() is in F[_] or not.
def cedeMap[A, B](fa: F[A])(f: A => B): F[B] =
(fa <* cede).map(a => f(a)).guarantee(cede)
def intercede[A](fa: F[A]): F[A] =
cede *> fa.guarantee(cede)
(Names subject to bikeshed.) These should also be added as syntax and on IO itself.
I think both variants are important, because for example the following would not achieve the desired semantics.
fa.flatMap(data => intercede(F.pure(expensiveWork(data))))
There, expensiveWork() would be computed eagerly when the pure(...) is constructed (before the cede), not when it is interpreted (after the cede).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.