-
Notifications
You must be signed in to change notification settings - Fork 414
/
lazy_register.rb
76 lines (66 loc) · 2.22 KB
/
lazy_register.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
76
require 'concurrent/atomic/atomic_reference'
require 'concurrent/delay'
module Concurrent
# Hash-like collection that store lazys evaluated values.
#
# @example
# register = Concurrent::LazyRegister.new
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
# register[:key]
# #=> nil
# register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } }
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
# register[:key]
# #=> #<Concurrent::Actor::Reference /ping (Concurrent::Actor::AdHoc)>
class LazyRegister
def initialize
@data = AtomicReference.new(Hash.new)
end
# Element reference. Retrieves the value object corresponding to the
# key object. Returns nil if the key is not found. Raises an exception
# if the stored item raised an exception when the block was evaluated.
#
# @param [Object] key
# @return [Object] value stored for the key or nil if the key is not found
#
# @raise Exception when the initialization block fails
def [](key)
delay = @data.get[key]
delay ? delay.value! : nil
end
# Returns true if the given key is present.
#
# @param [Object] key
# @return [true, false] if the key is registered
def registered?(key)
@data.get.key?(key)
end
alias_method :key?, :registered?
alias_method :has_key?, :registered?
# Element assignment. Associates the value given by value with the
# key given by key.
#
# @param [Object] key
# @yield the object to store under the key
#
# @return [LazyRegister] self
def register(key, &block)
delay = Delay.new(executor: :immediate, &block)
@data.update { |h| h.merge(key => delay) }
self
end
alias_method :add, :register
alias_method :store, :register
# Un-registers the object under key, realized or not.
#
# @param [Object] key
#
# @return [LazyRegister] self
def unregister(key)
@data.update { |h| h.dup.tap { |j| j.delete(key) } }
self
end
alias_method :remove, :unregister
alias_method :delete, :unregister
end
end