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

TimeoutException #15

Closed
colinbes opened this issue Nov 6, 2015 · 4 comments
Closed

TimeoutException #15

colinbes opened this issue Nov 6, 2015 · 4 comments

Comments

@colinbes
Copy link

colinbes commented Nov 6, 2015

I am wondering how to ensure graceful handling of timeout exception when get or set of memcache when memcache is not actually running.

I must be doing something wrong in trying to capture the exception and would appreciate any advice.

I am assuming I need to wrap the memcache.get with a try/catch block.

@colinbes
Copy link
Author

colinbes commented Nov 6, 2015

I ended up modifying my code - I thought I had to catch exception on the get/set function as opposed to when future is processed. I ended up using Either method to gracefully handle failure in my calling code.
As example see FastStore, a convenience object for access Memcache

object FastStore {
  lazy val memcached: Memcached = Memcached(Configuration("127.0.0.1:11211"), ec)

  def get[T: shade.memcached.Codec](key: String):Future[Either[Throwable, Option[T]]] =  {
    memcached.get[T](key).map { x => 
      Right(x)
    } recover {
      case cause => Left(cause)} 
    }

  def set ..
}

@colinbes colinbes closed this as completed Nov 6, 2015
@alexandru
Copy link
Member

@colinbes yes, recover and recoverWith are the helpers you get on Future to handle exceptions, plus you can also handle those errors with a simple .onComplete(callback) or an .onFailure(callback).

Btw, a Future is basically a delayed Try and a Try[T] is equivalent to an Either[Throwable, T]. There aren't many reasons for turning a Future[T] into a Future[Either[Throwable, T]]. But if you must, I would still use Try instead of either, meaning that I would turn Future[T] into a Future[Try[T]]. Here's a helper that I use ...

def liftTry[T](source: Future[T])(implicit ec: ExecutionContext): Future[Try[T]] = {
  val p = Promise[Try[T]]()
  source.onComplete { case result => p.success(result) }
  p.future
}

And in fact, because Shade currently depends on monifu-core (for the time being, though I'm thinking of removing it in the next version), you can just use this helper as it is defined in Monifu, like so:

import monifu.concurrent.extensions._

// now this works ...
val result: Future[Try[Option[T]]] =
  memcached.get[T](key).liftTry

@alexandru
Copy link
Member

@colinbes also make sure to update to the latest version of Shade, I released 1.7.1 yesterday.

@colinbes
Copy link
Author

Thanks @alexandru for the good input and the update!

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

No branches or pull requests

2 participants