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

org.specs2.concurrent.FuturezAttempt.scala Maven / Gradle / Ivy

package org.specs2
package concurrent

import java.util.concurrent.TimeoutException
import scalaz.concurrent._
import scala.concurrent.duration._
import scalaz._, Scalaz._

/**
 * implicit methods to attempt a Scalaz future values with a given timeout and
 * number of retries
 */
trait FuturezAttempt {
  implicit class AttemptFuture[T](f: Future[T])(implicit ee: ExecutionEnv) {
    def attempt: TimeoutFailure \/ T =
      attempt(retries = 0, timeout = 1.second)

    def retry(retries: Int): TimeoutFailure \/ T =
      attempt(retries, timeout = 1.second)

    def attemptFor(timeout: FiniteDuration): TimeoutFailure \/ T =
      attempt(retries = 0, timeout)

    def attempt(retries: Int, timeout: FiniteDuration): TimeoutFailure \/ T = {
      val tf = ee.timeFactor
      val appliedTimeout = timeout * tf.toLong

      def attemptFuture(remainingRetries: Int, totalDuration: FiniteDuration): TimeoutFailure \/ T = {
        f.timed(appliedTimeout.toMillis)(ee.scheduledExecutorService).run.fold({
          case e if e.getClass == classOf[TimeoutException] =>
            if (remainingRetries <= 0) TimeoutFailure(appliedTimeout, totalDuration, tf).left
            else                       attemptFuture(remainingRetries - 1, totalDuration + appliedTimeout)

          case other: Throwable  => throw other
        },
          r => r.right)
      }

      attemptFuture(retries, 0.second)
    }
  }

}

object FuturezAttempt extends FuturezAttempt




© 2015 - 2025 Weber Informatics LLC | Privacy Policy