Skip to content

Releases: TimWSpence/cats-stm

v0.10.0-RC1

18 Feb 10:15
Compare
Choose a tag to compare

Release candidates time!

This is a release tracking cats effect 3.0.0-RC2 and scala 3.0.0-RC1. Many thanks to the swift work of the maintainers of all of our dependencies for releasing faster than me!

v0.10.0-M3

01 Feb 17:27
0430388
Compare
Choose a tag to compare

A relatively small release with a few notable changes:

  • Support for 3.0.0-M3!
  • Fixed several bugs where error and retry handlers were not correctly lexically scoped
  • Removed the distributive law a.orElse(b) >>= f <-> (a >>= f).orElse(b >>= f) While a nice property, it is also a lie 🍰 Take a = stm.unit, b = stm.abort(new RuntimeException()), f = _ => stm.retry as a counterexample

v0.10.0-M2

14 Dec 11:45
Compare
Choose a tag to compare

A small release but with two exciting changes:

  1. Cross-building and publishing for Dotty!
  2. A rewrite of the pattern matching runloop we use to evaluate transactions. This was initially to make Dotty happy but enabled us to make this cats effect 3-inspired optimization which resulted in an ~20% performance improvement for eval (the core of our runloop which evaluates transactions lock-free)

v0.10.0-M1

09 Dec 11:44
Compare
Choose a tag to compare

This is a big release! (In fact, it's basically a from-scratch rewrite). Unfortunately it involves some source-incompatible changes but hopefully you'll agree the benefits are very much worth it! Highlights include:

  • 'Honest effect polymorphism': previously we could run STM.atomically[IO](txn1) and STM.atomically[OptionT[IO, *]](txn2) and run the risk of class-cast exceptions as we tracked state internally that was parameterized on F without that being tracked in the type system. Now the design looks like:
trait STM[F[_]] {
  class TVar[A] {
    def get: Txn[A]
  }

  trait Txn[A]

  def commit[A](txn: Txn[A]): F[A]
}

which means that a Txn is tied to the effect type of the STM instance which created it and hence safe

  • Stack-safe construction and evaluation of Txns
  • Fine-grained locking: when committing we only acquire a lock on the TVars that we are comitting, rather than a global lock, and hence can support a higher degree of parallelism
  • Fully semantic-blocking: one of the worst features of previous versions was that it would acquire a global lock via a blocking STM.synchronized - something you should never do on an IO thread. Now the implementation is entirely based on the Cats Effect semantically-blocking Ref and Semaphore abstractions
  • a MonadError[Txn, Throwable] instance which enables backtracking in a transaction eg
    for {
      tvar <- stm.commit(TVar.of(0))
      _ <- stm.commit(
        for {
          _ <- tvar.set(1)
          _ <- (tvar.modify(_ + 1) >> stm.abort(new RuntimeException("BOOM"))).handleErrorWith {
            case _ => tvar.modify(_ + 2)
          }
        } yield ()
      )
      v   <- stm.commit(tvar.get)
      res <- IO(assertEquals(v, 3))
    } yield res
  • Laws governing the interaction of the stm combinators
  • Support for Cats Effect 3! Unfortunately this release actually depends on some specifics of cats effect 3 so it has not (yet at least) been back-ported to cats effect 2. The expectation is that the non-milestone release will happen as soon as cats effect 3 is released
  • Defining a lot of derived cats combinators directly on Txn for convenience and discoverability in IDEs