Skip to content
An STM implementation for Cats Effect
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
core/src Use scalatest for property-based tests for consistent output (#23) May 21, 2019
docs/src/main Update latest version in sbt dependency snippet May 20, 2019
examples/src/main/scala/io/github/timwspence/cats/stm Add Santa Claus Problem (#16) May 8, 2019
project Add Santa Claus Problem (#16) May 8, 2019
.gitignore Refactor Build May 1, 2019
.scalafmt.conf Add rewrite rules to scalafmt Apr 25, 2019
.travis.yml
CHANGELOG.md Fix Website Generation and Add CoC (#6) May 2, 2019
CODE_OF_CONDUCT.md Fix Website Generation and Add CoC (#6) May 2, 2019
LICENSE.txt Add Apache license Apr 25, 2019
README.md Update latest version in sbt dependency snippet May 20, 2019
build.sbt Update scalatest to 3.0.8 (#28) Jun 11, 2019
version.sbt Setting version to 0.4.1-SNAPSHOT May 20, 2019

README.md

Cats STM

Build Status Join the chat at https://gitter.im/cats-stm/community

An implementation of Software Transactional Memory for Cats Effect, inspired by Beautiful Concurrency.

For more information, see the documentation.

Usage

libraryDependencies += "io.github.timwspence" %% "cats-stm" % "0.4.0"

The core abstraction is the TVar (transactional var), which exposes operations in the STM monad. Once constructed, STM actions can be atomically evaluated in the IO monad.

import cats.effect.{ExitCode, IO, IOApp}
import io.github.timwspence.cats.stm.{TVar, STM}

object Main extends IOApp {

  override def run(args: List[String]): IO[ExitCode] = for {
    accountForTim   <- TVar.of[Long](100).commit[IO]
    accountForSteve <- TVar.of[Long](0).commit[IO]
    _               <- printBalances(accountForTim, accountForSteve)
    _               <- giveTimMoreMoney(accountForTim).start
    _               <- transfer(accountForTim, accountForSteve)
    _               <- printBalances(accountForTim, accountForSteve)
  } yield ExitCode.Success

  private def transfer(accountForTim: TVar[Long], accountForSteve: TVar[Long]): IO[Unit] = for {
    _ <- STM.atomically[IO] {
      for {
        balance <- accountForTim.get
        _       <- STM.check(balance > 100)
        _       <- accountForTim.modify(_ - 100)
        _       <- accountForSteve.modify(_ + 100)
      } yield ()
    }
  } yield ()

  private def giveTimMoreMoney(accountForTim: TVar[Long]): IO[Unit] = for {
    _ <- IO(Thread.sleep(5000))
    _ <- STM.atomically[IO](accountForTim.modify(_ + 1))
  } yield ()

  private def printBalances(accountForTim: TVar[Long], accountForSteve: TVar[Long]): IO[Unit] = for {
    _ <- accountForTim.get.commit[IO].flatMap(b => IO(println(s"Tim: $b")))
    _ <- accountForSteve.get.commit[IO].flatMap(b => IO(println(s"Tim: $b")))
  } yield ()

}

Documentation

The documentation is built using sbt microsites. You can generate it via sbt makeMicrosite. You can view it locally via cd docs/target/site && jekyll serve.

Credits

This software was inspired by Beautiful Concurrency and informed by ZIO which has a common origin in that paper via the stm package.

You can’t perform that action at this time.