lib/ohm.rb in ohm-2.2.1 vs lib/ohm.rb in ohm-2.3.0
- old
+ new
@@ -37,10 +37,15 @@
class Error < StandardError; end
class MissingID < Error; end
class IndexNotFound < Error; end
class UniqueIndexViolation < Error; end
+ module ErrorPatterns
+ DUPLICATE = /(UniqueIndexViolation: (\w+))/.freeze
+ NOSCRIPT = /^NOSCRIPT/.freeze
+ end
+
# Instead of monkey patching Kernel or trying to be clever, it's
# best to confine all the helper methods in a Utils module.
module Utils
# Used by: `attribute`, `counter`, `set`, `reference`,
@@ -1297,27 +1302,17 @@
if defined?(@id)
features["id"] = @id
end
- response = script(LUA_SAVE, 0,
+ @id = script(LUA_SAVE, 0,
features.to_msgpack,
_sanitized_attributes.to_msgpack,
indices.to_msgpack,
uniques.to_msgpack
)
- if response.is_a?(RuntimeError)
- if response.message =~ /(UniqueIndexViolation: (\w+))/
- raise UniqueIndexViolation, $1
- else
- raise response
- end
- end
-
- @id = response
-
return self
end
# Delete the model, including all the following keys:
#
@@ -1344,21 +1339,35 @@
end
# Run lua scripts and cache the sha in order to improve
# successive calls.
def script(file, *args)
- cache = LUA_CACHE[redis.url]
+ begin
+ cache = LUA_CACHE[redis.url]
- if cache.key?(file)
- sha = cache[file]
- else
- src = File.read(file)
- sha = redis.call("SCRIPT", "LOAD", src)
+ if cache.key?(file)
+ sha = cache[file]
+ else
+ src = File.read(file)
+ sha = redis.call("SCRIPT", "LOAD", src)
- cache[file] = sha
- end
+ cache[file] = sha
+ end
- redis.call("EVALSHA", sha, *args)
+ redis.call!("EVALSHA", sha, *args)
+
+ rescue RuntimeError
+
+ case $!.message
+ when ErrorPatterns::NOSCRIPT
+ LUA_CACHE[redis.url].clear
+ retry
+ when ErrorPatterns::DUPLICATE
+ raise UniqueIndexViolation, $1
+ else
+ raise $!
+ end
+ end
end
# Update the model attributes and call save.
#
# Example: