-
-
Notifications
You must be signed in to change notification settings - Fork 432
Expand file tree
/
Copy pathmemory.rb
More file actions
144 lines (123 loc) · 3.56 KB
/
Copy pathmemory.rb
File metadata and controls
144 lines (123 loc) · 3.56 KB
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
77
78
79
80
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
require "flipper/adapter"
require "flipper/typecast"
module Flipper
module Adapters
# Public: Adapter for storing everything in memory.
# Useful for tests/specs.
class Memory
include ::Flipper::Adapter
# Public
def initialize(source = nil, threadsafe: true)
@source = Typecast.features_hash(source)
@lock = Mutex.new if threadsafe
reset
end
# Public: The set of known features.
def features
synchronize { @source.keys }.to_set
end
# Public: Adds a feature to the set of known features.
def add(feature)
synchronize { @source[feature.key] ||= default_config }
true
end
# Public: Removes a feature from the set of known features and clears
# all the values for the feature.
def remove(feature)
synchronize { @source.delete(feature.key) }
true
end
# Public: Clears all the gate values for a feature.
def clear(feature)
synchronize { @source[feature.key] = default_config }
true
end
# Public
def get(feature)
synchronize { @source[feature.key] } || default_config
end
def get_multi(features)
synchronize do
result = {}
features.each do |feature|
result[feature.key] = @source[feature.key] || default_config
end
result
end
end
def get_all(**kwargs)
synchronize { Typecast.features_hash(@source) }
end
# Public
def enable(feature, gate, thing)
synchronize do
@source[feature.key] ||= default_config
case gate.data_type
when :boolean
@source[feature.key] = default_config
@source[feature.key][gate.key] = thing.value.to_s
when :integer
@source[feature.key][gate.key] = thing.value.to_s
when :set
@source[feature.key][gate.key] << thing.value.to_s
when :json
@source[feature.key][gate.key] = thing.value
else
raise "#{gate} is not supported by this adapter yet"
end
true
end
end
# Public
def disable(feature, gate, thing)
synchronize do
@source[feature.key] ||= default_config
case gate.data_type
when :boolean
@source[feature.key] = default_config
when :integer
@source[feature.key][gate.key] = thing.value.to_s
when :set
@source[feature.key][gate.key].delete thing.value.to_s
when :json
@source[feature.key].delete(gate.key)
else
raise "#{gate} is not supported by this adapter yet"
end
true
end
end
# Public
def inspect
attributes = [
'name=:memory',
"source=#{@source.inspect}",
]
"#<#{self.class.name}:#{object_id} #{attributes.join(', ')}>"
end
# Public: a more efficient implementation of import for this adapter
def import(source)
adapter = self.class.from(source)
get_all = Typecast.features_hash(adapter.get_all)
synchronize { @source.replace(get_all) }
true
end
private
def reset
@pid = Process.pid
@lock&.unlock if @lock&.locked?
end
def forked?
@pid != Process.pid
end
def synchronize(&block)
if @lock
reset if forked?
@lock.synchronize(&block)
else
block.call
end
end
end
end
end