我在scala中使用了play框架。我还使用RedisScala驱动程序(这一个https://github.com/etaty/rediscala )与Redis通信。如果Redis不包含数据,那么我的应用程序正在MongoDB中查找数据。当Redis失败或只是由于某种原因而不可用时,应用程序等待响应的时间太长。如何在这种情况下实现故障转移策略。如果请求时间太长,我想停止请求Redis。当它恢复在线时,开始与Redis合作。为了澄清这个问题,我的代码如下所示
private def getUserInfo(userName: String): Future[Option[UserInfo]] = {
CacheRepository.getBaseUserInfo(userName) flatMap{
case Some(userInfo) =>
Logger.trace(s"AuthenticatedAction.getUserInfo($userName). User has been found in cache")
Future.successful(Some(userInfo))
case None =>
getUserFromMongo(userName)
}
}发布于 2014-12-25 02:14:00
我认为你需要区分以下情况(按其发生的可能性排列):
最后,您可以在上面的程序中使用带超时(参见- Scala Futures - built in timeout?)的未来。如果“未来”没有在超时之前完成,则可以执行其他操作(转到Mongo或向用户返回错误消息)。考虑到#1和#2可能发生的频率比#3高得多,超时值应该反映这两种情况。鉴于#1和#2在LAN上速度很快,您可以从超时值100 of开始。
发布于 2014-12-25 10:22:44
Simanta给出了详细的答案,我只想发布用于超时的代码。代码需要在我的项目中使用的Play框架。
private def get[B](key: String, valueExtractor: Map[String, ByteString] => Option[B], logErrorMessage: String): Future[Option[B]] = {
val timeoutFuture = Promise.timeout(None, Duration(Settings.redisTimeout))
val mayBeHaveData = redisClient.hgetall(key) map { value =>
valueExtractor(value)
} recover{
case e =>
Logger.info(logErrorMessage + e)
None
}
// if timeout occurred then None will be result of method
Future.firstCompletedOf(List(mayBeHaveData, timeoutFuture))
}https://stackoverflow.com/questions/27639206
复制相似问题