specwrk 0.10.0 → 0.10.2

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: 656884cedc1e6851a42054d696fb0c8cbb3c7afffa48935340c973d824cc6cc0
4
- data.tar.gz: e8b562b8070e5342d6343b299a80fe0bc98a17060632aa369f5ded91ffecb820
3
+ metadata.gz: 4570e3aaeb01c00647b8671803076848bf28dee5068ec0cde66c88effea85bbe
4
+ data.tar.gz: 1d6709fc4b518ca5dcbad15e59820ba855adebb5dc6830ec26cc7f92d59f597d
5
5
  SHA512:
6
- metadata.gz: a536a0bf7de4959ca820afa5e9249024181f198d073ca648f040f8f4276f63572ac74a1cdff481b9e050b1983f7af7eac5b2d31c3271dff911ae88aa75092f27
7
- data.tar.gz: eddaa254e6254727f950006b30b653402a33acd827b1060baf583840d99ae2d41dec0ab4a15c11754c03db3f2664ea348efefc1b32b95b494c56287a0d3b88d0
6
+ metadata.gz: 3868e891fc3c14a8ce281b747d8e5b0c271e55f946f1fe1d23aa4d88d940ee40ea966fbf32bce5711ca1597c7870a8a4b1aa1bac610f117a9695888015eee6db
7
+ data.tar.gz: 385faa8d85c751eca15e1203ab626ec8d9abe3584e79265550dc52b18c81327f6a837535827dd63d56bc5fb0671fe11c8bd91698a96dc0d9a82d36a23edc7430
@@ -1,11 +1,6 @@
1
1
  FROM ruby:3.4-alpine
2
2
 
3
- RUN apk add --no-cache \
4
- build-base \
5
- ruby-dev \
6
- linux-headers \
7
- zlib-dev \
8
- libffi-dev
3
+ RUN apk add --no-cache build-base
9
4
 
10
5
  WORKDIR /app
11
6
 
@@ -13,14 +8,15 @@ RUN mkdir .specwrk/
13
8
 
14
9
  ARG SPECWRK_SRV_PORT=5138
15
10
  ARG SPECWRK_VERSION=latest
16
- ARG GEMFILE=specwrk-$SPECWRK_VERSION.gem
11
+ ARG GEM_FILE=specwrk-$SPECWRK_VERSION.gem
17
12
 
18
- COPY $GEMFILE ./
19
- RUN gem install ./$GEMFILE --no-document
20
- RUN rm ./$GEMFILE
13
+ COPY $GEM_FILE ./
14
+ RUN gem install ./$GEM_FILE --no-document
15
+ RUN rm ./$GEM_FILE
21
16
 
22
- RUN gem install puma thruster
17
+ RUN gem install pitchfork thruster
23
18
  COPY config.ru ./
19
+ COPY docker/pitchfork.conf ./
24
20
 
25
21
  COPY docker/entrypoint.server.sh /usr/local/bin/entrypoint
26
22
  RUN chmod +x /usr/local/bin/entrypoint
@@ -2,6 +2,6 @@
2
2
 
3
3
  export THRUSTER_HTTP_PORT=${PORT:-5138}
4
4
  export THRUSTER_TARGET_PORT=3000
5
- export THRUSTER_HTTP_IDLE_TIMEOUT=${IDLE_TIMEOUT:-305}
5
+ export THRUSTER_HTTP_IDLE_TIMEOUT=${IDLE_TIMEOUT:-300}
6
6
 
7
- exec thrust puma --workers 0 --bind tcp://127.0.0.1:3000 --threads ${PUMA_THREADS:-1} --workers ${PUMA_WORKERS:-0}
7
+ exec thrust pitchfork -c pitchfork.conf
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ worker_processes 1
4
+ listen "localhost:3000", backlog: 2048
5
+ timeout 301
@@ -10,20 +10,24 @@ module Specwrk
10
10
  class FileAdapter
11
11
  EXT = ".wrk.json"
12
12
 
13
- THREAD_POOL = Class.new do
14
- @work_queue = Queue.new
13
+ @work_queue = Queue.new
14
+ @threads = []
15
15
 
16
- @threads = Array.new(ENV.fetch("SPECWRK_SRV_FILE_ADAPTER_THREAD_COUNT", "4").to_i) do
17
- Thread.new do
18
- loop do
19
- @work_queue.pop.call
20
- end
21
- end
16
+ class << self
17
+ def schedule_work(&blk)
18
+ start_threads!
19
+ @work_queue.push blk
22
20
  end
23
21
 
24
- class << self
25
- def schedule(&blk)
26
- @work_queue.push blk
22
+ def start_threads!
23
+ return if @threads.length.positive?
24
+
25
+ Array.new(ENV.fetch("SPECWRK_THREAD_COUNT", "4").to_i) do
26
+ @threads << Thread.new do
27
+ loop do
28
+ @work_queue.pop.call
29
+ end
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -80,7 +84,7 @@ module Specwrk
80
84
  result_queue = Queue.new
81
85
 
82
86
  read_keys.each do |key|
83
- THREAD_POOL.schedule do
87
+ self.class.schedule_work do
84
88
  result_queue.push([key.to_s, read(key)])
85
89
  end
86
90
  end
@@ -107,7 +111,7 @@ module Specwrk
107
111
  hash_with_filenames.each do |key, (filename, value)|
108
112
  content = JSON.generate(value)
109
113
 
110
- THREAD_POOL.schedule do
114
+ self.class.schedule_work do
111
115
  result_queue << write(filename, content)
112
116
  end
113
117
  end
data/lib/specwrk/store.rb CHANGED
@@ -7,40 +7,24 @@ require "specwrk/store/file_adapter"
7
7
 
8
8
  module Specwrk
9
9
  class Store
10
- MUTEXES = {}
11
- MUTEXES_MUTEX = Mutex.new # 🐢🐢🐢🐢
12
-
13
- class << self
14
- def mutex_for(path)
15
- MUTEXES_MUTEX.synchronize do
16
- MUTEXES[path] ||= Mutex.new
17
- end
18
- end
19
- end
20
-
21
- def initialize(path, thread_safe_reads: true)
10
+ def initialize(path)
22
11
  @path = path
23
- @thread_safe_reads = thread_safe_reads
24
12
  end
25
13
 
26
14
  def [](key)
27
- sync(thread_safe: thread_safe_reads) { adapter[key.to_s] }
15
+ adapter[key.to_s]
28
16
  end
29
17
 
30
18
  def multi_read(*keys)
31
- sync(thread_safe: thread_safe_reads) { adapter.multi_read(*keys) }
19
+ adapter.multi_read(*keys)
32
20
  end
33
21
 
34
22
  def []=(key, value)
35
- sync do
36
- adapter[key.to_s] = value
37
- end
23
+ adapter[key.to_s] = value
38
24
  end
39
25
 
40
26
  def keys
41
- all_keys = sync(thread_safe: thread_safe_reads) do
42
- adapter.keys
43
- end
27
+ all_keys = adapter.keys
44
28
 
45
29
  all_keys.reject { |k| k.start_with? "____" }
46
30
  end
@@ -54,28 +38,24 @@ module Specwrk
54
38
  end
55
39
 
56
40
  def empty?
57
- sync(thread_safe: thread_safe_reads) do
58
- adapter.empty?
59
- end
41
+ adapter.empty?
60
42
  end
61
43
 
62
44
  def delete(*keys)
63
- sync { adapter.delete(*keys) }
45
+ adapter.delete(*keys)
64
46
  end
65
47
 
66
48
  def merge!(h2)
67
49
  h2.transform_keys!(&:to_s)
68
- sync { adapter.merge!(h2) }
50
+ adapter.merge!(h2)
69
51
  end
70
52
 
71
53
  def clear
72
- sync { adapter.clear }
54
+ adapter.clear
73
55
  end
74
56
 
75
57
  def to_h
76
- sync(thread_safe: thread_safe_reads) do
77
- adapter.multi_read(*keys).transform_keys!(&:to_sym)
78
- end
58
+ adapter.multi_read(*keys).transform_keys!(&:to_sym)
79
59
  end
80
60
 
81
61
  def inspect
@@ -92,16 +72,6 @@ module Specwrk
92
72
 
93
73
  private
94
74
 
95
- attr_reader :thread_safe_reads
96
-
97
- def sync(thread_safe: true)
98
- if !thread_safe || mutex.owned?
99
- yield
100
- else
101
- mutex.synchronize { yield }
102
- end
103
- end
104
-
105
75
  def adapter
106
76
  @adapter ||= FileAdapter.new(@path)
107
77
  end
@@ -123,15 +93,13 @@ module Specwrk
123
93
  end
124
94
 
125
95
  def shift_bucket
126
- sync do
127
- return bucket_by_file unless run_time_bucket_maximum&.positive?
128
-
129
- case ENV["SPECWRK_SRV_GROUP_BY"]
130
- when "file"
131
- bucket_by_file
132
- else
133
- bucket_by_timings
134
- end
96
+ return bucket_by_file unless run_time_bucket_maximum&.positive?
97
+
98
+ case ENV["SPECWRK_SRV_GROUP_BY"]
99
+ when "file"
100
+ bucket_by_file
101
+ else
102
+ bucket_by_timings
135
103
  end
136
104
  end
137
105
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Specwrk
4
- VERSION = "0.10.0"
4
+ VERSION = "0.10.2"
5
5
  end
