Skip to content

Instantly share code, notes, and snippets.

@matfournier
Created March 29, 2020 23:23
Show Gist options
  • Save matfournier/6f1c3dec8a754fe86882cde01bcc593b to your computer and use it in GitHub Desktop.
Save matfournier/6f1c3dec8a754fe86882cde01bcc593b to your computer and use it in GitHub Desktop.
Wrapping legacy blocking / context shift / blocker
trait Statsd[F[_]] {
def inc(key: String, magnitude: Int = 1, sampleRate: Double = 1.0): F[Unit]
def dec(key: String, magnitude: Int = 1, sampleRate: Double = 1.0): F[Unit]
def gauge(key: String, magnitude: Double, sampleRate: Double = 1.0): F[Unit]
def timer(key: String, value: Int, sampleRate: Double = 1.0): F[Unit]
}
object Statsd {
def apply[F[_]](implicit F: Statsd[F]): Statsd[F] = F
}
class UdpCatsStatsd[F[_]: Sync : ContextShift](
private val client: UdpStatsdClient,
blocker: Blocker
) extends Statsd[F] {
def inc(key: String, magnitude: Int = 1, sampleRate: Double = 1.0): F[Unit] =
blocker.delay[F, Unit](client.inc(key, magnitude, sampleRate))
def dec(key: String, magnitude: Int, sampleRate: Double): F[Unit] =
blocker.delay[F, Unit](client.dec(key, magnitude, sampleRate))
def gauge(key: String, magnitude: Double, sampleRate: Double): F[Unit] =
blocker.delay[F, Unit](client.gauge(key, magnitude, sampleRate))
def timer(key: String, value: Int, sampleRate: Double): F[Unit] =
blocker.delay[F, Unit](client.timer(key, value, sampleRate))
}
object UdpCatsStatsd {
def make[F[_]: Sync : ContextShift](config: Config, blocker: Blocker): Resource[F, UdpCatsStatsd[F]] =
Resource(Sync[F].delay {
val executor = Executors.newFixedThreadPool(1)
val ec = ExecutionContext.fromExecutor(executor)
val underlyingClient = new UdpStatsdClient(config, Some(ec))
val wrappedClient = new UdpCatsStatsd[F](underlyingClient, blocker)
(wrappedClient, Sync[F].delay(executor.shutdown()))
})
}
class NoOpStatsd[F[_]: Applicative] extends Statsd[F] {
def inc(key: String, magnitude: Int, sampleRate: Double): F[Unit] =
Applicative[F].pure(())
def dec(key: String, magnitude: Int, sampleRate: Double): F[Unit] =
Applicative[F].pure(())
def timer(key: String, value: Int, sampleRate: Double): F[Unit] =
Applicative[F].pure(())
def gauge(key: String, magnitude: Double, sampleRate: Double): F[Unit] =
Applicative[F].pure(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment