Releases: typelevel/cats-effect
v3.2.4
Update: This release introduced a regression in the work-stealing thread pool. This regression is fixed in 3.2.5, and it is strongly recommended that users not depend on 3.2.4.
This is the tenth major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release, and fully source-compatible with every 3.2.x release.
User-Facing Pull Requests
- #2264 – Fix batched queue starvation (@vasilmkd)
- #2249 – Binpack continuations stack to improve memory density (@viktorklang)
- #2254 – Check
WorkerThread
ownership before scheduling (@vasilmkd) - #2237 – Swap
Thenable
forPromise
inAsync.fromPromise
(@armanbilge)
Thank you so very much, all of you!
v3.2.3
This is the ninth major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release, and fully source-compatible with every 3.2.x release.
Notable Changes
The main new feature of this release is the support for programmatically generating IO
runtime tracing information through the IO.trace
constructor, courtesy of @alexandrustana.
As always, this Cats Effect 3 release brings important bug-fixes and performance improvements. Namely, an oversight in the implementation of the improved par
operators from the 3.2.2 release, which could lead to nonterminating code in the face of concurrent errors, has been successfully identified and fixed.
Furthermore, a surprising Scala 3 regression which pertains to the conversion process of => A
thunks to () => A
(Function0
) instances, and its effect on IO.delay
constructor tracing was identified by @armanbilge. An elegant cross-platform solution has been implemented, which ultimately resulted in bringing the regressed performance of Scala 3 thunks back to the expected Scala 2 levels of performance.
We thank our tireless contributors for their outstanding work and we hope that you enjoy this release.
User-Facing Pull Requests
- #2174, #2227 – Add support for generating
IO
runtime traces usingIO.trace
(@alexandrustana, @vasilmkd) - #2226 – Fix cached tracing support for
IO.delay
and improveIO.delay
performance on Scala 3 (@armanbilge) - #2239 – Fix nontermination issue in
par
operators (@djspiewak) - #2208, #2213, #2232 – Documentation fixes and improvements (@bplommer, @vasilmkd)
Special thanks to each and every one of you! You are all awesome!
v3.2.2
This is the eighth major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release, and fully source-compatible with every 3.2.x release.
Notable Changes
This release brings Cats Effect 3 tracing exception enhancement to match the exception augmentation behavior of Cats Effect 2. Essentially, any raised or caught Exception
inside the Cats Effect 3 runtime is augmented. This allows higher level error recovery combinators to still have access to an Exception
enhanced with IO
tracing information, instead of the initial CE3 behavior where only unhandled exceptions were augmented.
This release also brings important bug fixes and library improvements. The cats.effect.unsafe.implicits.global
IORuntime
instance initialization behavior has been relaxed from a fatal error to a System.err
warning message. The Scala.js runtime polyfill discovery process has been improved to handle tricky cases in environments such as jsdom
. This environment has also been added to the Cats Effect test matrix and tested continuously in the CI.
Last but not least, this release increases the ScalJS version to 1.7.0.
User-Facing Pull Requests
- #2192 – Update Scala.js to version 1.7.0 (@scala-steward)
- #2191 – Test Cats Effect on
jsdom
and fixes to polyfill discovery (@armanbilge) - #2202 – Relax
global
IORuntime
initialization fatal error to a warning (@djspiewak) - #2203 – Always augment raised exceptions in the Cats Effect runtime (@vasilmkd)
- #2180, #2182, #2183, #2186, #2199 – Updates to documentation for new releases, various build and tests changes (@djspiewak, @vasilmkd)
Special thanks to each and every one of you! You are all awesome!
v2.5.3
This is the sixteenth major release in the Cats Effect 2.x lineage. It is fully binary compatible with all 2.x.y
releases.
This release deprecates IO.suspend
and SyncIO.suspend
in favor of IO.defer
and SyncIO.defer
respectively. This helps bring the Cats Effect 2 syntax closer to the new naming used in Cats Effect 3, which should aid the migration. Scalafix rewrite rules are also available.
User-Facing Pull Requests
- #2169 Add
IO.defer
,SyncIO.defer
, deprecateIO.suspend
,SyncIO.suspend
and add scalafix migrations (@vasilmkd) - Bring library versions up to date in documentation (@djspiewak)
v3.2.1
This is the seventh major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release, and fully source-compatible with every 3.2.x release.
Notable Changes
This release brings a new data type to the cats.effect.std
palette of concurrent data types, Backpressure
, which can be used to apply basic support for backpressure to the execution of a given effect. It comes equipped with a couple of execution strategies for a more customizable experience. Users can also take advantage of the added custom syntax which can be found by importing cats.effect.std.syntax.all._
.
Other behind the scenes improvements include added support for browser web workers, which brings substantial performance improvements for Scala.js IO
programs on browsers which support this feature.
Finally, this release also includes important bug fixes and performance improvements. A peculiar stack-safety issue has been fixed for long parTraverse
chains in combination with the Kleisli
monad transformer. We have used this opportunity to also improve the performance of the parTraverse
combinator, whose simpler implementation for parallel data types now allocates far fewer short-lived objects, resulting in noticeable performance improvements, especially in shorter-length sequences.
User-Facing Pull Requests
- #1817, #2163 -
Backpressure
concurrent data type (@etspaceman) - #2160 -
Backpressure
syntax (@armanbilge) - #2154 - Concepts documentation page cleanup (@djspiewak)
- #2167 - Add
ParallelBenchmark
(@manufacturist) - #2150, #2165, #2173 - Web worker polyfill implementation and testing (@armanbilge)
- #2159 -
map2/map2Eval
optimization for parallel data types (@manufacturist) - #2159 -
Kleisli
parTraverse
stack-safety fix (@vasilmkd and @djspiewak)
Special thanks to each and every one of you! You are all awesome!
v2.5.2
This is the fifteenth major release in the Cats Effect 2.x lineage. It is fully binary compatible with all 2.x.y
releases.
This release brings stack safety bug fixes in long traverse
and parTraverse
chains for IO
and Resource
in
combination with the Kleisli
monad transformer.
User-Facing Pull Requests
- #1990 – Add support for Scala 2.13.6 (@vasilmkd)
- #2016 – Add support for Scala 2.12.14 (@vasilmkd)
- #2053 – Update Scala.js to version 1.6.0 (@vasilmkd)
- #2112 – Add support for Scala 3.0.1 (@vasilmkd)
- #2157 – Fix stack safety in long
traverse
andparTraverse
Kleisli
chains forIO
andResource
(@vasilmkd)
Special thanks to Vasil for doing literally everything.
v3.2.0
This is the sixth major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release, and fully source-compatible with every 3.2.x release.
This release sees several major improvements and fixes to the library, but despite that, most of the pull requests in this release cycle were focused on improving documentation and general library convenience. We've made a lot of progress in this area but there's still plenty of work to do; come join us! Writing a bit of scaladoc or contributing a paragraph of explanation to the website is a great way to dip your toes into contribution, as the many invaluable authors in this release cycle can attest.
Notable Changes
Fixes for guarantee
(and bracket
) When Used with Monad Transformers
In previous versions, guaranteeCase
(and by extension, bracketCase
) was inconsistent with Fiber#join
, despite the fact that both produce an Outcome
representing the results of some effect. This inconsistency was particularly jarring when observed through the lens of monad transformers which have internal short-circuiting, such as OptionT
or EitherT
. The following snippet demonstrates the problem quite succinctly:
import cats.data.OptionT
import cats.effect._
import cats.effect.syntax.all._
OptionT.none[IO, Unit].guarantee(OptionT.liftF(IO.println("guaranteed?"))) >>
OptionT.liftF(IO.println("definitely not"))
On Cats Effect 3.1.1 and earlier, the above snippet would print nothing at all. The fact that "definitely not" fails to print is probably intuitive: after all, calling flatMap
on None
is equivalent to None
, which is to say the flatMap
is "skipped". However, the fact that guarantee
was decidedly not "guaranteed" was a little weird, and in some cases, could actually result in deadlocks.
This was an oversight in implementation. In fact, the design of Outcome
was always intended to take this possibility into account; it is the reason that Outcome.Succeeded
contains an F[A]
rather than just an A
. Fiber#join
leverages this design, but guaranteeCase
was never adjusted to do so.
This oversight has now been corrected, and a new set of laws relating guaranteeCase
and Fiber#join
have been added. These laws codified a set of assumptions that were already generally being made by consumers of the library (the authors included!), and thus they strengthen the guarantees around Cats Effect's semantics rather than making any changes to them. These added laws also have the effect of clarifying the intended semantics of more complex compound effect types (such as monad transformers or polyfunctorial constructors), which should improve compatibility between such types and the vast middleware ecosystem (such as Fs2).
Experimental async
/await
Syntax
Thanks to the tireless work of @Baccata, Cats Effect has added a new incubator library which implements async
/await
syntax for all types which form an Async
(including IO
). This incubator can be found in the typelevel/cats-effect-cps library. Depending on user adoption and feedback, as well as the ongoing work on the Scala 3 compiler, this functionality will likely be added to the Cats Effect core distribution at some point in the future.
async
/await
syntax has seen a surge of popularity across many language ecosystems in recent years, with JavaScript's implementation being the most notable. Roughly speaking, it is an alternative to for
-comprehensions in which imperative statement flow is rewritten into flatMap
(and similar). For example:
async[IO] {
IO.print("Enter your age: ").await
if (IO.readLine.await.toInt % 2 == 0)
IO.println("You're an even number of years old!").await
else
IO.println("Unfortunately, your age is very odd").await
}
The above is equivalent to the following written in a more direct style:
val init = IO.print("Enter your age: ") >> IO.readLine
init flatMap { ageS =>
val age = ageS.toInt
if (age % 2 == 0)
IO.println("You're an even number of years old!")
else
IO.println("Unfortunately, your age is very odd")
}
This syntax is supported on Scala 2 using the -Xasync
compiler flag, and on Scala 3 through the use of @rssh's dotty-cps-async library. Let us know what you think!
Fiber Tracing and Enhanced Exceptions
One of the most popular features ever added to Cats Effect 2 was support for asynchronous fiber tracing, and in particular, the automatic enhancement of exception stack traces that came along with it. Building on the original work of @RaasAhsan, @vasilmkd has now brought this functionality to Cats Effect 3, and in the process further improved and optimized its implementation.
Exception in thread "main" java.lang.Throwable: Boom!
at Example$.$anonfun$program$5(Main.scala:25)
at apply @ Example$.$anonfun$program$3(Main.scala:24)
at ifM @ Example$.$anonfun$program$3(Main.scala:25)
at map @ Example$.$anonfun$program$3(Main.scala:24)
at apply @ Example$.$anonfun$program$1(Main.scala:23)
at flatMap @ Example$.$anonfun$program$1(Main.scala:23)
at apply @ Example$.fib(Main.scala:13)
at flatMap @ Example$.fib(Main.scala:13)
at apply @ Example$.fib(Main.scala:13)
at flatMap @ Example$.fib(Main.scala:13)
In particular, one limitation of the Cats Effect 2 tracing implementation is that it is prone to classloader leaks when using it with frameworks like OSGi. This issue has been eliminated in the reimplementation of this functionality by leveraging java.lang.ClassValue
(a concurrent hashtable specialized to java.lang.Class
keys). Several additional features have been added, including significant optimizations to the full tracing mode.
As in Cats Effect 2, the performance impact of tracing is extremely minimal, but still measurable in synthetic benchmarks. For this reason, tracing defaults to on if not reconfigured by setting -Dcats.effect.tracing.mode=none
when launching the application process. You can read more details on the Tracing documentation page.
User-Facing Pull Requests
- #2148 – More efficient
IO#foreverM
(@armanbilge) - #2134 – Add method forwarders to
Resource
(@alexandrustana) - #2143 – Grow and shrink the error callback hashtable (@vasilmkd)
- #2145 – Add
flatTap
toIO
(@armanbilge) - #2126 – Reimplement
IO#guaranteeCase
andIO.bracketFull
(@vasilmkd) - #2107 – Fix
MonadCancel#guaranteeCase
for transformers and harden with new laws (@djspiewak) - #2114 – Added private functions for resetting the global runtime (@djspiewak)
- #2105 – Add syntax for
Supervisor
(@armanbilge) - #2093 – Add
unsafeToPromise
and friends toDispatcher
(@armanbilge) - #1953 – Translate
SyncIO
toF[_]: Sync
(@vasilmkd) - #1772 – Implement
UUIDGen
capability trait (@Wosin) - #1897 – Add
printStackTrace
toConsole
(@kubukoz) - #1903 – Added some convenience methods to
Outcome
(@davidabrahams) - #1923 – Testing utility method to check that
StackOverflowError
is reproducible (@nikitapecasa) - #1945 –
IO#syncStep
(@vasilmkd) - #2101 – Override
map2Eval
forIO
(@vasilmkd) - #2084 – Small, mostly cosmetics changes to
Resource.both
(@igstan) - #2076 – Remove custom
Order
code already released in Cats (@vasilmkd) - #2064 – Port the
StripedHashtableSpec
to ScalaJS (@vasilmkd) - #2147, #2065, #2051 – Tracing (@RaasAhsan, @vasilmkd, @djspiewak)
- #2048 – Load fields into local variables when using them multiple times (@vasilmkd)
- #2041 – Rewrite and improve
ThreadSafeHashtable
(@vasilmkd) - #2010 – Lazy initialization of array based stacks (@vasilmkd)
- #1958 – Added
ResourceApp
(@RaasAhsan) - #1996 – Get rid of the giant
try
/catch
block inIOFiber
(@vasilmkd) - #1980 – Add explicit return type to
IO.interruptible
andIO#attempt
(@lorandszakacs) - #2140, #2132, #2128, #2120, #2106, #2087, #2083, #2080, #2040, #2071, #2070, #2063, #2030, #2019, #2018, #2015, #1991, #1977, #1988, #1986, #1973 – Miscellaneous documentation improvements (@djspiewak, @vasilmkd, @TimWSpence, @igstan, @Baccata, @arosien, @armanbilge, @balthz, @slice, @bastewart, @kubukoz, @tototoshi, @dangerousben, @paualarco)
Special thanks to each and every one of you!
v3.1.1
This is the fifth major release in the Cats Effect 3.x lineage. It is fully binary compatible with every 3.x release. It is fully source-compatible with every release in the 3.1.x lineage (with a small caveat that a leaked internal implementation detail was hidden from the public IORuntimeConfig
API, we hope that this does not cause trouble for anyone).
The primary focus of this release are substantial performance improvements to the IO
interop with the outside world (unsafeRun
methods), thanks to the outstanding work of @RafalSumislawski, SyncIO
API fixes, as well as some minor thread scheduling improvements in the face of blocking code running on the work stealing compute thread pool.
The long awaited migration guide by the tireless @kubukoz has been finally published. We cannot wait to hear your feedback.
Alongside these changes come the improvements to the project documentation and the tutorial on the website, including updated links to the new Typelevel Discord server.
Finally, this release brings Cats Effect 3 into the Scala 3.0.0 final world. We hope that you enjoy it.
User-Facing Pull Requests
- #1913 – Add striped locks to the
IORuntime
custom fiber callback hashtable (@vasilmkd) - #1879 – The "Dealing with cancelation" section of the documentation has been change to not include Semaphores anymore (@lrodero)
- #1687 – The great Cats Effect 3 Migration Guide (@kubukoz)
- #1935 #1937 – Intricate performance tuning of the
IORuntime
custom fiber callback hashtable (@RafalSumislawski) - #1880, #1941 – Build and test Cats Effect 3 against the latest JDK versions (@vasilmkd)
- #1943 – Hide leaked internal implementation detail from the public
IORuntimeConfig
API (@vasilmkd) - #1938 – Performance optimization for running externally submitted
Runnable
instances on the work stealing thread pool (@vasilmkd) - #1928 – Scheduling improvements when running blocking code on the work stealing thread pool (@vasilmkd)
- #1947 – Fix
SyncIO#>>
to take a by-name parameter (@vasilmkd) - #1921 – Documentation of cancelation boundaries (@TimWSpence)
- #1951, #1952 – Add a badge for the Typelevel Discord server (@paualarco)
- #1967 – Scala 3.0.0 support (dropped support for Scala 3.0.0-RC2 and 3.0.0-RC3) (@larsrh)
Special thanks to each and every one of you! You are all amazing.
v2.5.1
This is the fourteenth major release in the Cats Effect 2.x lineage. It is fully binary compatible with all 2.x.y releases.
This release brings support for Scala 3.0.0 final to Cats Effect 2.x. We hope that you enjoy it.
- #1926, #1961 – Version updates to the
sbt
build plugins (@vasilmkd) - #1946, #1949 –
sbt
update and rewriting of deprecatedsbt
syntax (@vasilmkd) - #1966 – Scala 3.0.0 support (dropped support for Scala 3.0.0-RC2 and 3.0.0-RC3) (@larsrh)
Special thanks to all of you!
v3.1.0
This release is fully backwards compatible with everythin in the 3.x lineage. It is fully source-compatible with everything in the 3.1.x lineage. The primary focus of this release are some minor refinements as well as the addition of Scala 3.0.0-RC3 support (and the associated upgrade to Cats 2.6.0).
User-Facing Pull Requests
- #1915 – Updated to Scala 3.0.0-RC3 (@djspiewak)
- #1850 – Add
Random
materializers for monad transformers (@alexandrustana) - #1836 – Add
IO#unsafeToFutureCancelable
(@vasilmkd) - #1910, #1909, #1900 – Documentation fixes and updates (@LLCampos, @vasilmkd)
Special thanks to each and every one of you!