Open kirhgoff opened 7 years ago
@kirhgoff thanks for the very detailed issue!
I wonder if we should instead be explicitly returning nil
from call_redis_with_failover
in the case of an exception? For example,
def call_redis_with_failover(*arguments)
calling_method = caller[0][/`.*'/][1..-2]
begin
yield
rescue => e
if Vanity.configuration.failover_on_datastore_error
Vanity.configuration.on_datastore_error.call(e, self.class, calling_method, arguments)
return nil # don't implicitly return the value returned by `on_datastore_error`
else
raise e
end
end
end
Another approach is to have a default_result parameter with default value as nil to give other methods calling call_redis_with_failover possibility to provide default return value to have more flexibility (some method would like to have [] or {} to be returned instead of nil). Though not sure whether this is needed and probably simple return nil would suffice.
While testing Vanity (2.2.7) behavior in situation when Redis is down, we discovered that the following code
Vanity.playground.participant_info(vanity_identity)
throws an errorNoMethodError (undefined method
to_i' for true:TrueClass):` with no stack trace in Vanity code.We traced how the error and found a workaround, but it probably makes sense to get fixed on Vanity side.
Here is Vanity.playground.participant_info code:
Looks like when the connection to Redis is down, ab_assigned returns true instead of nil or 0, which is being converted to int
This is the code of RedisAdapter.ab_assigned
So it either return alternative.id or nil. But we get true, how come? Lets check call_redis_with_failover method
This is RedisAdapter.call_redis_with_failover
It either rethrows exception, or return blocks return value, or... it returns result of on_datastore_error callback.
This is the callback we have (documentation says that return value will be ignored, but looks like it is not http://www.rubydoc.info/gems/vanity/Vanity/Configuration#on_datastore_error=-instance_method)
If we add nil as return value of on_datastore_error callback, everything works ok. Without it, Rails.logger.error seems to return true which is being returned from ab_assigned and breaks participants_info method logic.
We are not sure how it should be fixed, probably documentation just should mention returning nil.