@@ -28,7 +28,7 @@ module Specwrk
28
28
  private
29
29
 
30
30
  def unauthorized
31
- [401, {"Content-Type" => "application/json"}, ["Unauthorized"]]
31
+ [401, {"content-type" => "application/json"}, ["Unauthorized"]]
32
32
  end
33
33
  end
34
34
  end
@@ -51,11 +51,11 @@ module Specwrk
51
51
  end
52
52
 
53
53
  def not_found
54
- [404, {"Content-Type" => "text/plain"}, ["This is not the path you're looking for, 'ol chap..."]]
54
+ [404, {"content-type" => "text/plain"}, ["This is not the path you're looking for, 'ol chap..."]]
55
55
  end
56
56
 
57
57
  def ok
58
- [200, {"Content-Type" => "text/plain"}, ["OK, 'ol chap"]]
58
+ [200, {"content-type" => "text/plain"}, ["OK, 'ol chap"]]
59
59
  end
60
60
 
61
61
  def payload
@@ -83,11 +83,11 @@ module Specwrk
83
83
  end
84
84
 
85
85
  def metadata
86
- @metadata ||= Store.new(File.join(datastore_path, "metadata"), thread_safe_reads: false)
86
+ @metadata ||= Store.new(File.join(datastore_path, "metadata"))
87
87
  end
88
88
 
89
89
  def run_times
90
- @run_times ||= Store.new(File.join(ENV["SPECWRK_OUT"], "run_times"), thread_safe_reads: false)
90
+ @run_times ||= Store.new(File.join(ENV["SPECWRK_OUT"], "run_times"))
91
91
  end
92
92
 
93
93
  def worker
@@ -230,11 +230,11 @@ module Specwrk
230
230
  processing.merge!(processing_data)
231
231
 
232
232
  if @examples.any?
233
- [200, {"Content-Type" => "application/json"}, [JSON.generate(@examples)]]
233
+ [200, {"content-type" => "application/json"}, [JSON.generate(@examples)]]
234
234
  elsif pending.empty? && processing.empty? && completed.empty?
235
- [204, {"Content-Type" => "text/plain"}, ["Waiting for sample to be seeded."]]
235
+ [204, {"content-type" => "text/plain"}, ["Waiting for sample to be seeded."]]
236
236
  elsif completed.any? && processing.empty?
237
- [410, {"Content-Type" => "text/plain"}, ["That's a good lad. Run along now and go home."]]
237
+ [410, {"content-type" => "text/plain"}, ["That's a good lad. Run along now and go home."]]
238
238
  else
239
239
  not_found
240
240
  end
@@ -253,11 +253,11 @@ module Specwrk
253
253
  processing.merge!(processing_data)
254
254
 
255
255
  if @examples.any?
256
- [200, {"Content-Type" => "application/json"}, [JSON.generate(@examples)]]
256
+ [200, {"content-type" => "application/json"}, [JSON.generate(@examples)]]
257
257
  elsif pending.empty? && processing.empty? && completed.empty?
258
- [204, {"Content-Type" => "text/plain"}, ["Waiting for sample to be seeded."]]
258
+ [204, {"content-type" => "text/plain"}, ["Waiting for sample to be seeded."]]
259
259
  elsif completed.any? && processing.empty?
260
- [410, {"Content-Type" => "text/plain"}, ["That's a good lad. Run along now and go home."]]
260
+ [410, {"content-type" => "text/plain"}, ["That's a good lad. Run along now and go home."]]
261
261
  else
262
262
  not_found
263
263
  end
@@ -288,7 +288,7 @@ module Specwrk
288
288
 
289
289
  class Report < Base
290
290
  def with_response
291
- [200, {"Content-Type" => "application/json"}, [JSON.generate(completed.dump)]]
291
+ [200, {"content-type" => "application/json"}, [JSON.generate(completed.dump)]]
292
292
  end
293
293
  end
294
294
 
@@ -299,7 +299,7 @@ module Specwrk
299
299
 
300
300
  interupt! if ENV["SPECWRK_SRV_SINGLE_RUN"]
301
301
 
302
- [200, {"Content-Type" => "text/plain"}, ["✌️"]]
302
+ [200, {"content-type" => "text/plain"}, ["✌️"]]
303
303
  end
304
304
 
305
305
  def interupt!
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.10.0
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Westendorf
@@ -180,6 +180,7 @@ files:
180
180
  - config.ru
181
181
  - docker/Dockerfile.server
182
182
  - docker/entrypoint.server.sh
183
+ - docker/pitchfork.conf
183
184
  - examples/circleci/config.yml
184
185
  - examples/github/specwrk-multi-node.yml
185
186
  - examples/github/specwrk-single-node.yml