specwrk 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc8e7bf6a7d8bebb0a79a536f403a51fd6cf88948e69e4d03304cd62a039290e
4
- data.tar.gz: c0f58e84e321b6407cefb18bad2ad42344f8919ff754471725ab498072e54267
3
+ metadata.gz: 690eaebf0ec2f7621284bc0ce56d6613001bdffc6297651b9d4f6da7a439971b
4
+ data.tar.gz: 8d3104699becc543cbe5aaa6f2b6537d931d34d0e931d720b254262d5b2889a9
5
5
  SHA512:
6
- metadata.gz: 22fc0af6d23a344521e870194f6ea6c943b313c6596ec3b420a103e533a34ad60fe262b5138b8d0dcdbe1644850cdc633e28510c30d4c0ecea07e9607a4c23e3
7
- data.tar.gz: 2a0b62e8140bd41efdbc62838bc8972ce56d9b7f3d7cd316479d5264d16909af2aef9f699d4262cb8dcc2960fdd5ae361a978729403a960b3fd55e0e880060fa
6
+ metadata.gz: 52210c132192267d027e6756e9b34e7871544a968e57627f433d7f5bcef5f8211cd1a548721f6903269397a07c547f65bbd89816a0c4e576e3f9e22a958e777f
7
+ data.tar.gz: 43132d8f86f99fa6932f479e3bcb0a1c9d224dcd62a2f6b59f18910c9a2ef6d24560d1ad48d35d1c5ce4c7df483ed0d42ebe05663c4d6a94b3899bb0cdb9cda2
data/lib/specwrk/cli.rb CHANGED
@@ -8,6 +8,7 @@ require "dry/cli"
8
8
 
9
9
  require "specwrk"
10
10
  require "specwrk/hookable"
11
+ require "specwrk/store"
11
12
 
12
13
  module Specwrk
13
14
  module CLI
@@ -136,13 +137,15 @@ module Specwrk
136
137
  base.unique_option :output, type: :string, default: ENV.fetch("SPECWRK_OUT", ".specwrk/"), aliases: ["-o"], desc: "Directory where worker or server output is stored. Overrides SPECWRK_OUT"
137
138
  base.unique_option :store_uri, type: :string, desc: "Directory where server state is stored. Required for multi-node or multi-process servers."
138
139
  base.unique_option :group_by, values: %w[file timings], default: ENV.fetch("SPECWRK_SRV_GROUP_BY", "timings"), desc: "How examples will be grouped for workers; fallback to file if no timings are found. Overrides SPECWRK_SRV_GROUP_BY"
140
+ base.unique_option :store_serializer, values: %w[json msgpack], default: ENV.fetch("SPECWRK_STORE_SERIALIZER", "json"), desc: "Serializer to use for store payloads. Overrides SPECWRK_STORE_SERIALIZER"
139
141
  base.unique_option :verbose, type: :boolean, default: false, desc: "Run in verbose mode"
140
142
  end
141
143
 
142
- on_setup do |port:, bind:, output:, key:, group_by:, verbose:, **opts|
144
+ on_setup do |port:, bind:, output:, key:, group_by:, verbose:, store_serializer:, **opts|
143
145
  ENV["SPECWRK_OUT"] = Pathname.new(output).expand_path(Dir.pwd).to_s
144
146
  ENV["SPECWRK_SRV_STORE_URI"] = opts[:store_uri] if opts.key? :store_uri
145
147
  ENV["SPECWRK_SRV_VERBOSE"] = "1" if verbose
148
+ ENV["SPECWRK_STORE_SERIALIZER"] = store_serializer
146
149
 
147
150
  ENV["SPECWRK_SRV_PORT"] = port
148
151
  ENV["SPECWRK_SRV_BIND"] = bind
@@ -11,6 +11,14 @@ module Specwrk
11
11
  def with_lock(_uri, _key)
12
12
  yield
13
13
  end
14
+
15
+ def serializer
16
+ @serializer ||= Serializer.resolve
17
+ end
18
+
19
+ def reset_serializer!
20
+ @serializer = nil
21
+ end
14
22
  end
15
23
 
16
24
  def initialize(uri, scope)
@@ -3,14 +3,14 @@
3
3
  require "json"
4
4
  require "base64"
5
5
  require "securerandom"
6
+ require "fileutils"
6
7
 
7
8
  require "specwrk/store/base_adapter"
9
+ require "specwrk/store/serializer"
8
10
 
9
11
  module Specwrk
10
12
  class Store
11
13
  class FileAdapter < BaseAdapter
12
- EXT = ".wrk.json"
13
-
14
14
  @work_queue = Queue.new
15
15
  @threads = []
16
16
 
@@ -45,13 +45,17 @@ module Specwrk
45
45
  end
46
46
  end
47
47
  end
48
+
49
+ def ext
50
+ ".wrk.#{serializer.adapter_name}"
51
+ end
48
52
  end
49
53
 
50
54
  def [](key)
51
55
  content = read(key.to_s)
52
56
  return unless content
53
57
 
54
- JSON.parse(content, symbolize_names: true)
58
+ self.class.serializer.load(content)
55
59
  end
56
60
 
57
61
  def []=(key, value)
@@ -60,7 +64,7 @@ module Specwrk
60
64
  delete(key_string)
61
65
  else
62
66
  filename = filename_for_key(key_string)
63
- write(filename, JSON.generate(value))
67
+ write(filename, self.class.serializer.dump(value))
64
68
  end
65
69
  end
66
70
 
@@ -99,7 +103,7 @@ module Specwrk
99
103
  result = result_queue.pop
100
104
  next if result.last.nil?
101
105
 
102
- results[result.first] = JSON.parse(result.last, symbolize_names: true)
106
+ results[result.first] = self.class.serializer.load(result.last)
103
107
  end
104
108
 
105
109
  read_keys.map { |key| [key.to_s, results[key.to_s]] if results.key?(key.to_s) }.compact.to_h # respect order requested in the returned hash
@@ -110,7 +114,7 @@ module Specwrk
110
114
 
111
115
  hash_with_filenames = hash.map { |key, value| [key.to_s, [filename_for_key(key.to_s), value]] }.to_h
112
116
  hash_with_filenames.each do |key, (filename, value)|
113
- content = JSON.generate(value)
117
+ content = self.class.serializer.dump(value)
114
118
 
115
119
  self.class.schedule_work do
116
120
  result_queue << write(filename, content)
@@ -137,7 +141,7 @@ module Specwrk
137
141
 
138
142
  def read(key)
139
143
  filename = filename_for_key key
140
- File.read(filename)
144
+ File.binread(filename)
141
145
  rescue Errno::ENOENT
142
146
  nil
143
147
  end
@@ -146,7 +150,7 @@ module Specwrk
146
150
  File.join(
147
151
  path,
148
152
  encode_key(key)
149
- ) + EXT
153
+ ) + self.class.ext
150
154
  end
151
155
 
152
156
  def path
@@ -160,7 +164,7 @@ module Specwrk
160
164
  end
161
165
 
162
166
  def decode_key(key)
163
- encoded_key_part = File.basename(key).delete_suffix(EXT)
167
+ encoded_key_part = File.basename(key).delete_suffix(self.class.ext)
164
168
  padding_count = (4 - encoded_key_part.length % 4) % 4
165
169
 
166
170
  Base64.urlsafe_decode64(encoded_key_part + ("=" * padding_count))
@@ -169,7 +173,7 @@ module Specwrk
169
173
  def known_key_pairs
170
174
  Dir.entries(path).sort.map do |filename|
171
175
  next if filename.start_with? "."
172
- next unless filename.end_with? EXT
176
+ next unless filename.end_with? self.class.ext
173
177
 
174
178
  file_path = File.join(path, filename)
175
179
  [decode_key(filename), file_path]
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Specwrk
6
+ class Store
7
+ module Serializers
8
+ module JSON
9
+ module_function
10
+
11
+ def adapter_name
12
+ "json"
13
+ end
14
+
15
+ def dump(value)
16
+ ::JSON.generate(value)
17
+ end
18
+
19
+ def load(payload)
20
+ ::JSON.parse(payload, symbolize_names: true)
21
+ end
22
+ end
23
+
24
+ module MessagePack
25
+ module_function
26
+
27
+ def ensure_loaded!
28
+ require "msgpack"
29
+ rescue LoadError
30
+ raise LoadError, "Unable to use msgpack, gem not found. Add `gem 'msgpack' to your Gemfile and bundle install"
31
+ end
32
+
33
+ module_function
34
+
35
+ def adapter_name
36
+ "msgpack"
37
+ end
38
+
39
+ def dump(value)
40
+ ensure_loaded!
41
+
42
+ ::MessagePack.dump(value)
43
+ end
44
+
45
+ def load(payload)
46
+ ensure_loaded!
47
+
48
+ ::MessagePack.load(payload, symbolize_keys: true)
49
+ end
50
+ end
51
+ end
52
+
53
+ module Serializer
54
+ module_function
55
+
56
+ def resolve(name = ENV.fetch("SPECWRK_STORE_SERIALIZER", "json"))
57
+ return name if name.respond_to?(:dump) && name.respond_to?(:load)
58
+
59
+ case name.to_s.downcase
60
+ when "", "json"
61
+ Serializers::JSON
62
+ when "msgpack", "messagepack"
63
+ Serializers::MessagePack.tap(&:ensure_loaded!)
64
+ else
65
+ raise ArgumentError, "Unsupported serializer #{name.inspect}. Choose json or msgpack."
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Specwrk
4
- VERSION = "0.18.0"
4
+ VERSION = "0.19.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: specwrk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Westendorf
@@ -177,6 +177,20 @@ dependencies:
177
177
  - - ">="
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0'
180
+ - !ruby/object:Gem::Dependency
181
+ name: msgpack
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
180
194
  email:
181
195
  - daniel@prowestech.com
182
196
  executables:
@@ -217,6 +231,7 @@ files:
217
231
  - lib/specwrk/store/memory_adapter.rb
218
232
  - lib/specwrk/store/pending_store.rb
219
233
  - lib/specwrk/store/processing_store.rb
234
+ - lib/specwrk/store/serializer.rb
220
235
  - lib/specwrk/store/worker_store.rb
221
236
  - lib/specwrk/version.rb
222
237
  - lib/specwrk/watcher.rb