Skip to content

Commit 03cd74c

Browse files
Merge pull request #122 from ChristopherDavenport/mapKImplementations
MapK implementations
2 parents 8969f06 + dcb8e90 commit 03cd74c

6 files changed

Lines changed: 107 additions & 21 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ tags
88

99
.bloop
1010
.metals
11+
project/metals.sbt
1112

1213
.vscode

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ lazy val commonSettings = Seq(
3737
organization := "io.chrisdavenport",
3838

3939
scalaVersion := "2.13.0",
40-
crossScalaVersions := Seq(scalaVersion.value, "2.12.9"),
40+
crossScalaVersions := Seq(scalaVersion.value, "2.12.10"),
4141

4242
scalacOptions in (Compile, doc) ++= Seq(
4343
"-groups",

core/src/main/scala/io/chrisdavenport/epimetheus/Counter.scala

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ sealed abstract class Counter[F[_]]{
5555
*
5656
*/
5757
def incBy(d: Double): F[Unit]
58+
59+
def mapK[G[_]](fk: F ~> G): Counter[G] = new Counter.MapKCounter[F, G](this, fk)
5860
}
5961

6062
/**
@@ -99,7 +101,7 @@ object Counter {
99101
): F[UnlabelledCounter[F, A]] = for {
100102
c <- Sync[F].delay(JCounter.build().name(name.getName).help(help).labelNames(labels.map(_.getLabel):_*))
101103
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
102-
} yield new UnlabelledCounter[F, A](out, f.andThen(_.unsized))
104+
} yield new UnlabelledCounterImpl[F, A](out, f.andThen(_.unsized))
103105

104106
private final class NoLabelsCounter[F[_]: Sync] private[Counter] (private[Counter] val underlying: JCounter) extends Counter[F] {
105107
override def get: F[Double] = Sync[F].delay(underlying.get)
@@ -115,25 +117,44 @@ object Counter {
115117
def incBy(d: Double): F[Unit] = Sync[F].delay(underlying.inc(d))
116118
}
117119

120+
private final class MapKCounter[F[_], G[_]](private[Counter] val base: Counter[F], fk: F ~> G) extends Counter[G]{
121+
def get: G[Double] = fk(base.get)
122+
def inc: G[Unit] = fk(base.inc)
123+
def incBy(d: Double): G[Unit] = fk(base.incBy(d))
124+
}
125+
118126
/**
119127
* Generic Unlabeled Counter
120128
*
121129
* It is necessary to apply a value of type `A` to this
122130
* counter to be able to take any measurements.
123131
*/
124-
final class UnlabelledCounter[F[_]: Sync, A] private[Counter](
132+
sealed trait UnlabelledCounter[F[_], A]{
133+
def label(a: A): Counter[F]
134+
def mapK[G[_]](fk: F ~> G): UnlabelledCounter[G, A] = new MapKUnlabelledCounter[F, G, A](this, fk)
135+
}
136+
137+
private final class UnlabelledCounterImpl[F[_]: Sync, A] private[Counter](
125138
private[Counter] val underlying: JCounter,
126139
private val f: A => IndexedSeq[String]
127-
) {
140+
) extends UnlabelledCounter[F, A]{
128141
def label(a: A): Counter[F] =
129142
new LabelledCounter(underlying.labels(f(a):_*))
130143
}
131144

145+
private final class MapKUnlabelledCounter[F[_], G[_], A](private[Counter] val base: UnlabelledCounter[F, A], fk: F ~> G) extends UnlabelledCounter[G, A]{
146+
def label(a: A): Counter[G] = base.label(a).mapK(fk)
147+
}
148+
132149
object Unsafe {
133-
def asJavaUnlabelled[F[_], A](c: UnlabelledCounter[F, A]): JCounter = c.underlying
150+
def asJavaUnlabelled[F[_], A](c: UnlabelledCounter[F, A]): JCounter = c match {
151+
case m: MapKUnlabelledCounter[_, _, _] => asJavaUnlabelled(m.base)
152+
case m: UnlabelledCounterImpl[_, _] => m.underlying
153+
}
134154
def asJava[F[_]: ApplicativeError[?[_], Throwable]](c: Counter[F]): F[JCounter] = c match {
135155
case _: LabelledCounter[F] => ApplicativeError[F, Throwable].raiseError(new IllegalArgumentException("Cannot Get Underlying Parent with Labels Applied"))
136156
case n: NoLabelsCounter[F] => n.underlying.pure[F]
157+
case b: MapKCounter[_, _] => asJava(b.base)
137158
}
138159
}
139160
}

core/src/main/scala/io/chrisdavenport/epimetheus/Gauge.scala

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ sealed abstract class Gauge[F[_]]{
6969
def incBy(d: Double): F[Unit]
7070

7171
def set(d: Double): F[Unit]
72+
73+
def mapK[G[_]](fk: F ~> G): Gauge[G] = new Gauge.MapKGauge[F, G](this, fk)
7274
}
7375

7476
/**
@@ -128,7 +130,7 @@ object Gauge {
128130
): F[UnlabelledGauge[F, A]] = for {
129131
c <- Sync[F].delay(JGauge.build().name(name.getName).help(help).labelNames(labels.map(_.getLabel):_*))
130132
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
131-
} yield new UnlabelledGauge[F, A](out, f.andThen(_.unsized))
133+
} yield new UnlabelledGaugeImpl[F, A](out, f.andThen(_.unsized))
132134

133135

134136
private final class NoLabelsGauge[F[_]: Sync] private[Gauge] (
@@ -159,26 +161,52 @@ object Gauge {
159161
def set(d: Double): F[Unit] = Sync[F].delay(underlying.set(d))
160162
}
161163

164+
private final class MapKGauge[F[_], G[_]](private[Gauge] val base: Gauge[F], fk: F ~> G) extends Gauge[G]{
165+
def get: G[Double] = fk(base.get)
166+
167+
def dec: G[Unit] = fk(base.dec)
168+
def decBy(d: Double): G[Unit] = fk(base.decBy(d))
169+
170+
def inc: G[Unit] = fk(base.inc)
171+
def incBy(d: Double): G[Unit] = fk(base.incBy(d))
172+
173+
def set(d: Double): G[Unit] = fk(base.set(d))
174+
}
175+
162176

177+
sealed trait UnlabelledGauge[F[_], A]{
178+
def label(a: A): Gauge[F]
179+
def mapK[G[_]](fk: F ~> G): UnlabelledGauge[G, A] = new MapKUnlabelledGauge[F, G, A](this, fk)
180+
}
163181

164182
/**
165183
* Generic Unlabeled Gauge
166184
*
167185
* It is necessary to apply a value of type `A` to this
168186
* gauge to be able to take any measurements.
169187
*/
170-
final class UnlabelledGauge[F[_]: Sync, A] private[epimetheus](
188+
final private class UnlabelledGaugeImpl[F[_]: Sync, A] private[epimetheus](
171189
private[Gauge] val underlying: JGauge,
172190
private val f: A => IndexedSeq[String]
173-
) {
191+
) extends UnlabelledGauge[F, A] {
174192
def label(a: A): Gauge[F] =
175193
new LabelledGauge[F](underlying.labels(f(a):_*))
176194
}
195+
196+
final private class MapKUnlabelledGauge[F[_], G[_], A](private[Gauge] val base: UnlabelledGauge[F, A], fk: F ~> G) extends UnlabelledGauge[G, A]{
197+
def label(a: A): Gauge[G] = base.label(a).mapK(fk)
198+
}
199+
200+
177201
object Unsafe {
178-
def asJavaUnlabelled[F[_], A](g: UnlabelledGauge[F, A]): JGauge = g.underlying
202+
def asJavaUnlabelled[F[_], A](g: UnlabelledGauge[F, A]): JGauge = g match {
203+
case x: UnlabelledGaugeImpl[_, _] => x.underlying
204+
case x: MapKUnlabelledGauge[_, _, _] => asJavaUnlabelled(x.base)
205+
}
179206
def asJava[F[_]: ApplicativeError[?[_], Throwable]](c: Gauge[F]): F[JGauge] = c match {
180207
case _: LabelledGauge[F] => ApplicativeError[F, Throwable].raiseError(new IllegalArgumentException("Cannot Get Underlying Parent with Labels Applied"))
181208
case n: NoLabelsGauge[F] => n.underlying.pure[F]
209+
case m: MapKGauge[_, _] => asJava(m.base)
182210
}
183211
}
184212
}

core/src/main/scala/io/chrisdavenport/epimetheus/Histogram.scala

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import cats.implicits._
77
import io.prometheus.client.{Histogram => JHistogram}
88
import scala.concurrent.duration._
99
import shapeless._
10+
import io.chrisdavenport.epimetheus.Histogram.UnlabelledHistogramImpl
11+
import io.chrisdavenport.epimetheus.Histogram.MapKUnlabelledHistogram
1012

1113
/**
1214
* Histogram metric, to track distributions of events.
@@ -26,6 +28,8 @@ sealed abstract class Histogram[F[_]]{
2628
*/
2729
def observe(d: Double): F[Unit]
2830

31+
def mapK[G[_]](fk: F ~> G): Histogram[G] = new Histogram.MapKHistogram[F, G](this, fk)
32+
2933
}
3034

3135
/**
@@ -203,7 +207,7 @@ object Histogram {
203207
.buckets(buckets:_*)
204208
)
205209
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
206-
} yield new UnlabelledHistogram[F, A](out, f.andThen(_.unsized))
210+
} yield new UnlabelledHistogramImpl[F, A](out, f.andThen(_.unsized))
207211

208212
def labelledLinearBuckets[F[_]: Sync, A, N <: Nat](
209213
cr: CollectorRegistry[F],
@@ -223,7 +227,7 @@ object Histogram {
223227
.linearBuckets(start, factor, count)
224228
)
225229
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
226-
} yield new UnlabelledHistogram[F, A](out, f.andThen(_.unsized))
230+
} yield new UnlabelledHistogramImpl[F, A](out, f.andThen(_.unsized))
227231

228232
def labelledExponentialBuckets[F[_]: Sync, A, N <: Nat](
229233
cr: CollectorRegistry[F],
@@ -243,7 +247,7 @@ object Histogram {
243247
.exponentialBuckets(start, factor, count)
244248
)
245249
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
246-
} yield new UnlabelledHistogram[F, A](out, f.andThen(_.unsized))
250+
} yield new UnlabelledHistogramImpl[F, A](out, f.andThen(_.unsized))
247251

248252
private final class NoLabelsHistogram[F[_]: Sync] private[Histogram] (
249253
private[Histogram] val underlying: JHistogram
@@ -258,26 +262,42 @@ object Histogram {
258262
def observe(d: Double): F[Unit] = Sync[F].delay(underlying.observe(d))
259263
}
260264

265+
private final class MapKHistogram[F[_], G[_]](private[Histogram] val base: Histogram[F], fk: F ~> G) extends Histogram[G]{
266+
def observe(d: Double): G[Unit] = fk(base.observe(d))
267+
}
268+
261269
/**
262270
* Generic UnlabelledHistorgram
263271
*
264272
* It is necessary to apply a value of type `A` to this
265273
* histogram to be able to take any measurements.
266274
*/
267-
final class UnlabelledHistogram[F[_]: Sync, A] private[Histogram] (
275+
sealed trait UnlabelledHistogram[F[_], A]{
276+
def label(a: A): Histogram[F]
277+
def mapK[G[_]](fk: F ~> G): UnlabelledHistogram[G, A] = new MapKUnlabelledHistogram[F, G, A](this, fk)
278+
}
279+
280+
final private class UnlabelledHistogramImpl[F[_]: Sync, A] private[Histogram] (
268281
private[Histogram] val underlying: JHistogram,
269282
private val f: A => IndexedSeq[String]
270-
) {
283+
) extends UnlabelledHistogram[F, A]{
271284
def label(a: A): Histogram[F] =
272285
new LabelledHistogram[F](underlying.labels(f(a):_*))
273286
}
274287

288+
final private class MapKUnlabelledHistogram[F[_], G[_], A](private[Histogram] val base: UnlabelledHistogram[F, A], fk: F ~> G) extends UnlabelledHistogram[G, A]{
289+
def label(a: A): Histogram[G] = base.label(a).mapK(fk)
290+
}
291+
275292
object Unsafe {
276-
def asJavaUnlabelled[F[_], A](h: UnlabelledHistogram[F, A]): JHistogram =
277-
h.underlying
293+
def asJavaUnlabelled[F[_], A](h: UnlabelledHistogram[F, A]): JHistogram = h match {
294+
case h: UnlabelledHistogramImpl[_, _] => h.underlying
295+
case h: MapKUnlabelledHistogram[_, _, _] => asJavaUnlabelled(h.base)
296+
}
278297
def asJava[F[_]: ApplicativeError[?[_], Throwable]](c: Histogram[F]): F[JHistogram] = c match {
279298
case _: LabelledHistogram[F] => ApplicativeError[F, Throwable].raiseError(new IllegalArgumentException("Cannot Get Underlying Parent with Labels Applied"))
280299
case n: NoLabelsHistogram[F] => n.underlying.pure[F]
300+
case h: MapKHistogram[_, _] => asJava(h.base)
281301
}
282302
}
283303

core/src/main/scala/io/chrisdavenport/epimetheus/Summary.scala

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ sealed abstract class Summary[F[_]]{
3232
* @param d The observation to persist
3333
*/
3434
def observe(d: Double): F[Unit]
35+
36+
def mapK[G[_]](fk: F ~> G): Summary[G] = new Summary.MapKSummary[F, G](this, fk)
3537
}
3638

3739

@@ -215,7 +217,7 @@ object Summary {
215217
)
216218
c <- Sync[F].delay(quantiles.foldLeft(c1){ case (c, q) => c.quantile(q.quantile, q.error)})
217219
out <- Sync[F].delay(c.register(CollectorRegistry.Unsafe.asJava(cr)))
218-
} yield new UnlabelledSummary[F, A](out, f.andThen(_.unsized))
220+
} yield new UnlabelledSummaryImpl[F, A](out, f.andThen(_.unsized))
219221

220222
final private class NoLabelsSummary[F[_]: Sync] private[Summary] (
221223
private[Summary] val underlying: JSummary
@@ -228,19 +230,30 @@ object Summary {
228230
def observe(d: Double): F[Unit] = Sync[F].delay(underlying.observe(d))
229231
}
230232

233+
final private class MapKSummary[F[_], G[_]](private[Summary] val base: Summary[F], fk: F ~> G) extends Summary[G]{
234+
def observe(d: Double): G[Unit] = fk(base.observe(d))
235+
}
236+
231237
/**
232238
* Generic Unlabeled Summary
233239
*
234240
* Apply a label to be able to measure events.
235241
*/
236-
final class UnlabelledSummary[F[_]: Sync, A] private[epimetheus](
242+
sealed trait UnlabelledSummary[F[_], A]{
243+
def label(a: A): Summary[F]
244+
def mapK[G[_]](fk: F ~> G): UnlabelledSummary[G, A] = new MapKUnlabelledSummary[F,G, A](this, fk)
245+
}
246+
final private class UnlabelledSummaryImpl[F[_]: Sync, A] private[epimetheus](
237247
private[Summary] val underlying: JSummary,
238248
private val f: A => IndexedSeq[String]
239-
) {
249+
) extends UnlabelledSummary[F,A]{
240250
def label(a: A): Summary[F] =
241251
new LabelledSummary[F](underlying.labels(f(a):_*))
242252
}
243253

254+
final private class MapKUnlabelledSummary[F[_], G[_], A](private[Summary] val base: UnlabelledSummary[F,A], fk: F ~> G) extends UnlabelledSummary[G, A]{
255+
def label(a: A): Summary[G] = base.label(a).mapK(fk)
256+
}
244257
/**
245258
* The percentile and tolerated error to be observed
246259
*
@@ -292,11 +305,14 @@ object Summary {
292305
}
293306

294307
object Unsafe {
295-
def asJavaUnlabelled[F[_], A](g: UnlabelledSummary[F, A]): JSummary =
296-
g.underlying
308+
def asJavaUnlabelled[F[_], A](g: UnlabelledSummary[F, A]): JSummary = g match {
309+
case a: UnlabelledSummaryImpl[_, _] => a.underlying
310+
case a: MapKUnlabelledSummary[_, _, _] => asJavaUnlabelled(a.base)
311+
}
297312
def asJava[F[_]: ApplicativeError[?[_], Throwable]](c: Summary[F]): F[JSummary] = c match {
298313
case _: LabelledSummary[F] => ApplicativeError[F, Throwable].raiseError(new IllegalArgumentException("Cannot Get Underlying Parent with Labels Applied"))
299314
case n: NoLabelsSummary[F] => n.underlying.pure[F]
315+
case b: MapKSummary[_, _] => asJava(b.base)
300316
}
301317
}
302318
}

0 commit comments

Comments
 (0)