Module: Seabright::CachedScripts::ClassMethods

Defined in:
lib/redis_object/ext/script_cache.rb

Defined Under Namespace

Classes: SourceNotFoundError

Constant Summary collapse

NoScriptError =
"NOSCRIPT No matching script. Please use EVAL.".freeze
SCRIPT_KEY_PREFIX =
"ScriptCache::SHA::".freeze

Instance Method Summary collapse

Instance Method Details

#expire_all_script_shas(store_name = nil) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/redis_object/ext/script_cache.rb', line 73

def expire_all_script_shas(store_name=nil)
	store_obj = store_name.is_a?(String) || store_name.is_a?(Symbol) ? store(store_name.to_sym) : store_name
	store_obj.keys(script_sha_key("*")).each do |k|
		store_obj.del k
	end
	$ScriptSHAMap = {}
end

#get_script_sha(name, source = nil) ⇒ Object



40
41
42
# File 'lib/redis_object/ext/script_cache.rb', line 40

def get_script_sha(name,source=nil)
	$ScriptSHAMap[name] ||= (script_sha_from_key(name) || store_script(name,source))
end

#run_script(name, keys = [], args = [], source = nil, stor = nil) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/redis_object/ext/script_cache.rb', line 19

def run_script(name,keys=[],args=[],source=nil,stor=nil)
	@tmp_store = stor if stor
	@rescue_recurse ||= 0
	begin
		out = (@tmp_store || store).evalsha(get_script_sha(name,source),keys,args)
	rescue Redis::CommandError => e
		if e.message == NoScriptError && @rescue_recurse < 3
			Log.debug "Rescuing NOSCRIPT error for #{name} - running again..."
			untrack_script name
			@rescue_recurse += 1
			out = (@tmp_store || store).evalsha(get_script_sha(name,source),keys,args)
		else
			@rescue_recurse = 0
			raise e
		end
	end
	@rescue_recurse = 0
	remove_instance_variable(:@tmp_store) if @tmp_store
	out
end

#script_sha_from_key(name) ⇒ Object



44
45
46
# File 'lib/redis_object/ext/script_cache.rb', line 44

def script_sha_from_key(name)
	(@tmp_store || store).get(script_sha_key(name))
end

#script_sha_key(name) ⇒ Object



81
82
83
# File 'lib/redis_object/ext/script_cache.rb', line 81

def script_sha_key(name)
	"#{SCRIPT_KEY_PREFIX}#{name.to_s}"
end

#script_source_from_const(name) ⇒ Object



67
68
69
# File 'lib/redis_object/ext/script_cache.rb', line 67

def script_source_from_const(name)
	(self.const_defined?(name.to_sym) && self.const_get(name.to_sym)) || (RedisObject::ScriptSources.const_defined?(name.to_sym) && RedisObject::ScriptSources.const_get(name.to_sym)) || nil
end

#store_script(name, source = nil) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/redis_object/ext/script_cache.rb', line 54

def store_script(name,source=nil)
	source ||= script_source_from_const(name)
	raise SourceNotFoundError unless source
	sha = (@tmp_store || store).script(:load,source)
	(@tmp_store || store).set(script_sha_key(name),sha)
	sha
end

#untrack_script(name) ⇒ Object



62
63
64
65
# File 'lib/redis_object/ext/script_cache.rb', line 62

def untrack_script(name)
	$ScriptSHAMap.delete name
	(@tmp_store || store).del(script_sha_key(name))
end