Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rescue from TimeoutException #42

Closed
electricmonk opened this issue Nov 6, 2012 · 6 comments
Closed

Rescue from TimeoutException #42

electricmonk opened this issue Nov 6, 2012 · 6 comments

Comments

@electricmonk
Copy link

I'm trying to write a method to execute a blocking method (legacy HTTP GET, for that matter) asynchronously, with retries on timeout. I'd like to avoid catching the TimeoutException, so I'm trying to use Future.rescue instead.

Follows is a specs2 test attempting to do just that; for some reason which I can't really understand, the test fails. Am I missing something, or is there a bug somewhere?

class FutureRescueTimeout extends SpecificationWithJUnit {

  import com.twitter.util._
  import java.util.concurrent.Executors

  val pool = FuturePool(Executors.newSingleThreadExecutor)
  implicit val timer = new JavaTimer
  val timeout = new RichWholeNumber(100).millis // because of implicit conversion collision between specs and twitter time

  "rescue" should {
    "recover from timeout immediately" in {
      val f: Future[Boolean] = pool {
        Thread.sleep(500)
        true
      }
      .within(timeout)
      .rescue {
        case e: TimeoutException => Future(true)
      }

      f.get must beTrue
    }

    "recover from timeout using another future" in {
      val f = recursiveRetry(List(150, 30), timeout)
      f.get must beTrue
     }

  }

  def recursiveRetry(sleep: List[Long], timeout: Duration): Future[Boolean] = pool {
      Thread.sleep(sleep.head)
      true
    }
    .within(timeout)
    .rescue {
      case e: TimeoutException if !sleep.tail.isEmpty => recursiveRetry(sleep.tail, timeout)
    }
}
@mariusae
Copy link
Contributor

mariusae commented Nov 6, 2012

I just tried running this, and it works just fine.

Running com.twitter.util.FutureRescueTimeout
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.83 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Also, the canonical way to create durations without the use of implicates is:

val timeout = Duration(100, TimeUnit.MILLISECONDS)

@mariusae
Copy link
Contributor

mariusae commented Nov 6, 2012

(Can you paste the actual error you get?)

@electricmonk
Copy link
Author

I get a TimeoutException; I use 5.3.13, BTW

rescue should
recover from timeout immediately

100.milliseconds
com.twitter.util.TimeoutException: 100.milliseconds
    at com.twitter.util.Future$$anonfun$within$1$$anonfun$2.apply$mcV$sp(Future.scala:453)
    at com.twitter.util.JavaTimer$$anon$1.run(Timer.scala:155)

recover from timeout using another future

@electricmonk
Copy link
Author

Any clue?

@luciferous
Copy link
Collaborator

@electricmonk can you reproduce this with the latest release?

@vkostyukov
Copy link
Contributor

Just double-checked it: not reproducible on 6.26.0. We can close it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants