Skip to content

Instantly share code, notes, and snippets.

@tkawachi
Created October 5, 2016 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkawachi/9eb37a76a5a7776b0b8c24c4036eb1d1 to your computer and use it in GitHub Desktop.
Save tkawachi/9eb37a76a5a7776b0b8c24c4036eb1d1 to your computer and use it in GitHub Desktop.
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
import scalaz.std.scalaFuture._
import scalaz.{ContT, Kleisli}
package object smt {
type FutureCont[A] = ContT[Future, A, A]
type DBActionz[A] = Kleisli[FutureCont, Context, A]
object DBActionz {
def apply[A](f: Context => (A => Future[A]) => Future[A]) =
Kleisli[FutureCont, Context, A] { ctx =>
ContT[Future, A, A](f(ctx))
}
def error[A](e: Exception) = DBActionz[A](_ => _ => Future.failed(e))
}
implicit class DBActionzSyntax[A](z: DBActionz[A])(implicit ec: ExecutionContext) {
def runWithContext(context: Context): Future[A] = {
z.run(context).run_.andThen {
case Success(_) => context.forceCommit()
case Failure(_) => context.forceRollback()
}
}
def runWithRunner(runner: DBActionRunner): Future[A] = runWithContext(runner.newContext())
def runTx(runner: DBActionRunner): Future[A] = {
val context = runner.newContext()
context.beginTransaction()
runWithContext(context)
}
def recover(pf: PartialFunction[Throwable, A]) =
DBActionz[A](ctx => cb => z.run(ctx).run_.recover(pf))
def recoverWith(pf: PartialFunction[Throwable, Future[A]]) =
DBActionz[A](ctx => cb => z.run(ctx).run_.recoverWith(pf))
def preAction(f: => Unit): DBActionz[A] =
DBActionz[A]{ctx => cb => Future(f).flatMap (_ => z.run(ctx).run_ )}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment