All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sangria.execution.ExecutionScheme.scala Maven / Gradle / Ivy

package sangria.execution

import sangria.streaming.SubscriptionStream

import scala.concurrent.{ExecutionContext, Future}

trait ExecutionScheme {
  type Result[Ctx, Res]

  def failed[Ctx, Res](error: Throwable): Result[Ctx, Res]
  def onComplete[Ctx, Res](result: Result[Ctx, Res])(op: => Unit)(implicit
      ec: ExecutionContext): Result[Ctx, Res]
  def flatMapFuture[Ctx, Res, T](future: Future[T])(resultFn: T => Result[Ctx, Res])(implicit
      ec: ExecutionContext): Result[Ctx, Res]
  def extended: Boolean
  val resolverBuilder: ResolverBuilder
}

object ExecutionScheme extends AlternativeExecutionScheme {
  implicit object Default extends ExecutionScheme {
    type Result[Ctx, Res] = Future[Res]

    def failed[Ctx, Res](error: Throwable): Result[Ctx, Res] =
      Future.failed(error)

    def onComplete[Ctx, Res](result: Result[Ctx, Res])(op: => Unit)(implicit
        ec: ExecutionContext): Result[Ctx, Res] =
      result
        .map { x => op; x }
        .recover { case e => op; throw e }

    def flatMapFuture[Ctx, Res, T](future: Future[T])(resultFn: T => Result[Ctx, Res])(implicit
        ec: ExecutionContext): Result[Ctx, Res] =
      future.flatMap(resultFn)

    def extended = false

    override val resolverBuilder: ResolverBuilder = FutureResolverBuilder
  }
}

trait AlternativeExecutionScheme {
  trait StreamBasedExecutionScheme[S[_]] {
    def subscriptionStream: SubscriptionStream[S]
  }

  implicit object Extended extends ExecutionScheme {
    type Result[Ctx, T] = Future[ExecutionResult[Ctx, T]]

    def failed[Ctx, Res](error: Throwable): Result[Ctx, Res] =
      Future.failed(error)

    def onComplete[Ctx, Res](result: Result[Ctx, Res])(op: => Unit)(implicit
        ec: ExecutionContext): Result[Ctx, Res] =
      result
        .map { x => op; x }
        .recover { case e => op; throw e }

    def flatMapFuture[Ctx, Res, T](future: Future[T])(resultFn: T => Result[Ctx, Res])(implicit
        ec: ExecutionContext): Result[Ctx, Res] =
      future.flatMap(resultFn)

    def extended = true

    override val resolverBuilder: ResolverBuilder = FutureResolverBuilder
  }

  implicit def Stream[S[_]](implicit
      stream: SubscriptionStream[S]): ExecutionScheme with StreamBasedExecutionScheme[S] {
    type Result[Ctx, T] = S[T]
  } =
    new ExecutionScheme with StreamBasedExecutionScheme[S] {
      type Result[Ctx, T] = S[T]

      def subscriptionStream = stream
      def extended = false

      def failed[Ctx, Res](error: Throwable): Result[Ctx, Res] =
        stream.failed(error)

      def onComplete[Ctx, Res](result: Result[Ctx, Res])(op: => Unit)(implicit
          ec: ExecutionContext): Result[Ctx, Res] =
        stream.onComplete(result)(op)

      def flatMapFuture[Ctx, Res, T](future: Future[T])(resultFn: T => Result[Ctx, Res])(implicit
          ec: ExecutionContext): Result[Ctx, Res] =
        stream.flatMapFuture(future)(resultFn)

      override val resolverBuilder: ResolverBuilder = FutureResolverBuilder
    }

  implicit def StreamExtended[S[_]](implicit
      stream: SubscriptionStream[S]): ExecutionScheme with StreamBasedExecutionScheme[S] {
    type Result[Ctx, T] = S[ExecutionResult[Ctx, T]]
  } =
    new ExecutionScheme with StreamBasedExecutionScheme[S] {
      type Result[Ctx, T] = S[ExecutionResult[Ctx, T]]

      def subscriptionStream = stream
      def extended = true

      def failed[Ctx, Res](error: Throwable): Result[Ctx, Res] =
        stream.failed(error)

      def onComplete[Ctx, Res](result: Result[Ctx, Res])(op: => Unit)(implicit
          ec: ExecutionContext): Result[Ctx, Res] =
        stream.onComplete(result)(op)

      def flatMapFuture[Ctx, Res, T](future: Future[T])(resultFn: T => Result[Ctx, Res])(implicit
          ec: ExecutionContext): Result[Ctx, Res] =
        stream.flatMapFuture(future)(resultFn)

      override val resolverBuilder: ResolverBuilder = FutureResolverBuilder
    }
}

case class ExecutionResult[Ctx, Res](
    ctx: Ctx,
    result: Res,
    errors: Vector[RegisteredError],
    middlewareVals: List[(Any, Middleware[_])],
    validationTiming: TimeMeasurement,
    queryReducerTiming: TimeMeasurement)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy