alexdoth/fyrie-redis — Issue #2: Request and result callbacks may stall or kill RedisClientSession/Worker actors
Author: alexdoth
Created: 2012-01-22 01:37:35+00:00
State: open
Labels: Bug

Both RedisClientSession and RedisClientWorker execute the callback functions in their own thread

```
RedisClientSession:
def onRequest(req: RequestMessage): Unit = {
if (config.retryOnReconnect) waiting enqueue req
requests += 1L
if (requestCallbacks.nonEmpty) {
val atTime = System.currentTimeMillis
requestCallbacks foreach (_(requests, atTime)) // <-- CALLBACK INVOCATION
}
}

RedisClientWorker:
def onResult() {
if (config.retryOnReconnect) sendToSupervisor(Received)
results += 1L
if (resultCallbacks.nonEmpty) {
val atTime = System.currentTimeMillis
resultCallbacks foreach (_(results, atTime)) // <-- CALLBACK INVOCATION
}
}
```
There are a few problems with this:

* The callback may throw an exception, which is not caught in any of the invocations. Thus unexpectedly shutting down the active actor.
* The callback may take unspecified amount of time. Thus the actor will stall until all the callback complete. Possibly triggering future timeout exceptions if the callbacks take long time to complete.
* The callback will be executed by the current Actor thread, thus if the callback uses shared data-structures there may be potential race-conditions.