-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathJournaller.scala
96 lines (67 loc) · 2.3 KB
/
Journaller.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.evolutiongaming.akkaeffect.persistence
import cats.{Applicative, FlatMap, Monad, ~>}
import com.evolutiongaming.akkaeffect.Fail
import com.evolutiongaming.catshelper.{Log, MeasureDuration, MonadThrowable}
/** Describes communication with underlying journal
*
* @tparam A
* event
*/
trait Journaller[F[_], -A] {
/** @see
* [[akka.persistence.PersistentActor.persistAllAsync]]
*/
def append: Append[F, A]
/** @see
* [[akka.persistence.Eventsourced.deleteMessages]]
* @return
* outer F[_] is about deletion in background, inner F[_] is about deletion being completed
*/
def deleteTo: DeleteEventsTo[F]
}
object Journaller {
def empty[F[_]: Applicative, A]: Journaller[F, A] =
Journaller(Append.empty[F, A], DeleteEventsTo.empty[F])
def apply[F[_], A](
append: Append[F, A],
deleteEventsTo: DeleteEventsTo[F],
): Journaller[F, A] = {
val append1 = append
class Main
new Main with Journaller[F, A] {
def append = append1
def deleteTo = deleteEventsTo
}
}
sealed abstract private class Narrow
sealed abstract private class Convert
sealed abstract private class MapK
sealed abstract private class WithFail
implicit class JournallerOps[F[_], A](val self: Journaller[F, A]) extends AnyVal {
def mapK[G[_]: Applicative](f: F ~> G): Journaller[G, A] =
new MapK with Journaller[G, A] {
def append = self.append.mapK(f)
def deleteTo = self.deleteTo.mapK(f)
}
def convert[B](f: B => F[A])(implicit F: Monad[F]): Journaller[F, B] =
new Convert with Journaller[F, B] {
val append = self.append.convert(f)
def deleteTo = self.deleteTo
}
def narrow[B <: A]: Journaller[F, B] =
new Narrow with Journaller[F, B] {
val append = self.append.narrow[B]
def deleteTo = self.deleteTo
}
def withLogging1(log: Log[F])(implicit
F: FlatMap[F],
measureDuration: MeasureDuration[F],
): Journaller[F, A] =
Journaller(self.append.withLogging1(log), self.deleteTo.withLogging1(log))
def withFail(fail: Fail[F])(implicit F: MonadThrowable[F]): Journaller[F, A] =
new WithFail with Journaller[F, A] {
val append = self.append.withFail(fail)
val deleteTo = self.deleteTo.withFail(fail)
}
}
}