specwrk 0.1.0 → 0.1.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 +4 -4
- data/exe/specwrk +1 -1
- data/lib/specwrk/cli.rb +22 -14
- data/lib/specwrk/hookable.rb +4 -0
- data/lib/specwrk/version.rb +1 -1
- data/lib/specwrk/web/app.rb +31 -22
- data/lib/specwrk/web/logger.rb +22 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c16c0b37ed56096253bc295ee77360813c5d1363a68cbd75f3694545448a588
|
4
|
+
data.tar.gz: 365e391b1075fead8b38c00ba57d307c0ee47107acec2a946d2c9484abe89fee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28ecd7dd329f4ca7db54c27fbf1454810c8cf06966c8317e51611820c9ab39adba812377ec2ac99e2c9d902b5456a60e4696545662e2952c2768bdc2a6777477
|
7
|
+
data.tar.gz: 642b25bcf069fd689472c408408baa48e25b9fe8bb32989b89b68e68f210381c9f0e9b160d2c6207e700c356bd9a668b30ae29f093b1c69c0dd42debaf02b72b
|
data/exe/specwrk
CHANGED
@@ -5,7 +5,7 @@ require "specwrk/cli"
|
|
5
5
|
|
6
6
|
trap("INT") do
|
7
7
|
if Specwrk.starting_pid == Process.pid && !Specwrk.force_quit
|
8
|
-
warn "Waiting for in-progress work to finish. Interrupt again to force quit (warning: at_exit hooks will be skipped if you force quit)."
|
8
|
+
warn " ↓ Waiting for in-progress work to finish. Interrupt again to force quit (warning: at_exit hooks will be skipped if you force quit)."
|
9
9
|
|
10
10
|
Specwrk.force_quit = true
|
11
11
|
elsif Specwrk.starting_pid != Process.pid
|
data/lib/specwrk/cli.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
|
3
5
|
require "dry/cli"
|
4
6
|
|
5
7
|
require "specwrk"
|
@@ -13,10 +15,10 @@ module Specwrk
|
|
13
15
|
extend Hookable
|
14
16
|
|
15
17
|
on_included do |base|
|
16
|
-
base.
|
17
|
-
base.
|
18
|
-
base.
|
19
|
-
base.
|
18
|
+
base.unique_option :uri, type: :string, default: ENV.fetch("SPECWRK_SRV_URI", "https://localhost:#{ENV.fetch("SPECWRK_SRV_PORT", "5138")}"), desc: "HTTP URI of the server to pull jobs from. Overrides SPECWRK_SRV_PORT. Default 5138."
|
19
|
+
base.unique_option :key, type: :string, default: ENV.fetch("SPECWRK_SRV_KEY", ""), aliases: ["-k"], desc: "Authentication key clients must use for access. Overrides SPECWRK_SRV_KEY. Default ''."
|
20
|
+
base.unique_option :run, type: :string, default: ENV.fetch("SPECWRK_RUN", "main"), aliases: ["-r"], desc: "The run identifier for this job execution. Overrides SPECWRK_RUN. Default main."
|
21
|
+
base.unique_option :timeout, type: :integer, default: ENV.fetch("SPECWRK_TIMEOUT", "5"), aliases: ["-t"], desc: "The amount of time to wait for the server to respond. Overrides SPECWRK_TIMEOUT. Default 5."
|
20
22
|
end
|
21
23
|
|
22
24
|
on_setup do |uri:, key:, run:, timeout:, **|
|
@@ -31,9 +33,9 @@ module Specwrk
|
|
31
33
|
extend Hookable
|
32
34
|
|
33
35
|
on_included do |base|
|
34
|
-
base.
|
35
|
-
base.
|
36
|
-
base.
|
36
|
+
base.unique_option :id, type: :string, default: "specwrk-worker", desc: "The identifier for this worker. Default specwrk-worker(-COUNT_INDEX)."
|
37
|
+
base.unique_option :count, type: :integer, default: 1, aliases: ["-c"], desc: "The number of worker processes you want to start. Default 1."
|
38
|
+
base.unique_option :output, type: :string, default: ENV.fetch("SPECWRK_OUT", ".specwrk/"), aliases: ["-o"], desc: "Directory where worker output is stored. Overrides SPECWRK_OUT. Default '.specwrk/'."
|
37
39
|
end
|
38
40
|
|
39
41
|
on_setup do |id:, count:, output:, **|
|
@@ -64,14 +66,16 @@ module Specwrk
|
|
64
66
|
extend Hookable
|
65
67
|
|
66
68
|
on_included do |base|
|
67
|
-
base.
|
68
|
-
base.
|
69
|
-
base.
|
70
|
-
base.
|
71
|
-
base.
|
69
|
+
base.unique_option :port, type: :integer, default: ENV.fetch("SPECWRK_SRV_PORT", "5138"), aliases: ["-p"], desc: "Server port. Overrides SPECWRK_SRV_PORT. Default 5138."
|
70
|
+
base.unique_option :key, type: :string, aliases: ["-k"], default: ENV.fetch("SPECWRK_SRV_KEY", ""), desc: "Authentication key clients must use for access. Overrides SPECWRK_SRV_KEY. Default ''."
|
71
|
+
base.unique_option :output, type: :string, default: ENV.fetch("SPECWRK_OUT", ".specwrk/"), aliases: ["-o"], desc: "Directory where worker output is stored. Overrides SPECWRK_OUT. Default '.specwrk/'."
|
72
|
+
base.unique_option :group_by, values: %w[file timings], default: ENV.fetch("SPECWERK_SRV_GROUP_BY", "timings"), desc: "How examples will be grouped for workers; fallback to file if no timings are found. Overrides SPECWERK_SRV_GROUP_BY. Default timings."
|
73
|
+
base.unique_option :single_run, type: :boolean, default: false, desc: "Act on shutdown requests from clients. Default: false."
|
74
|
+
base.unique_option :verbose, type: :boolean, default: false, desc: "Run in verbose mode. Default false."
|
72
75
|
end
|
73
76
|
|
74
|
-
on_setup do |output:, port:, key:, single_run:, group_by:, **|
|
77
|
+
on_setup do |output:, port:, key:, single_run:, group_by:, verbose:, **|
|
78
|
+
ENV["SPECWRK_SRV_LOG"] = Pathname.new(File.join(output, "server.log")).expand_path(Dir.pwd).to_s if output && !verbose
|
75
79
|
ENV["SPECWRK_SRV_OUTPUT"] = Pathname.new(File.join(output, "report.json")).expand_path(Dir.pwd).to_s if output
|
76
80
|
ENV["SPECWRK_SRV_PORT"] = port
|
77
81
|
ENV["SPECWRK_SRV_KEY"] = key
|
@@ -134,7 +138,7 @@ module Specwrk
|
|
134
138
|
class Serve < Dry::CLI::Command
|
135
139
|
include Servable
|
136
140
|
|
137
|
-
desc "Start a server"
|
141
|
+
desc "Start a queue server"
|
138
142
|
|
139
143
|
def call(**args)
|
140
144
|
self.class.setup(**args)
|
@@ -168,6 +172,7 @@ module Specwrk
|
|
168
172
|
Specwrk::Web::App.run!
|
169
173
|
end
|
170
174
|
|
175
|
+
return if Specwrk.force_quit
|
171
176
|
seed_pid = Process.fork do
|
172
177
|
require "specwrk/list_examples"
|
173
178
|
require "specwrk/client"
|
@@ -184,12 +189,15 @@ module Specwrk
|
|
184
189
|
|
185
190
|
wait_for_pids_exit([seed_pid])
|
186
191
|
|
192
|
+
return if Specwrk.force_quit
|
187
193
|
status "Starting #{worker_count} workers..."
|
188
194
|
start_workers
|
189
195
|
|
190
196
|
status "#{worker_count} workers started ✓\n"
|
191
197
|
wait_for_pids_exit(@worker_pids)
|
192
198
|
|
199
|
+
return if Specwrk.force_quit
|
200
|
+
|
193
201
|
require "specwrk/cli_reporter"
|
194
202
|
status = Specwrk::CLIReporter.new.report
|
195
203
|
|
data/lib/specwrk/hookable.rb
CHANGED
@@ -35,6 +35,10 @@ module Hookable
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module ClassMethods
|
38
|
+
def unique_option(name, opts = {})
|
39
|
+
option(name, opts) unless options.find { |existing_option| existing_option.name == name }
|
40
|
+
end
|
41
|
+
|
38
42
|
def setup(**args)
|
39
43
|
setup_hooks.each { |blk| blk.call(**args) }
|
40
44
|
end
|
data/lib/specwrk/version.rb
CHANGED
data/lib/specwrk/web/app.rb
CHANGED
@@ -10,33 +10,49 @@ rescue LoadError
|
|
10
10
|
require "rack/handler/webrick"
|
11
11
|
end
|
12
12
|
|
13
|
+
require "specwrk/web/logger"
|
13
14
|
require "specwrk/web/auth"
|
14
15
|
require "specwrk/web/endpoints"
|
15
16
|
|
16
17
|
module Specwrk
|
17
18
|
class Web
|
18
19
|
class App
|
19
|
-
|
20
|
-
|
20
|
+
class << self
|
21
|
+
def run!
|
22
|
+
Process.setproctitle "specwrk-server"
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
if ENV["SPECWRK_SRV_LOG"]
|
25
|
+
$stdout.reopen(ENV["SPECWRK_SRV_LOG"], "w")
|
26
|
+
end
|
27
|
+
|
28
|
+
server_opts = {
|
29
|
+
Port: ENV.fetch("SPECWRK_SRV_PORT", "5138").to_i,
|
30
|
+
Logger: WEBrick::Log.new($stdout, WEBrick::Log::FATAL),
|
31
|
+
AccessLog: [],
|
32
|
+
KeepAliveTimeout: 300
|
33
|
+
}
|
28
34
|
|
29
|
-
|
30
|
-
|
35
|
+
# rack v3 or v2
|
36
|
+
handler_klass = defined?(Rackup::Handler) ? Rackup::Handler::WEBrick : Rack::Handler.get("webrick")
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
handler_klass.run(rackup, **server_opts) do |server|
|
39
|
+
["INT", "TERM"].each do |sig|
|
40
|
+
trap(sig) do
|
41
|
+
puts "\n→ Shutting down gracefully..." unless ENV["SPECWRK_FORKED"]
|
42
|
+
server.shutdown
|
43
|
+
end
|
37
44
|
end
|
38
45
|
end
|
39
46
|
end
|
47
|
+
|
48
|
+
def rackup
|
49
|
+
Rack::Builder.new do
|
50
|
+
use Rack::Runtime
|
51
|
+
use Specwrk::Web::Logger, $stdout
|
52
|
+
use Specwrk::Web::Auth # global auth check
|
53
|
+
run Specwrk::Web::App.new # your router
|
54
|
+
end
|
55
|
+
end
|
40
56
|
end
|
41
57
|
|
42
58
|
def call(env)
|
@@ -47,13 +63,6 @@ module Specwrk
|
|
47
63
|
.response
|
48
64
|
end
|
49
65
|
|
50
|
-
private_class_method def self.rackup
|
51
|
-
Rack::Builder.new do
|
52
|
-
use Specwrk::Web::Auth # global auth check
|
53
|
-
run Specwrk::Web::App.new # your router
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
66
|
def route(method:, path:)
|
58
67
|
case [method, path]
|
59
68
|
when ["GET", "/heartbeat"]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Specwrk
|
4
|
+
class Web
|
5
|
+
class Logger
|
6
|
+
def initialize(app, out = $stdout)
|
7
|
+
@app, @out = app, out
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
start_time = Time.now
|
12
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
13
|
+
status, headers, body = @app.call(env)
|
14
|
+
dur_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(4)
|
15
|
+
|
16
|
+
remote = env["REMOTE_ADDR"] || env["REMOTE_HOST"] || "-"
|
17
|
+
@out.puts "#{remote} [#{start_time.iso8601(6)}] #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]} → #{status} (#{dur_ms}ms)"
|
18
|
+
[status, headers, body]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
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.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Westendorf
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/specwrk/web/app.rb
|
148
148
|
- lib/specwrk/web/auth.rb
|
149
149
|
- lib/specwrk/web/endpoints.rb
|
150
|
+
- lib/specwrk/web/logger.rb
|
150
151
|
- lib/specwrk/worker.rb
|
151
152
|
- lib/specwrk/worker/completion_formatter.rb
|
152
153
|
- lib/specwrk/worker/executor.rb
|