Class: AsyncStorage::Allocator
- Inherits:
-
Object
- Object
- AsyncStorage::Allocator
- Extended by:
- Forwardable
- Defined in:
- lib/async_storage/allocator.rb
Constant Summary collapse
- CTRL =
{ enqueued: '0', executed: '1', missing: nil, }.freeze
Instance Attribute Summary collapse
-
#naming ⇒ Object
readonly
Returns the value of attribute naming.
Instance Method Summary collapse
-
#exist? ⇒ Boolean
Check if a fresh value exist.
-
#fresh? ⇒ Boolean
Check if a fresh object exists into the storage.
-
#get ⇒ Object, NilClass
Async get value with a given key.
-
#get! ⇒ Object
Sync get value with a given value.
-
#initialize(repo, *args) ⇒ Allocator
constructor
A new instance of Allocator.
-
#invalidate ⇒ Boolean
Expire object the object with a given key.
-
#invalidate! ⇒ Boolean
Delete object with a given key.
-
#refresh ⇒ Object, NilClass
Invalidate object with the given key and update content according to the strategy.
-
#refresh! ⇒ Object
Fetch data from resolver and store it into redis.
-
#stale? ⇒ NilClass, Boolean
Check if object with a given key is stale.
Constructor Details
#initialize(repo, *args) ⇒ Allocator
Returns a new instance of Allocator.
21 22 23 24 25 26 27 28 29 |
# File 'lib/async_storage/allocator.rb', line 21 def initialize(repo, *args) @repo = repo @args = args @naming = AsyncStorage::Naming.new(repo.resolver_class, *args) # It's different than the config.namespace. # Thinking about a directory structure.. The global namespace would be the root directory. # And the namespace under Repo level would be the subdirectory. @naming.prefix = repo.namespace if repo.namespace end |
Instance Attribute Details
#naming ⇒ Object (readonly)
Returns the value of attribute naming.
17 18 19 |
# File 'lib/async_storage/allocator.rb', line 17 def naming @naming end |
Instance Method Details
#exist? ⇒ Boolean
Check if a fresh value exist.
121 122 123 124 125 |
# File 'lib/async_storage/allocator.rb', line 121 def exist? breaker.run(fallback: -> { false }) do connection { |redis| redis.exists?(naming.head) && redis.exists?(naming.body) } end end |
#fresh? ⇒ Boolean
Check if a fresh object exists into the storage
139 140 141 142 143 |
# File 'lib/async_storage/allocator.rb', line 139 def fresh? breaker.run(fallback: -> { false }) do connection { |redis| redis.exists?(naming.body) && redis.ttl(naming.head) > 0 } end end |
#get ⇒ Object, NilClass
Async get value with a given key
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/async_storage/allocator.rb', line 34 def get breaker.run(fallback: -> { fetch! }) do connection do |redis| raw_head = redis.get(naming.head) case raw_head when CTRL[:executed], CTRL[:enqueued] read_body(redis) # Try to deliver stale content when CTRL[:missing] return update!(redis) unless async? perform_async(redis) # Enqueue background job to resolve content redis.set(naming.head, CTRL[:enqueued]) read_body(redis) # Try to deliver stale content else raise AsyncStorage::Error, format('the key %<k>s have an invalid value. Only "1" or "0" values are expected. And we got %<v>p', v: raw_head, k: naming.head) end end end end |
#get! ⇒ Object
Sync get value with a given value
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/async_storage/allocator.rb', line 57 def get! breaker.run(fallback: -> { fetch! }) do connection do |redis| raw_head = redis.get(naming.head) case raw_head when CTRL[:executed] read_body(redis) || begin update!(redis) unless redis.exists?(naming.body) end when CTRL[:missing], CTRL[:enqueued] update!(redis) else raise AsyncStorage::Error, format('the key %<k>s have an invalid value. Only "1" or "0" values are expected. And we got %<v>p', v: raw_head, k: naming.head) end end end end |
#invalidate ⇒ Boolean
Expire object the object with a given key. The stale object will not be removed
78 79 80 81 82 83 84 |
# File 'lib/async_storage/allocator.rb', line 78 def invalidate breaker.run(fallback: -> { false }) do connection do |redis| redis.del(naming.head) == 1 end end end |
#invalidate! ⇒ Boolean
Delete object with a given key.
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/async_storage/allocator.rb', line 89 def invalidate! breaker.run(fallback: -> { false }) do connection do |redis| redis.multi do |cli| cli.del(naming.body) cli.del(naming.head) end.include?(1) end end end |
#refresh ⇒ Object, NilClass
Invalidate object with the given key and update content according to the strategy
103 104 105 106 107 |
# File 'lib/async_storage/allocator.rb', line 103 def refresh breaker.run(fallback: -> { fetch! }) do get.tap { invalidate } end end |
#refresh! ⇒ Object
Fetch data from resolver and store it into redis
112 113 114 115 116 |
# File 'lib/async_storage/allocator.rb', line 112 def refresh! breaker.run(fallback: -> { fetch! }) do connection { |redis| update!(redis) } end end |
#stale? ⇒ NilClass, Boolean
Check if object with a given key is stale
130 131 132 133 134 |
# File 'lib/async_storage/allocator.rb', line 130 def stale? breaker.run(fallback: -> { false }) do connection { |redis| redis.exists?(naming.body) && redis.ttl(naming.head) < 0 } end end |