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

caliban.reporting.ReportingDaemon.scala Maven / Gradle / Ivy

The newest version!
package caliban.reporting

import zio._

/**
 * Manages schema reporting on start up, can be provided a set of ReportingRefs which will then be periodically
 * sent to apollo
 */
trait ReportingDaemon {

  /**
   * Registers a schema reference for upload. Returns a managed which can be used to manage the lifespan of the
   * reporting.
   */
  def register(ref: SchemaReportingRef[_])(implicit trace: Trace): ZIO[Scope, Nothing, Unit]
}

object ReportingDaemon {

  def register(ref: SchemaReportingRef[_]): ZIO[ReportingDaemon with Scope, Nothing, Unit] =
    ZIO.serviceWithZIO[ReportingDaemon](_.register(ref))

  def live: ZLayer[SchemaReporter, Nothing, ReportingDaemon] = ZLayer(make)

  def make: ZIO[SchemaReporter, Nothing, ReportingDaemon] =
    ZIO.serviceWith[SchemaReporter] { reporter =>
      new ReportingDaemon {

        override def register(ref: SchemaReportingRef[_])(implicit trace: Trace): ZIO[Scope, Nothing, Unit] = {
          def loop(withCoreSchema: Boolean): ZIO[Any, Nothing, Unit] =
            reporter
              .report(ref, withCoreSchema)
              .foldZIO(
                {
                  case ReportingError.SchemaError(_, _, message, _)  =>
                    ZIO.logError(s"Schema reporting failed for ${ref.graphRef}: $message")
                  case ReportingError.ClientError(error)             =>
                    ZIO.logWarningCause(
                      s"Schema reporting for ${ref.graphRef} failed because of a client error ${error.getMessage}. This is likely a defect, halting retries",
                      Cause.fail(error)
                    )
                  case ReportingError.RetryableError(innerThrowable) =>
                    ZIO.logWarningCause(
                      s"Schema reporting encountered an error: ${innerThrowable.getMessage}, retrying in 20 seconds",
                      Cause.fail(innerThrowable)
                    ) *> loop(false).delay(20.seconds)
                },
                resp => loop(resp.withCoreSchema).delay(resp.in)
              )

          loop(false).forkScoped
        }.unit
      }
    }
}

case class ReportingResponse(
  withCoreSchema: Boolean,
  in: Duration
)

sealed trait ReportingError

object ReportingError {
  case class SchemaError(withCoreSchema: Boolean, code: String, message: String, inSeconds: Duration)
      extends ReportingError
  case class ClientError(innerThrowable: Throwable)    extends ReportingError
  case class RetryableError(innerThrowable: Throwable) extends ReportingError

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy