cats.effect.Bracket Scala Examples

The following examples show how to use cats.effect.Bracket. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: NatchezHttp4sModule.scala    From skunk   with MIT License 8 votes vote down vote up
// Copyright (c) 2018-2020 by Rob Norris
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package natchez.http4s

import cats.~>
import cats.data.{ Kleisli, OptionT }
import cats.effect.Bracket
import cats.implicits._
import natchez.{ EntryPoint, Kernel, Span }
import org.http4s.HttpRoutes
import natchez.Trace
import natchez.Tags
import scala.util.control.NonFatal
import org.http4s.Response
import cats.effect.Resource
import cats.Defer
import natchez.TraceValue
import cats.Monad

object implicits {

  // Given an entry point and HTTP Routes in Kleisli[F, Span[F], ?] return routes in F. A new span
  // is created with the URI path as the name, either as a continuation of the incoming trace, if
  // any, or as a new root. This can likely be simplified, I just did what the types were saying
  // and it works so :shrug:
  private def liftT[F[_]: Bracket[?[_], Throwable]](
    entryPoint: EntryPoint[F])(
    routes:     HttpRoutes[Kleisli[F, Span[F], ?]]
  ): HttpRoutes[F] =
    Kleisli { req =>
      type G[A]  = Kleisli[F, Span[F], A]
      val lift   = λ[F ~> G](fa => Kleisli(_ => fa))
      val kernel = Kernel(req.headers.toList.map(h => (h.name.value -> h.value)).toMap)
      val spanR  = entryPoint.continueOrElseRoot(req.uri.path, kernel)
      OptionT {
        spanR.use { span =>
          val lower = λ[G ~> F](_(span))
          routes.run(req.mapK(lift)).mapK(lower).map(_.mapK(lower)).value
        }
      }
    }

  implicit class EntryPointOps[F[_]](self: EntryPoint[F]) {

    private def dummySpan(
      implicit ev: Monad[F]
    ): Span[F] =
      new Span[F] {
        val kernel: F[Kernel] = Kernel(Map.empty).pure[F]
        def put(fields: (String, TraceValue)*): F[Unit] = Monad[F].unit
        def span(name: String): Resource[F, Span[F]] = Monad[Resource[F, ?]].pure(this)
      }

    def liftT(routes: HttpRoutes[Kleisli[F, Span[F], ?]])(
      implicit ev: Bracket[F, Throwable]
    ): HttpRoutes[F] =
      implicits.liftT(self)(routes)

    
  def natchezMiddleware[F[_]: Bracket[?[_], Throwable]: Trace](routes: HttpRoutes[F]): HttpRoutes[F] =
    Kleisli { req =>

      val addRequestFields: F[Unit] =
        Trace[F].put(
          Tags.http.method(req.method.name),
          Tags.http.url(req.uri.renderString)
        )

      def addResponseFields(res: Response[F]): F[Unit] =
        Trace[F].put(
          Tags.http.status_code(res.status.code.toString)
        )

      def addErrorFields(e: Throwable): F[Unit] =
        Trace[F].put(
          Tags.error(true),
          "error.message"    -> e.getMessage,
          "error.stacktrace" -> e.getStackTrace.mkString("\n"),
        )

      OptionT {
        routes(req).onError {
          case NonFatal(e)   => OptionT.liftF(addRequestFields *> addErrorFields(e))
        } .value.flatMap {
          case Some(handler) => addRequestFields *> addResponseFields(handler).as(handler.some)
          case None          => Option.empty[Response[F]].pure[F]
        }
      }
    }

} 
Example 2
Source File: Guarantee.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu

import cats.effect.{Bracket, ExitCase}


  def finallyCase[A, B, C](init: F[A])(action: A => F[B])(release: (A, Exit[B]) => F[C]): F[B]
}

object Finally extends FinallyInstanceChain[Finally]

trait FinallyInstanceChain[T[f[_], exit[_]] >: Finally[f, exit]] {
  final implicit def fromBracket[F[_], E](implicit F: Bracket[F, E]): T[F, TConst[ExitCase[E], *]] =
    new Finally[F, TConst[ExitCase[E], *]] {
      def finallyCase[A, B, C](init: F[A])(action: A => F[B])(release: (A, ExitCase[E]) => F[C]): F[B] =
        F.bracketCase(init)(action) {
          case (a, exit) => F.void(release(a, exit))
        }
      def bracket[A, B, C](init: F[A])(action: A => F[B])(release: (A, Boolean) => F[C]): F[B]         =
        F.bracketCase(init)(action) {
          case (a, ExitCase.Completed) => F.void(release(a, true))
          case (a, _)                  => F.void(release(a, false))
        }
    }
} 
Example 3
Source File: package.scala    From puretracing   with Apache License 2.0 5 votes vote down vote up
package puretracing.cats

import cats.{Applicative, Monad}
import cats.effect.{Bracket, IO}
import cats.effect.syntax.all._
import cats.syntax.all._
import cats.instances.list._

import puretracing.api.{Propagation, Tracer, TracingValue}

package object dsl {
  def inChildSpan[F[_]]: ChildSpanPartiallyApplied[F] = new ChildSpanPartiallyApplied[F]

  implicit def tracingValueFromString(value: String): TracingValue = TracingValue.StringTracingValue(value)
  implicit def tracingValueFromBoolean(value: Boolean): TracingValue = TracingValue.BooleanTracingValue(value)
  implicit def tracingValueFromInt(value: Int): TracingValue = TracingValue.NumberTracingValue(value)
  implicit def tracingValueFromDouble(value: Double): TracingValue = TracingValue.NumberTracingValue(value)
  implicit def tracingValueFromBigDecimal(value: BigDecimal): TracingValue = TracingValue.NumberTracingValue(value)
}


class ChildSpanPartiallyApplied[F[_]] {
  def apply[A](operationName: String, tags: (String, TracingValue)*)(logic: SpanOps[F] => F[A])(
    implicit
    tracing: Propagation[F],
    M: Monad[F],
    E: Bracket[F, Throwable]
  ): F[A] = for {
    parent <- tracing.currentSpan()
    span <- tracing.startChild(parent, operationName)
    richSpan = spanOps(tracing)(span)
    fa <- tracing.useSpanIn(span)(richSpan.tag(tags: _*) *> logic(richSpan)).guarantee(tracing.finish(span))
  } yield fa

  private def spanOps(tracer: Tracer[F])(span: tracer.Span)(implicit F: Applicative[F]) = new SpanOps[F] {
    def tag(tags: (String, TracingValue)*): F[Unit] =
      tags.toList.traverse { case (k, v) => tracer.setTag(span, k, v) }.map(_ => ())

    def log(fields: (String, TracingValue)*): F[Unit] = tracer.log(span, fields)
    def set(key: String, value: String): F[Unit] = tracer.setBaggageItem(span, key, value)
    def get(key: String): F[Option[String]] = tracer.getBaggageItem(span, key)
  }
}

trait SpanOps[F[_]] {
  def tag(tags: (String, TracingValue)*): F[Unit]
  def log(fields: (String, TracingValue)*): F[Unit]
  def set(key: String, value: String): F[Unit]
  def get(key: String): F[Option[String]]
} 
Example 4
Source File: Services.scala    From puretracing   with Apache License 2.0 5 votes vote down vote up
import cats.data.ReaderT
import cats.{Applicative, Functor, ~>, FlatMap}
import cats.effect.{Bracket, IO}
import cats.syntax.all._
import cats.instances.list._
import puretracing.api.Propagation
import puretracing.cats.dsl._



class BazAlgebra[F[_]: Applicative: Propagation] {

  def baz()(implicit F: Bracket[F, Throwable]): F[Int] =
    inChildSpan[F]("baz") { span =>
      for {
        _ <- span.log("baz" -> 1)
        res <- 1.pure[F]
      } yield res
    }

}

// Console is defined for IO only, we should be able to derive instance for Tracing IO
trait Console[F[_]] {
  def println(a: Any): F[Unit]

  final def mapK[G[_]](f: F ~> G): Console[G] =
    a => f(println(a))
}
object Console {
  def apply[F[_]](implicit F: Console[F]) = F
  implicit val ioConsoleImpl: Console[IO] = (a: Any) => IO(println(a))
  implicit def readerTImpl[F[_], A](implicit console: Console[F]): Console[ReaderT[F, A, ?]] =
    a => ReaderT.liftF(console.println(a))
}

// Example how to instrument an http client to propagate headers
class InstrumentedHttpClient[F[_]: FlatMap](implicit console: Console[F], tracer: Propagation[F]) {
  import cats.syntax.all._

  def request(method: String, url: String): F[Unit] =
    for {
      span <- tracer.currentSpan
      headers <- tracer.export(span)
      // Simulate http request
      _ <- Console[F].println(s"┌$method $url HTTP/1.1")
      _ <- Console[F].println(headers.map { case (k,v) => s"$k: $v" }.mkString("│", " \n", ""))
      _ <- Console[F].println(s"│Keep-Alive: 300")
      _ <- Console[F].println(s"└Connection: keep-alive")
    } yield ()
} 
Example 5
Source File: BracketSyntax.scala    From cats-effect   with Apache License 2.0 5 votes vote down vote up
package cats.effect.syntax

import cats.effect.{Bracket, ExitCase}

trait BracketSyntax {
  implicit def catsEffectSyntaxBracket[F[_], A, E](fa: F[A])(implicit bracket: Bracket[F, E]): BracketOps[F, E, A] = {
    // Bracket instance here is required to ensure correct inference for E
    val _ = bracket
    new BracketOps[F, E, A](fa)
  }
}

final class BracketOps[F[_], E, A](val self: F[A]) extends AnyVal {
  def bracketCase[B](use: A => F[B])(release: (A, ExitCase[E]) => F[Unit])(implicit F: Bracket[F, E]): F[B] =
    F.bracketCase(self)(use)(release)

  def bracket[B](use: A => F[B])(release: A => F[Unit])(implicit F: Bracket[F, E]): F[B] =
    F.bracket(self)(use)(release)

  def guarantee(finalizer: F[Unit])(implicit F: Bracket[F, E]): F[A] =
    F.guarantee(self)(finalizer)

  def guaranteeCase(finalizer: ExitCase[E] => F[Unit])(implicit F: Bracket[F, E]): F[A] =
    F.guaranteeCase(self)(finalizer)

  def uncancelable(implicit F: Bracket[F, E]): F[A] =
    F.uncancelable(self)

  def onCancel(finalizer: F[Unit])(implicit F: Bracket[F, E]): F[A] =
    F.onCancel(self)(finalizer)
} 
Example 6
Source File: DoobieUserRepositoryInterpreter.scala    From scala-pet-store   with Apache License 2.0 5 votes vote down vote up
package io.github.pauljamescleary.petstore
package infrastructure.repository.doobie

import cats.data.OptionT
import cats.effect.Bracket
import cats.implicits._
import doobie._
import doobie.implicits._
import io.circe.parser.decode
import io.circe.syntax._
import domain.users.{Role, User, UserRepositoryAlgebra}
import io.github.pauljamescleary.petstore.infrastructure.repository.doobie.SQLPagination._
import tsec.authentication.IdentityStore

private object UserSQL {
  // H2 does not support JSON data type.
  implicit val roleMeta: Meta[Role] =
    Meta[String].imap(decode[Role](_).leftMap(throw _).merge)(_.asJson.toString)

  def insert(user: User): Update0 = sql"""
    INSERT INTO USERS (USER_NAME, FIRST_NAME, LAST_NAME, EMAIL, HASH, PHONE, ROLE)
    VALUES (${user.userName}, ${user.firstName}, ${user.lastName}, ${user.email}, ${user.hash}, ${user.phone}, ${user.role})
  """.update

  def update(user: User, id: Long): Update0 = sql"""
    UPDATE USERS
    SET FIRST_NAME = ${user.firstName}, LAST_NAME = ${user.lastName},
        EMAIL = ${user.email}, HASH = ${user.hash}, PHONE = ${user.phone}, ROLE = ${user.role}
    WHERE ID = $id
  """.update

  def select(userId: Long): Query0[User] = sql"""
    SELECT USER_NAME, FIRST_NAME, LAST_NAME, EMAIL, HASH, PHONE, ID, ROLE
    FROM USERS
    WHERE ID = $userId
  """.query

  def byUserName(userName: String): Query0[User] = sql"""
    SELECT USER_NAME, FIRST_NAME, LAST_NAME, EMAIL, HASH, PHONE, ID, ROLE
    FROM USERS
    WHERE USER_NAME = $userName
  """.query[User]

  def delete(userId: Long): Update0 = sql"""
    DELETE FROM USERS WHERE ID = $userId
  """.update

  val selectAll: Query0[User] = sql"""
    SELECT USER_NAME, FIRST_NAME, LAST_NAME, EMAIL, HASH, PHONE, ID, ROLE
    FROM USERS
  """.query
}

class DoobieUserRepositoryInterpreter[F[_]: Bracket[?[_], Throwable]](val xa: Transactor[F])
    extends UserRepositoryAlgebra[F]
    with IdentityStore[F, Long, User] { self =>
  import UserSQL._

  def create(user: User): F[User] =
    insert(user).withUniqueGeneratedKeys[Long]("ID").map(id => user.copy(id = id.some)).transact(xa)

  def update(user: User): OptionT[F, User] =
    OptionT.fromOption[F](user.id).semiflatMap { id =>
      UserSQL.update(user, id).run.transact(xa).as(user)
    }

  def get(userId: Long): OptionT[F, User] = OptionT(select(userId).option.transact(xa))

  def findByUserName(userName: String): OptionT[F, User] =
    OptionT(byUserName(userName).option.transact(xa))

  def delete(userId: Long): OptionT[F, User] =
    get(userId).semiflatMap(user => UserSQL.delete(userId).run.transact(xa).as(user))

  def deleteByUserName(userName: String): OptionT[F, User] =
    findByUserName(userName).mapFilter(_.id).flatMap(delete)

  def list(pageSize: Int, offset: Int): F[List[User]] =
    paginate(pageSize, offset)(selectAll).to[List].transact(xa)
}

object DoobieUserRepositoryInterpreter {
  def apply[F[_]: Bracket[?[_], Throwable]](xa: Transactor[F]): DoobieUserRepositoryInterpreter[F] =
    new DoobieUserRepositoryInterpreter(xa)
} 
Example 7
Source File: DoobieAuthRepositoryInterpreter.scala    From scala-pet-store   with Apache License 2.0 5 votes vote down vote up
package io.github.pauljamescleary.petstore.infrastructure.repository.doobie

import java.time.Instant

import cats._
import cats.data._
import cats.effect.Bracket
import cats.implicits._
import doobie._
import doobie.implicits._
import doobie.implicits.legacy.instant._
import tsec.authentication.{AugmentedJWT, BackingStore}
import tsec.common.SecureRandomId
import tsec.jws.JWSSerializer
import tsec.jws.mac.{JWSMacCV, JWSMacHeader, JWTMacImpure}
import tsec.mac.jca.{MacErrorM, MacSigningKey}

private object AuthSQL {
  implicit val secureRandomIdPut: Put[SecureRandomId] =
    Put[String].contramap((_: Id[SecureRandomId]).widen)

  def insert[A](jwt: AugmentedJWT[A, Long])(implicit hs: JWSSerializer[JWSMacHeader[A]]): Update0 =
    sql"""INSERT INTO JWT (ID, JWT, IDENTITY, EXPIRY, LAST_TOUCHED)
          VALUES (${jwt.id}, ${jwt.jwt.toEncodedString}, ${jwt.identity}, ${jwt.expiry}, ${jwt.lastTouched})
       """.update

  def update[A](jwt: AugmentedJWT[A, Long])(implicit hs: JWSSerializer[JWSMacHeader[A]]): Update0 =
    sql"""UPDATE JWT SET JWT = ${jwt.jwt.toEncodedString}, IDENTITY = ${jwt.identity},
         | EXPIRY = ${jwt.expiry}, LAST_TOUCHED = ${jwt.lastTouched} WHERE ID = ${jwt.id}
       """.stripMargin.update

  def delete(id: SecureRandomId): Update0 =
    sql"DELETE FROM JWT WHERE ID = $id".update

  def select(id: SecureRandomId): Query0[(String, Long, Instant, Option[Instant])] =
    sql"SELECT JWT, IDENTITY, EXPIRY, LAST_TOUCHED FROM JWT WHERE ID = $id"
      .query[(String, Long, Instant, Option[Instant])]
}

class DoobieAuthRepositoryInterpreter[F[_]: Bracket[?[_], Throwable], A](
    val key: MacSigningKey[A],
    val xa: Transactor[F],
)(
    implicit
    hs: JWSSerializer[JWSMacHeader[A]],
    s: JWSMacCV[MacErrorM, A],
) extends BackingStore[F, SecureRandomId, AugmentedJWT[A, Long]] {
  override def put(jwt: AugmentedJWT[A, Long]): F[AugmentedJWT[A, Long]] =
    AuthSQL.insert(jwt).run.transact(xa).as(jwt)

  override def update(jwt: AugmentedJWT[A, Long]): F[AugmentedJWT[A, Long]] =
    AuthSQL.update(jwt).run.transact(xa).as(jwt)

  override def delete(id: SecureRandomId): F[Unit] =
    AuthSQL.delete(id).run.transact(xa).void

  override def get(id: SecureRandomId): OptionT[F, AugmentedJWT[A, Long]] =
    OptionT(AuthSQL.select(id).option.transact(xa)).semiflatMap {
      case (jwtStringify, identity, expiry, lastTouched) =>
        JWTMacImpure.verifyAndParse(jwtStringify, key) match {
          case Left(err) => err.raiseError[F, AugmentedJWT[A, Long]]
          case Right(jwt) => AugmentedJWT(id, jwt, identity, expiry, lastTouched).pure[F]
        }
    }
}

object DoobieAuthRepositoryInterpreter {
  def apply[F[_]: Bracket[?[_], Throwable], A](key: MacSigningKey[A], xa: Transactor[F])(
      implicit
      hs: JWSSerializer[JWSMacHeader[A]],
      s: JWSMacCV[MacErrorM, A],
  ): DoobieAuthRepositoryInterpreter[F, A] =
    new DoobieAuthRepositoryInterpreter(key, xa)
} 
Example 8
Source File: DoobieOrderRepositoryInterpreter.scala    From scala-pet-store   with Apache License 2.0 5 votes vote down vote up
package io.github.pauljamescleary.petstore
package infrastructure.repository.doobie

import cats.data.OptionT
import cats.effect.Bracket
import cats.implicits._
import doobie._
import doobie.implicits._
import doobie.implicits.legacy.instant._
import domain.orders.{Order, OrderRepositoryAlgebra, OrderStatus}

private object OrderSQL {
  
  implicit val StatusMeta: Meta[OrderStatus] =
    Meta[String].imap(OrderStatus.withName)(_.entryName)

  def select(orderId: Long): Query0[Order] = sql"""
    SELECT PET_ID, SHIP_DATE, STATUS, COMPLETE, ID, USER_ID
    FROM ORDERS
    WHERE ID = $orderId
  """.query[Order]

  def insert(order: Order): Update0 = sql"""
    INSERT INTO ORDERS (PET_ID, SHIP_DATE, STATUS, COMPLETE, USER_ID)
    VALUES (${order.petId}, ${order.shipDate}, ${order.status}, ${order.complete}, ${order.userId.get})
  """.update

  def delete(orderId: Long): Update0 = sql"""
    DELETE FROM ORDERS
    WHERE ID = $orderId
  """.update
}

class DoobieOrderRepositoryInterpreter[F[_]: Bracket[?[_], Throwable]](val xa: Transactor[F])
    extends OrderRepositoryAlgebra[F] {
  import OrderSQL._

  def create(order: Order): F[Order] =
    insert(order)
      .withUniqueGeneratedKeys[Long]("ID")
      .map(id => order.copy(id = id.some))
      .transact(xa)

  def get(orderId: Long): F[Option[Order]] =
    OrderSQL.select(orderId).option.transact(xa)

  def delete(orderId: Long): F[Option[Order]] =
    OptionT(get(orderId))
      .semiflatMap(order => OrderSQL.delete(orderId).run.transact(xa).as(order))
      .value
}

object DoobieOrderRepositoryInterpreter {
  def apply[F[_]: Bracket[?[_], Throwable]](
      xa: Transactor[F],
  ): DoobieOrderRepositoryInterpreter[F] =
    new DoobieOrderRepositoryInterpreter(xa)
} 
Example 9
Source File: PreparedCommand.scala    From skunk   with MIT License 5 votes vote down vote up
// Copyright (c) 2018-2020 by Rob Norris
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package skunk

import cats.{ Contravariant, ~> }
import cats.effect.Bracket
import skunk.data.Completion
import skunk.net.Protocol
import skunk.util.Origin


  implicit def contravariantPreparedCommand[F[_]]: Contravariant[PreparedCommand[F, ?]] =
    new Contravariant[PreparedCommand[F, ?]] {
      override def contramap[A, B](fa: PreparedCommand[F,A])(f: B => A): PreparedCommand[F, B] =
        new PreparedCommand[F, B] {
          override def execute(args: B)(implicit origin: Origin): F[Completion] = fa.execute(f(args))
        }
    }

  def fromProto[F[_]: Bracket[?[_], Throwable], A](pc: Protocol.PreparedCommand[F, A]): PreparedCommand[F, A] =
    new PreparedCommand[F, A] {
      override def execute(args: A)(implicit origin: Origin): F[Completion] =
        pc.bind(args, origin).use(_.execute)
    }

} 
Example 10
Source File: Math1.scala    From skunk   with MIT License 5 votes vote down vote up
// Copyright (c) 2018-2020 by Rob Norris
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package example

import cats.effect.{ Bracket, ExitCode, IO, IOApp, Resource }
import skunk.Session
import skunk.implicits._
import skunk.codec.numeric.{ int4, float8 }
import natchez.Trace.Implicits.noop

object Math1 extends IOApp {

  val session: Resource[IO, Session[IO]] =
    Session.single(
      host     = "localhost",
      port     = 5432,
      user     = "jimmy",
      database = "world",
      password = Some("banana")
    )

  // An algebra for doing math.
  trait Math[F[_]] {
    def add(a: Int, b: Int): F[Int]
    def sqrt(d: Double): F[Double]
  }

  object Math {

    object Statements {
      val add  = sql"select $int4 + $int4".query(int4)
      val sqrt = sql"select sqrt($float8)".query(float8)
    }

    // `Math` implementation that delegates its work to Postgres.
    def fromSession[F[_]: Bracket[?[_], Throwable]](sess: Session[F]): Math[F] =
      new Math[F] {
        def add(a: Int, b: Int) = sess.prepare(Statements.add).use(_.unique(a ~ b))
        def sqrt(d: Double)     = sess.prepare(Statements.sqrt).use(_.unique(d))
      }

  }

  def run(args: List[String]): IO[ExitCode] =
    session.map(Math.fromSession(_)).use { m =>
      for {
        n  <- m.add(42, 71)
        d  <- m.sqrt(2)
        d2 <- m.sqrt(42)
        _  <- IO(println(s"The answers were $n and $d and $d2"))
      } yield ExitCode.Success
    }

} 
Example 11
Source File: FTracing.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.doobie

import cats.effect.ExitCase.{Canceled, Completed, Error}
import cats.effect.{Bracket, Sync}
import doobie.free.connection.ConnectionIO
import io.opencensus.scala.Tracing
import io.opencensus.scala.doobie.FTracing.FBracket
import io.opencensus.trace.{Span, Status}
import cats.syntax.flatMap._
import cats.syntax.functor._

abstract class FTracing[F[_]: Sync: FBracket] {

  protected val tracing: Tracing

  private def fTrace(name: String, parentSpan: Option[Span]): F[Span] =
    Sync[F].delay(
      parentSpan.fold(tracing.startSpan(name))(span =>
        tracing.startSpanWithParent(name, span)
      )
    )

  private def fStop(span: Span): F[Unit] =
    Sync[F].delay(tracing.endSpan(span, Status.OK))

  private def fStopError(span: Span): F[Unit] =
    Sync[F].delay(tracing.endSpan(span, Status.INTERNAL))

  private def fStopCanceled(span: Span): F[Unit] =
    Sync[F].delay(tracing.endSpan(span, Status.CANCELLED))

  def traceF[A](co: F[A], name: String, parentSpan: Option[Span]): F[A] =
    for {
      startedSpan <- fTrace(name, parentSpan)
      result <- Bracket[F, Throwable].guaranteeCase(co) {
        case Completed => fStop(startedSpan)
        case Error(_)  => fStopError(startedSpan)
        case Canceled  => fStopCanceled(startedSpan)
      }
    } yield result
}

object FTracing {
  type FBracket[F[_]] = Bracket[F, Throwable]
}

object ConnectionIOTracing extends FTracing[ConnectionIO] {
  override protected val tracing: Tracing = Tracing
} 
Example 12
Source File: Mut.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu
package concurrent

import cats.Functor
import cats.effect.Bracket
import cats.effect.concurrent.{MVar, Ref}
import cats.syntax.functor._
import tofu.concurrent.Mut.FocusedMut
import tofu.optics.Contains
import tofu.syntax.bracket._


@deprecated("use Atom / qvar.toAtom", since = "0.5.6")
trait Mut[F[_], A] {
  def get: F[A]
  def update(f: A => A): F[Unit]
  def set(a: A): F[Unit] = update(_ => a)

  def focused[B](implicit focus: A Contains B, F: Functor[F]): Mut[F, B] = new FocusedMut(this, focus)
}

object Mut {
  def ref[F[_], A](ref: Ref[F, A]): Mut[F, A]                                        = new RefMut(ref)
  def mvar[F[_], E, A](mvar: MVar[F, A])(implicit bracket: Bracket[F, E]): Mut[F, A] = new MVarMut(mvar)

  private class RefMut[F[_], A](ref: Ref[F, A]) extends Mut[F, A] {
    def get: F[A]                   = ref.get
    override def set(a: A): F[Unit] = ref.set(a)
    def update(f: A => A): F[Unit]  = ref.update(f)
  }

  private class MVarMut[F[_]: Bracket[*[_], E], E, A](mvar: MVar[F, A]) extends Mut[F, A] {
    def get: F[A]                  = mvar.read
    def update(f: A => A): F[Unit] = mvar.take.bracketIncomplete(f andThen mvar.put)(mvar.put)
  }

  private[Mut] class FocusedMut[F[_], A, B](v: Mut[F, A], focus: Contains[A, B])(implicit F: Functor[F])
      extends Mut[F, B] {
    def get: F[B]                   = v.get.map(focus.extract)
    def update(f: B => B): F[Unit]  = v.update(focus.update(_, f))
    override def set(b: B): F[Unit] = v.update(focus.set(_, b))

    override def focused[C](implicit next: B Contains C, F: Functor[F]): Mut[F, C] =
      new FocusedMut[F, A, C](v, focus >> next)
  }
} 
Example 13
Source File: ConsumerOf.scala    From skafka   with MIT License 5 votes vote down vote up
package com.evolutiongaming.skafka.consumer

import cats.effect.{Bracket, Concurrent, ContextShift, Resource}
import cats.{Applicative, Defer, ~>}
import com.evolutiongaming.catshelper.{ToFuture, ToTry}
import com.evolutiongaming.skafka.FromBytes
import com.evolutiongaming.smetrics.MeasureDuration

import scala.concurrent.ExecutionContext

trait ConsumerOf[F[_]] {

  def apply[K, V](
    config: ConsumerConfig)(implicit
    fromBytesK: FromBytes[F, K],
    fromBytesV: FromBytes[F, V]
  ): Resource[F, Consumer[F, K, V]]
}

object ConsumerOf {

  def apply[F[_] : Concurrent : ContextShift : ToTry : ToFuture : MeasureDuration](
    executorBlocking: ExecutionContext,
    metrics: Option[ConsumerMetrics[F]] = None
  ): ConsumerOf[F] = new ConsumerOf[F] {

    def apply[K, V](
      config: ConsumerConfig)(implicit
      fromBytesK: FromBytes[F, K],
      fromBytesV: FromBytes[F, V]
    ) = {
      for {
        consumer <- Consumer.of[F, K, V](config, executorBlocking)
      } yield {
        metrics.fold(consumer)(consumer.withMetrics[Throwable])
      }
    }
  }


  implicit class ConsumerOfOps[F[_]](val self: ConsumerOf[F]) extends AnyVal {

    def mapK[G[_] : Applicative : Defer](
      fg: F ~> G,
      gf: G ~> F)(implicit
      B: Bracket[F, Throwable]
    ): ConsumerOf[G] = new ConsumerOf[G] {

      def apply[K, V](
        config: ConsumerConfig)(implicit
        fromBytesK: FromBytes[G, K],
        fromBytesV: FromBytes[G, V]
      ) = {
        for {
          a <- self[K, V](config)(fromBytesK.mapK(gf), fromBytesV.mapK(gf)).mapK(fg)
        } yield {
          a.mapK(fg, gf)
        }
      }
    }
  }
} 
Example 14
Source File: ProducerOf.scala    From skafka   with MIT License 5 votes vote down vote up
package com.evolutiongaming.skafka.producer

import cats.effect.{Bracket, ContextShift, Effect, Resource}
import cats.{Defer, Monad, ~>}
import com.evolutiongaming.smetrics.MeasureDuration

import scala.concurrent.ExecutionContext

trait ProducerOf[F[_]] {

  def apply(config: ProducerConfig): Resource[F, Producer[F]]
}

object ProducerOf {

  def apply[F[_] : Effect : ContextShift : MeasureDuration](
    executorBlocking: ExecutionContext,
    metrics: Option[ProducerMetrics[F]] = None
  ): ProducerOf[F] = new ProducerOf[F] {

    def apply(config: ProducerConfig) = {
      for {
        producer <- Producer.of[F](config, executorBlocking)
      } yield {
        metrics.fold(producer)(producer.withMetrics[Throwable])
      }
    }
  }


  implicit class ProducerOfOps[F[_]](val self: ProducerOf[F]) extends AnyVal {

    def mapK[G[_] : Monad : Defer](
      fg: F ~> G,
      gf: G ~> F)(implicit
      B: Bracket[F, Throwable]
    ): ProducerOf[G] = new ProducerOf[G] {

      def apply(config: ProducerConfig) = {
        for {
          a <- self(config).mapK(fg)
        } yield {
          a.mapK(fg, gf)
        }
      }
    }
  }
} 
Example 15
Source File: doobie.scala    From eff   with MIT License 5 votes vote down vote up
package org.atnos.eff.syntax.addon

import _root_.doobie.Transactor
import _root_.doobie.free.connection.ConnectionIO
import cats.effect.Bracket
import org.atnos.eff.addon.doobie._
import org.atnos.eff.{Eff, _}

trait doobie {

  implicit final def toDoobieConnectionIOOps[R, A](e: Eff[R, A]): DoobieConnectionIOOps[R, A] =
    new DoobieConnectionIOOps[R, A](e)

}

final class DoobieConnectionIOOps[R, A](private val e: Eff[R, A]) extends AnyVal {
  def runConnectionIO[F[_], U, E, B](t: Transactor[F])(
    implicit mc: Member.Aux[ConnectionIO, R, U],
    mf: MemberInOut[F, U],
    me: Bracket[F, Throwable]): Eff[U, A] = {
    DoobieConnectionIOInterpretation.runConnectionIO[R, U, F, E, A, B](e)(t)
  }
}

object doobie extends doobie 
Example 16
Source File: DoobieConnectionIOEffect.scala    From eff   with MIT License 5 votes vote down vote up
package org.atnos.eff.addon.doobie

import java.sql.Connection

import _root_.doobie.Transactor
import _root_.doobie.free.connection.ConnectionIO
import cats.effect.Bracket
import cats.implicits._
import cats.~>
import org.atnos.eff._
import org.atnos.eff.all._

trait DoobieConnectionIOTypes {
  type _connectionIO[R] = ConnectionIO |= R
  type _ConnectionIO[R] = ConnectionIO <= R
}

trait DoobieConnectionIOCreation extends DoobieConnectionIOTypes {
  final def fromConnectionIO[R: _connectionIO, A](a: ConnectionIO[A]): Eff[R, A] =
    send[ConnectionIO, R, A](a)
}

trait DoobieConnectionIOInterpretation extends DoobieConnectionIOTypes {

  def runConnectionIO[R, U, F[_], E, A, B](e: Eff[R, A])(t: Transactor[F])(
    implicit mc: Member.Aux[ConnectionIO, R, U],
             mf: F /= U,
             me: Bracket[F, Throwable] ): Eff[U, A] = {

    def getConnection: Eff[U, Connection] =
      send[F, U, Connection](t.connect(t.kernel).allocated.map(_._1))

    def runEffect(connection: Connection): Eff[U, A] =
      interpret.translate(e)(new Translate[ConnectionIO, U] {
        def apply[X](c: ConnectionIO[X]): Eff[U, X] = {
          send[F, U, X](c.foldMap(t.interpret).run(connection))
        }
      })

    def interceptErrors[Y](effect: Eff[U, Y])(oops: F[Unit]): Eff[U, Y] =
      interpret.interceptNat(effect)(new (F ~> F) {
        def apply[X](f: F[X]): F[X] =
          f.handleErrorWith((err: Throwable) => oops *> me.raiseError[X](err))
      })

    getConnection.flatMap { connection =>
      lazy val always: F[Unit] =
        t.strategy.always.foldMap(t.interpret).run(connection)

      lazy val oops: F[Unit] =
        t.strategy.oops.foldMap(t.interpret).run(connection)

      val before: Eff[U, Unit] =
        send(t.strategy.before.foldMap(t.interpret).run(connection))

      val after: Eff[U, Unit] =
        send(t.strategy.after.foldMap(t.interpret).run(connection))

      interceptErrors(before >> runEffect(connection) << after)(oops).addLast(send(always))
    }
  }
}

object DoobieConnectionIOCreation extends DoobieConnectionIOCreation

object DoobieConnectionIOInterpretation extends DoobieConnectionIOInterpretation

trait DoobieConnectionIOEffect extends DoobieConnectionIOCreation with DoobieConnectionIOInterpretation

object DoobieConnectionIOEffect extends DoobieConnectionIOEffect 
Example 17
Source File: package.scala    From scala-steward   with Apache License 2.0 5 votes vote down vote up
package org.scalasteward.core

import cats._
import cats.effect.Bracket
import cats.implicits._
import fs2.Pipe
import scala.collection.mutable.ListBuffer

package object util {
  final type Nel[+A] = cats.data.NonEmptyList[A]
  final val Nel = cats.data.NonEmptyList

  type ApplicativeThrowable[F[_]] = ApplicativeError[F, Throwable]

  type MonadThrowable[F[_]] = MonadError[F, Throwable]

  type BracketThrowable[F[_]] = Bracket[F, Throwable]

  
  def takeUntil[F[_], A, N](limit: N)(weight: A => N)(implicit N: Numeric[N]): Pipe[F, A, A] = {
    import N._
    _.map(a => (a, weight(a)))
      .scan1[(A, N)] { case ((_, total), (a, i)) => (a, total + i) }
      .takeThrough { case (_, total) => total < limit }
      .map { case (a, _) => a }
  }
} 
Example 18
Source File: RerunnableSuite.scala    From catbird   with Apache License 2.0 5 votes vote down vote up
package io.catbird.util.effect

import cats.effect.laws.discipline.EffectTests
import cats.effect.laws.discipline.arbitrary.catsEffectLawsArbitraryForIO
import cats.effect.laws.util.{ TestContext, TestInstances }
import cats.effect.{ Bracket, IO }
import cats.instances.either._
import cats.instances.int._
import cats.instances.tuple._
import cats.instances.unit._
import cats.kernel.Eq
import cats.laws.discipline.arbitrary._
import com.twitter.util.{ Await, Monitor, Throw }
import io.catbird.util.{ ArbitraryInstances, Rerunnable }
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.prop.Configuration
import org.typelevel.discipline.scalatest.FunSuiteDiscipline

class RerunnableSuite
    extends AnyFunSuite
    with FunSuiteDiscipline
    with Configuration
    with ArbitraryInstances
    with TestInstances {
  implicit val context: TestContext = TestContext()
  implicit def rerunnableEq[A](implicit A: Eq[A]): Eq[Rerunnable[A]] =
    Eq.by[Rerunnable[A], IO[A]](rerunnableToIO)

  checkAll("Rerunnable[Int]", EffectTests[Rerunnable].effect[Int, Int, Int])

  test("Exceptions thrown by release are handled by Monitor") {
    val useException = new Exception("thrown by use")
    val releaseException = new Exception("thrown by release")

    var monitoredException: Throwable = null
    val monitor = Monitor.mk { case e => monitoredException = e; true; }

    val rerunnable = Bracket[Rerunnable, Throwable]
      .bracket(Rerunnable.Unit)(_ => Rerunnable.raiseError(useException))(_ => Rerunnable.raiseError(releaseException))
      .liftToTry

    val result = Await.result(Monitor.using(monitor)(rerunnable.run))

    assert(result == Throw(useException))
    assert(monitoredException == releaseException)
  }
} 
Example 19
Source File: doobie.scala    From sup   with Apache License 2.0 5 votes vote down vote up
package sup.modules

import cats.Id
import sup.HealthCheck
import cats.effect.Bracket
import scala.concurrent.duration._
import cats.implicits._

object doobie {
  import _root_.doobie._
  import _root_.doobie.implicits._

  
  def connectionCheck[F[_]: Bracket[?[_], Throwable]](
    xa: Transactor[F]
  )(
    timeout: Option[FiniteDuration]
  ): HealthCheck[F, Id] = {
    //zero means infinite in JDBC
    val actualTimeoutSeconds = timeout.foldMap(_.toSeconds.toInt)

    HealthCheck.liftFBoolean {
      FC.isValid(actualTimeoutSeconds).transact(xa)
    }
  }
} 
Example 20
Source File: implicits.scala    From opencensus-scala   with Apache License 2.0 5 votes vote down vote up
package io.opencensus.scala.doobie

import cats.Monad
import cats.effect.Bracket
import doobie.ConnectionIO
import doobie.util.transactor.Transactor
import io.opencensus.trace.Span

object implicits {
  implicit class ConnectionTracingOps[A](ma: ConnectionIO[A]) {
    def tracedTransact[M[_]: Monad](
        xa: Transactor[M],
        transactionName: String
    )(implicit ev: Bracket[M, Throwable]): M[A] =
      xa.trans.apply(ConnectionIOTracing.traceF(ma, transactionName, None))

    def tracedTransact[M[_]: Monad](
        xa: Transactor[M],
        transactionName: String,
        parentSpan: Span
    )(implicit ev: Bracket[M, Throwable]): M[A] =
      xa.trans.apply(
        ConnectionIOTracing.traceF(ma, transactionName, Some(parentSpan))
      )
  }
}