Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/evolution-gaming/akka-effect
Cats-Effect & Akka interop
https://github.com/evolution-gaming/akka-effect
akka cats cats-effect scala
Last synced: 10 days ago
JSON representation
Cats-Effect & Akka interop
- Host: GitHub
- URL: https://github.com/evolution-gaming/akka-effect
- Owner: evolution-gaming
- License: mit
- Created: 2019-03-20T14:31:04.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-29T11:51:35.000Z (2 months ago)
- Last Synced: 2024-10-29T13:31:54.665Z (2 months ago)
- Topics: akka, cats, cats-effect, scala
- Language: Scala
- Homepage:
- Size: 1.13 MB
- Stars: 55
- Watchers: 13
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Akka-Effect
[![Build Status](https://github.com/evolution-gaming/akka-effect/workflows/CI/badge.svg)](https://github.com/evolution-gaming/akka-effect/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/evolution-gaming/akka-effect/badge.svg)](https://coveralls.io/r/evolution-gaming/akka-effect)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/42b363aa8ad54f569c4eb62831db5eeb)](https://app.codacy.com/gh/evolution-gaming/akka-effect/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Version](https://img.shields.io/badge/version-click-blue)](https://evolution.jfrog.io/artifactory/api/search/latestVersion?g=com.evolutiongaming&a=akka-effect-actor_2.13&repos=public)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellowgreen.svg)](https://opensource.org/licenses/MIT)This project aims to build a bridge between [akka](https://akka.io) and pure functional code based on [cats-effect](https://typelevel.org/cats-effect)
Covered:
* [Actors](https://doc.akka.io/docs/akka/current/actors.html)
* [Persistence](https://doc.akka.io/docs/akka/current/persistence.html)## Building blocks
### `akka-effect-actor` module
#### [Tell.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/Tell.scala)
Represents `ActorRef.tell`
```scala
trait Tell[F[_], -A] {def apply(a: A, sender: Option[ActorRef] = None): F[Unit]
}
```#### [Ask.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/Ask.scala)
Represents `ActorRef.ask` pattern
```scala
trait Ask[F[_], -A, B] {def apply(msg: A, timeout: FiniteDuration, sender: Option[ActorRef]): F[B]
}
```#### [Reply.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/Reply.scala)
Represents reply pattern: `sender() ! reply`
```scala
trait Reply[F[_], -A] {def apply(msg: A): F[Unit]
}
```#### [Receive.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/Receive.scala)
This is what you need to implement instead of familiar `new Actor { ... }`
```scala
trait Receive[F[_], -A, B] {def apply(msg: A): F[B]
def timeout: F[B]
}
```#### [ActorOf.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/ActorOf.scala)
Constructs `Actor.scala` out of `receive: ActorCtx[F] => Resource[F, Receive[F, Any]]`
#### [ActorCtx.scala](actor/src/main/scala/com/evolutiongaming/akkaeffect/ActorCtx.scala)
Wraps `ActorContext`
```scala
trait ActorCtx[F[_]] {def self: ActorRef
def parent: ActorRef
def executor: ExecutionContextExecutor
def setReceiveTimeout(timeout: Duration): F[Unit]
def child(name: String): F[Option[ActorRef]]
def children: F[List[ActorRef]]
def actorRefFactory: ActorRefFactory
def watch[A](actorRef: ActorRef, msg: A): F[Unit]
def unwatch(actorRef: ActorRef): F[Unit]
def stop: F[Unit]
}
```### `akka-effect-persistence` module
#### [PersistentActorOf.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/PersistentActorOf.scala)
Constructs `PersistentActor.scala` out of `eventSourcedOf: ActorCtx[F] => F[EventSourced[F, S, E, C]]`
#### [EventSourced.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/EventSourced.scala)
Describes a lifecycle of entity with regard to event sourcing, phases are: Started, Recovering, Receiving and Termination
```scala
trait EventSourced[F[_], S, E, C] {def eventSourcedId: EventSourcedId
def recovery: Recovery
def pluginIds: PluginIds
def start: Resource[F, RecoveryStarted[F, S, E, C]]
}
```#### [RecoveryStarted.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/RecoveryStarted.scala)
Describes start of recovery phase
```scala
trait RecoveryStarted[F[_], S, E, C] {def apply(
seqNr: SeqNr,
snapshotOffer: Option[SnapshotOffer[S]]
): Resource[F, Recovering[F, S, E, C]]
}
```#### [Recovering.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/Recovering.scala)
Describes recovery phase
```scala
trait Recovering[F[_], S, E, C] {def replay: Resource[F, Replay[F, E]]
def completed(
seqNr: SeqNr,
journaller: Journaller[F, E],
snapshotter: Snapshotter[F, S]
): Resource[F, Receive[F, C]]
}
```#### [Replay.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/Replay.scala)
Used during recovery to replay events
```scala
trait Replay[F[_], A] {def apply(seqNr: SeqNr, event: A): F[Unit]
}
```#### [Journaller.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/Journaller.scala)
Describes communication with underlying journal
```scala
trait Journaller[F[_], -A] {def append: Append[F, A]
def deleteTo: DeleteEventsTo[F]
}
```#### [Snapshotter.scala](persistence/src/main/scala/com/evolutiongaming/akkaeffect/persistence/Snapshotter.scala)
Describes communication with underlying snapshot storage
```scala
/**
* Describes communication with underlying snapshot storage
*
* @tparam A - snapshot
*/
trait Snapshotter[F[_], -A] {def save(seqNr: SeqNr, snapshot: A): F[F[Instant]]
def delete(seqNr: SeqNr): F[F[Unit]]
def delete(criteria: SnapshotSelectionCriteria): F[F[Unit]]
}
```### `akka-effect-eventsourced` module
#### [Engine.scala](eventsourcing/src/main/scala/com/evolutiongaming/akkaeffect/eventsourcing/Engine.scala)
This is the main runtime/queue where all actions against your state are processed in desired eventsourcing sequence:
1. validate and finalize events
2. append events to journal
3. publish changed state
4. execute side effectsIt is optimised for maximum throughput hence different steps of different actions might be executed in parallel as well as events might be stored in batches
```scala
trait Engine[F[_], S, E] {def state: F[State[S]]
/**
* @return Outer F[_] is about `load` being enqueued, this immediately provides order guarantees
* Inner F[_] is about `load` being completed
*/
def apply[A](load: F[Validate[F, S, E, A]]): F[F[A]]
}
```## Setup
in [`build.sbt`](https://www.scala-sbt.org/1.x/docs/Basic-Def.html#What+is+a+build+definition%3F)
```scala
addSbtPlugin("com.evolution" % "sbt-artifactory-plugin" % "0.0.2")libraryDependencies += "com.evolutiongaming" %% "akka-effect-actor" % "0.2.1"
libraryDependencies += "com.evolutiongaming" %% "akka-effect-actor-tests" % "0.2.1"
libraryDependencies += "com.evolutiongaming" %% "akka-effect-persistence" % "0.2.1"
libraryDependencies += "com.evolutiongaming" %% "akka-effect-eventsourcing" % "0.2.1"
libraryDependencies += "com.evolutiongaming" %% "akka-effect-cluster" % "0.2.1"
libraryDependencies += "com.evolutiongaming" %% "akka-effect-cluster-sharding" % "0.2.1"
```