Module: LiveResource::Attributes
- Included in:
- Resource
- Defined in:
- lib/live_resource/attributes.rb
Instance Method Summary collapse
- #redis ⇒ Object
-
#remote_attribute_modify(*attributes, &block) ⇒ Object
Modify an attribute or set of attributes based on the current value(s).
- #remote_attribute_read(key, options = {}) ⇒ Object
- #remote_attribute_write(key, value, options = {}) ⇒ Object
-
#remote_attribute_writenx(key, value) ⇒ Object
Write a new value to an attribute if it doesn’t exist yet.
- #remote_attributes ⇒ Object
Instance Method Details
#redis ⇒ Object
3 4 5 |
# File 'lib/live_resource/attributes.rb', line 3 def redis @_redis ||= RedisClient.new(resource_class, resource_name) end |
#remote_attribute_modify(*attributes, &block) ⇒ Object
Modify an attribute or set of attributes based on the current value(s). Uses the optimistic locking mechanism provided by Redis WATCH/MULTI/EXEC transactions.
The user passes in the a block which will be used to update the attribute(s). Since the block may need to be replayed, the user should not update any external state that relies on the block executing only once.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/live_resource/attributes.rb', line 39 def remote_attribute_modify(*attributes, &block) invalid_attrs = attributes - redis.registered_attributes unless invalid_attrs.empty? raise ArgumentError.new("remote_modify: no such attribute(s) '#{invalid_attrs}'") end unless block raise ArgumentError.new("remote_modify requires a block") end # Optimistic locking implemented along the lines of: # http://redis.io/topics/transactions loop do # Gather up the attributes and their new values mods = attributes.map do |a| # Watch/get the value redis.attribute_watch(a) v = redis.attribute_read(a) # Block modifies the value v = block.call(a, v) [a, v] end # Start the transaction redis.multi mods.each do |mod| # Set to new value; if ok, we're done. redis.attribute_write(mod[0], mod[1]) end # Attempt to execute the transaction. Otherwise we'll loop and # try again with the new value. break if redis.exec end end |
#remote_attribute_read(key, options = {}) ⇒ Object
15 16 17 |
# File 'lib/live_resource/attributes.rb', line 15 def remote_attribute_read(key, = {}) redis.attribute_read(key, ) end |
#remote_attribute_write(key, value, options = {}) ⇒ Object
19 20 21 22 23 24 25 |
# File 'lib/live_resource/attributes.rb', line 19 def remote_attribute_write(key, value, = {}) if (key.to_sym == self.class.resource_name_attr) and !self.is_a?(Class) @_redis = RedisClient.new(resource_class, value) end redis.attribute_write(key, value, ) end |
#remote_attribute_writenx(key, value) ⇒ Object
Write a new value to an attribute if it doesn’t exist yet.
28 29 30 |
# File 'lib/live_resource/attributes.rb', line 28 def remote_attribute_writenx(key, value) remote_attribute_write(key, value, no_overwrite: true) end |
#remote_attributes ⇒ Object
7 8 9 10 11 12 13 |
# File 'lib/live_resource/attributes.rb', line 7 def remote_attributes if self.is_a? Class [] else self.class.remote_instance_attributes end end |