Class: Specwrk::Store::FileAdapter
Constant Summary
collapse
- READ_ATTEMPTS =
3
- READ_RETRY_DELAY =
0.01
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from BaseAdapter
#initialize, reset_serializer!, serializer
Class Method Details
.ext ⇒ Object
51
52
53
|
# File 'lib/specwrk/store/file_adapter.rb', line 51
def ext
".wrk.#{serializer.adapter_name}"
end
|
.schedule_work(&blk) ⇒ Object
34
35
36
37
|
# File 'lib/specwrk/store/file_adapter.rb', line 34
def schedule_work(&blk)
start_threads!
@work_queue.push blk
end
|
.start_threads! ⇒ Object
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/specwrk/store/file_adapter.rb', line 39
def start_threads!
return if @threads.length.positive?
Array.new(ENV.fetch("SPECWRK_THREAD_COUNT", "4").to_i) do
@threads << Thread.new do
loop do
@work_queue.pop.call
end
end
end
end
|
.with_lock(uri, key) ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
|
# File 'lib/specwrk/store/file_adapter.rb', line 20
def with_lock(uri, key)
lock_file_path = File.join(uri.path, "#{key}.lock").tap do |path|
FileUtils.mkdir_p(uri.path)
end
lock_file = File.open(lock_file_path, "a")
Thread.pass until lock_file.flock(File::LOCK_EX)
yield
ensure
lock_file.flock(File::LOCK_UN)
end
|
Instance Method Details
#[](key) ⇒ Object
56
57
58
59
60
61
|
# File 'lib/specwrk/store/file_adapter.rb', line 56
def [](key)
content = read(key.to_s)
return unless content
self.class.serializer.load(content)
end
|
#[]=(key, value) ⇒ Object
63
64
65
66
67
68
69
70
71
|
# File 'lib/specwrk/store/file_adapter.rb', line 63
def []=(key, value)
key_string = key.to_s
if value.nil?
delete(key_string)
else
filename = filename_for_key(key_string)
write(filename, self.class.serializer.dump(value))
end
end
|
#clear ⇒ Object
77
78
79
80
|
# File 'lib/specwrk/store/file_adapter.rb', line 77
def clear
FileUtils.rm_rf(path)
FileUtils.mkdir_p(path)
end
|
#delete(*keys) ⇒ Object
82
83
84
85
86
|
# File 'lib/specwrk/store/file_adapter.rb', line 82
def delete(*keys)
filenames = keys.map { |key| filename_for_key key }.compact
FileUtils.rm_f(filenames)
end
|
#empty? ⇒ Boolean
132
133
134
|
# File 'lib/specwrk/store/file_adapter.rb', line 132
def empty?
Dir.empty? path
end
|
#keys ⇒ Object
73
74
75
|
# File 'lib/specwrk/store/file_adapter.rb', line 73
def keys
known_key_pairs.keys
end
|
#merge!(h2) ⇒ Object
88
89
90
|
# File 'lib/specwrk/store/file_adapter.rb', line 88
def merge!(h2)
multi_write(h2)
end
|
#multi_read(*read_keys) ⇒ Object
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/specwrk/store/file_adapter.rb', line 92
def multi_read(*read_keys)
result_queue = Queue.new
read_keys.each do |key|
self.class.schedule_work do
result_queue.push([:ok, key.to_s, read(key)])
rescue => e
result_queue.push([:error, key.to_s, e])
end
end
raw_results = read_keys.length.times.map { result_queue.pop }
error = raw_results.find { |status, _key, _result| status == :error }
raise error.last if error
results = {}
raw_results.each do |_status, key, content|
next if content.nil?
results[key] = self.class.serializer.load(content)
end
read_keys.map { |key| [key.to_s, results[key.to_s]] if results.key?(key.to_s) }.compact.to_h end
|
#multi_write(hash) ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# File 'lib/specwrk/store/file_adapter.rb', line 117
def multi_write(hash)
result_queue = Queue.new
hash_with_filenames = hash.map { |key, value| [key.to_s, [filename_for_key(key.to_s), value]] }.to_h
hash_with_filenames.each do |key, (filename, value)|
content = self.class.serializer.dump(value)
self.class.schedule_work do
result_queue << write(filename, content)
end
end
Thread.pass until result_queue.length == hash.length
end
|