Class: LiveResource::RedisClient
- Inherits:
-
Object
- Object
- LiveResource::RedisClient
show all
- Includes:
- LogHelper
- Defined in:
- lib/live_resource/redis_client.rb,
lib/live_resource/redis_client/methods.rb,
lib/live_resource/redis_client/attributes.rb,
lib/live_resource/redis_client/registration.rb
Constant Summary
collapse
- @@logger =
Logger.new(STDERR)
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from LogHelper
#logger, #logger=
Constructor Details
#initialize(resource_class, resource_name) ⇒ RedisClient
Returns a new instance of RedisClient.
31
32
33
34
35
36
|
# File 'lib/live_resource/redis_client.rb', line 31
def initialize(resource_class, resource_name)
@redis_class = RedisClient.redisized_key(resource_class)
@redis_name = RedisClient.redisized_key(resource_name)
self.logger = self.class.logger
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *params, &block) ⇒ Object
38
39
40
41
42
43
44
|
# File 'lib/live_resource/redis_client.rb', line 38
def method_missing(method, *params, &block)
if self.class.redis.respond_to? method
redis_command(method, params, &block)
else
super
end
end
|
Instance Attribute Details
#redis=(value) ⇒ Object
25
26
27
|
# File 'lib/live_resource/redis_client.rb', line 25
def redis=(value)
@redis = value
end
|
#redis_class ⇒ Object
Returns the value of attribute redis_class.
26
27
28
|
# File 'lib/live_resource/redis_client.rb', line 26
def redis_class
@redis_class
end
|
#redis_name ⇒ Object
Returns the value of attribute redis_name.
26
27
28
|
# File 'lib/live_resource/redis_client.rb', line 26
def redis_name
@redis_name
end
|
Class Method Details
.logger ⇒ Object
73
74
75
|
# File 'lib/live_resource/redis_client.rb', line 73
def self.logger
@@logger
end
|
.logger=(logger) ⇒ Object
77
78
79
|
# File 'lib/live_resource/redis_client.rb', line 77
def self.logger=(logger)
@@logger = logger
end
|
.redis ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/live_resource/redis_client.rb', line 56
def self.redis
@@redis ||= {}
@@proto_redis ||= Redis.new
if @@redis[Thread.current].nil?
@@redis[Thread.current] = @@proto_redis.clone
end
@@redis[Thread.current]
end
|
.redis=(redis) ⇒ Object
68
69
70
71
|
# File 'lib/live_resource/redis_client.rb', line 68
def self.redis=(redis)
@@proto_redis = redis
@@redis = {}
end
|
.redisized_key(word) ⇒ Object
81
82
83
84
85
86
87
88
89
|
# File 'lib/live_resource/redis_client.rb', line 81
def self.redisized_key(word)
word = word.to_s.dup
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!("-", "_")
word.gsub!('::', '-')
word.downcase!
word
end
|
Instance Method Details
#all ⇒ Object
15
16
17
18
19
20
21
22
23
|
# File 'lib/live_resource/redis_client/registration.rb', line 15
def all
names = []
hgetall(instances_key).each_pair do |i, count|
names << i if (count.to_i > 0)
end
names
end
|
#attribute_read(key, options = {}) ⇒ Object
23
24
25
|
# File 'lib/live_resource/redis_client/attributes.rb', line 23
def attribute_read(key, options={})
deserialize(get("#{@redis_class}.#{@redis_name}.attributes.#{key}"))
end
|
#attribute_watch(key) ⇒ Object
36
37
38
|
# File 'lib/live_resource/redis_client/attributes.rb', line 36
def attribute_watch(key)
watch("#{@redis_class}.#{redis_name}.attributes.#{key}")
end
|
#attribute_write(key, value, options = {}) ⇒ Object
27
28
29
30
31
32
33
34
|
# File 'lib/live_resource/redis_client/attributes.rb', line 27
def attribute_write(key, value, options={})
redis_key = "#{@redis_class}.#{@redis_name}.attributes.#{key}"
if options[:no_overwrite]
setnx(redis_key, serialize(value))
else
set(redis_key, serialize(value))
end
end
|
#exec ⇒ Object
Override default (Ruby) exec with Redis exec.
52
53
54
|
# File 'lib/live_resource/redis_client.rb', line 52
def exec
redis_command(:exec, nil)
end
|
#instances_key ⇒ Object
3
4
5
|
# File 'lib/live_resource/redis_client/registration.rb', line 3
def instances_key
"#{@redis_class}.instances"
end
|
#method_details(token) ⇒ Object
21
22
23
|
# File 'lib/live_resource/redis_client/methods.rb', line 21
def method_details(token)
"#{token.redis_class}.#{token.redis_name}.method.#{token.seq}"
end
|
#method_discard_result(token) ⇒ Object
129
130
131
132
|
# File 'lib/live_resource/redis_client/methods.rb', line 129
def method_discard_result(token)
del result_details(token)
del method_details(token)
end
|
#method_done(token) ⇒ Object
50
51
52
|
# File 'lib/live_resource/redis_client/methods.rb', line 50
def method_done(token)
lrem methods_in_progress_list, 0, serialize(token)
end
|
#method_done_with?(method) ⇒ Boolean
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
# File 'lib/live_resource/redis_client/methods.rb', line 134
def method_done_with?(method)
st = serialize(method.token)
multi
lrange methods_list, 0, -1
lrange methods_in_progress_list, 0, -1
lrange result_details(method.token), 0, -1
result = exec
if (result[2] != [])
true
elsif result[0].include?(st) or result[1].include?(st)
false
else
raise ArgumentError.new("No method #{token} pending")
end
end
|
#method_get(token) ⇒ Object
54
55
56
57
58
|
# File 'lib/live_resource/redis_client/methods.rb', line 54
def method_get(token)
method = get method_details(token)
deserialize(method)
end
|
#method_push(token) ⇒ Object
46
47
48
|
# File 'lib/live_resource/redis_client/methods.rb', line 46
def method_push(token)
lpush methods_list, serialize(token)
end
|
#method_result(method, result) ⇒ Object
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/live_resource/redis_client/methods.rb', line 81
def method_result(method, result)
token = method.token
watch method_details(token)
unless exists(method_details(token))
warn "setting result for method #{token}, but caller deleted it"
unwatch
return
end
begin
multi
lpush result_details(token), serialize(result)
exec
rescue RuntimeError => e
warn e
discard
end
end
|
#method_send(method) ⇒ Object
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/live_resource/redis_client/methods.rb', line 60
def method_send(method)
unless method.token
loop do
method.token = RemoteMethodToken.new(
@redis_class,
@redis_name,
sprintf("%05d", Kernel.rand(100000)))
break if setnx(method_details(method.token), serialize(method))
end
else
set method_details(method.token), serialize(method)
end
method_push method.token
method
end
|
#method_wait ⇒ Object
41
42
43
44
|
# File 'lib/live_resource/redis_client/methods.rb', line 41
def method_wait
token = brpoplpush methods_list, methods_in_progress_list, 0
deserialize(token)
end
|
#method_wait_for_result(method, timeout) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/live_resource/redis_client/methods.rb', line 107
def method_wait_for_result(method, timeout)
token = method.token
result = nil
begin
list, result = brpop result_details(token), timeout
if result.nil?
raise RuntimeError.new("timed out waiting for method #{token}")
end
result = deserialize(result)
rescue
method_cleanup(token)
raise
ensure
del method_details(token)
end
end
|
#methods_in_progress_list ⇒ Object
17
18
19
|
# File 'lib/live_resource/redis_client/methods.rb', line 17
def methods_in_progress_list
"#{@redis_class}.#{@redis_name}.methods_in_progress"
end
|
#methods_list ⇒ Object
13
14
15
|
# File 'lib/live_resource/redis_client/methods.rb', line 13
def methods_list
"#{@redis_class}.#{@redis_name}.methods_pending"
end
|
#register ⇒ Object
7
8
9
|
# File 'lib/live_resource/redis_client/registration.rb', line 7
def register
hincrby instances_key, @redis_name, 1
end
|
#register_attributes(attributes) ⇒ Object
11
12
13
14
15
|
# File 'lib/live_resource/redis_client/attributes.rb', line 11
def register_attributes(attributes)
unless attributes.empty?
sadd remote_attributes_key, attributes
end
end
|
#register_methods(methods) ⇒ Object
29
30
31
32
33
|
# File 'lib/live_resource/redis_client/methods.rb', line 29
def register_methods(methods)
unless methods.empty?
sadd remote_methods_key, methods
end
end
|
#registered_attributes ⇒ Object
17
18
19
20
21
|
# File 'lib/live_resource/redis_client/attributes.rb', line 17
def registered_attributes
attributes = smembers remote_attributes_key
attributes.map { |a| a.to_sym }
end
|
#registered_methods ⇒ Object
35
36
37
38
39
|
# File 'lib/live_resource/redis_client/methods.rb', line 35
def registered_methods
methods = smembers remote_methods_key
methods.map { |m| m.to_sym }
end
|
#remote_attributes_key ⇒ Object
3
4
5
6
7
8
9
|
# File 'lib/live_resource/redis_client/attributes.rb', line 3
def remote_attributes_key
if @redis_class == "class"
"#{@redis_name}.class_attributes"
else
"#{@redis_class}.attributes"
end
end
|
#remote_methods_key ⇒ Object
5
6
7
8
9
10
11
|
# File 'lib/live_resource/redis_client/methods.rb', line 5
def remote_methods_key
if @redis_class == "class"
"#{@redis_name}.class_methods"
else
"#{@redis_class}.methods"
end
end
|
#respond_to?(method) ⇒ Boolean
46
47
48
49
|
# File 'lib/live_resource/redis_client.rb', line 46
def respond_to?(method)
return true if self.class.redis.respond_to?(method)
super
end
|
#result_details(token) ⇒ Object
25
26
27
|
# File 'lib/live_resource/redis_client/methods.rb', line 25
def result_details(token)
"#{token.redis_class}.#{token.redis_name}.result.#{token.seq}"
end
|
#unregister ⇒ Object
11
12
13
|
# File 'lib/live_resource/redis_client/registration.rb', line 11
def unregister
hincrby instances_key, @redis_name, -1
end
|