typelevel / typelevel/cats-effect

"`cedeMap`" and "`intercede`" combinators

Open
#3,318 2 comments 0 reactions 1 assignee View on GitHub

@biuld is already working on this.

Since Jan 8, 2023.

:mushroom: enhancement
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.

https://github.com/typelevel/cats-effect/blob/832079aecbbf956fb18f11392cfeec6cdaa52915/core/shared/src/main/scala/cats/effect/CpuStarvationCheck.scala#L43-L44

How to do this is described in the scaladocs for cede.

https://github.com/typelevel/cats-effect/blob/52b5a3ba1623ff40fc48318c9a0bfae558f0e5ed/kernel/shared/src/main/scala/cats/effect/kernel/GenSpawn.scala#L263-L269

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

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.