【发布时间】:2015-04-27 21:57:01
【问题描述】:
我正在 try-catch 块中创建一个 redis pubsub 客户端。在try 块中,客户端通过回调初始化以将消息转发给客户端。如果向客户端发送消息有问题,会抛出异常,此时我需要停止redis客户端。代码如下:
try {
val redisClient = RedisPubSub(
channels = Seq(currentUserId.toString),
patterns = Seq(),
onMessage = (pubSubMessage: PubSubMessage) => {
responseObserver.onValue(pubSubMessage.data)
}
)
}
catch {
case e: RuntimeException =>
// redisClient isn't defined here...
redisClient.unsubscribe(currentUserId.toString)
redisClient.stop()
messageStreamResult.complete(Try(true))
responseObserver.onCompleted()
}
问题是 redis 客户端 val 没有在 catch 块中定义,因为可能有一个异常创建它。我也无法将 try-catch 块移动到回调中,因为无法(我可以找到)从回调中引用 redisClient 对象(this 无法解析)。
为了解决这个问题,我将redisClient 实例化为var 在try-catch 块之外。然后在try 块内,我停止客户端并将新的redisPubSub(如上创建)分配给redisClient var。这是一个丑陋的 hack,也容易出错(例如,如果创建第二个客户端确实存在 问题,catch 块将尝试调用错误对象上的方法)。
是否有更好的方法来编写此代码,以便在尝试将消息发送到 responseObserver 时引发异常时,我可以在 redisClient 上正确调用 stop()?
更新
我刚刚使用 Promise 解决了这个问题。有没有更简单的方法?
【问题讨论】:
-
由于 try 子句中的唯一表达式是您的
RedisPubSub实例化,因此如果发生异常,我看不出您如何在redisClient上调用方法。如果抛出异常,则redisClient变量为空。 -
@LomigMégard 这就是我的问题的重点,不是吗。如果由于接收消息的错误而导致运行时异常,我想关闭客户端,但我无法获得对变量的引用,因为初始化它时也可能引发异常。
标签: scala