postjob 0.3.8 → 0.4.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 +4 -4
- data/lib/postjob/cli/db.rb +10 -0
- data/lib/postjob/cli/version.rb +10 -0
- data/lib/postjob/migrations.rb +3 -0
- data/lib/postjob/migrations/010_settings.sql +7 -0
- data/lib/postjob/queue.rb +1 -0
- data/lib/postjob/queue/search.rb +44 -68
- data/lib/postjob/queue/settings.rb +13 -0
- data/spec/postjob/queue/search_spec.rb +47 -79
- data/spec/spec_helper.rb +1 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bb4b3e0053cc36fb49b56b5711559dd4758ccab
|
4
|
+
data.tar.gz: 5d16630d479c92c4287c03201f3b3a5f28f9126f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 052a5b8e8db5e7b13b1c48d7e2a1daadf575f013374634d7f3cca32eefb95d0a0c5ad25d17be223d68807481b63fb64305de4f213835f67c07484bf3c4a39fd3
|
7
|
+
data.tar.gz: 8616e9115a0b6a1e4f5c0e709864b0878db39d65aa4f04ca195b9fe2c79ae54988e0b5678557a1be40e9eebed398280deb577e24927a58cb5a97bc26dabc5921
|
data/lib/postjob/cli/db.rb
CHANGED
@@ -2,6 +2,16 @@ require "postjob/cli"
|
|
2
2
|
require "postjob/migrations"
|
3
3
|
|
4
4
|
module Postjob::CLI
|
5
|
+
# Prints all settings in the queue
|
6
|
+
def db_settings
|
7
|
+
connect_to_database!
|
8
|
+
|
9
|
+
raise "No settings in this database schema" unless ::Postjob::Queue.settings?
|
10
|
+
|
11
|
+
records = "SELECT name,value FROM postjob.settings ORDER BY name"
|
12
|
+
tp Simple::SQL.all(records, into: Hash)
|
13
|
+
end
|
14
|
+
|
5
15
|
def db_migrate
|
6
16
|
connect_to_database!
|
7
17
|
Postjob::Migrations.migrate!
|
data/lib/postjob/migrations.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# rubocop:disable Security/Eval
|
2
2
|
|
3
3
|
module Postjob
|
4
|
+
VERSION = Gem.loaded_specs["postjob"].version
|
5
|
+
|
4
6
|
module Migrations
|
5
7
|
extend self
|
6
8
|
|
7
9
|
SQL = ::Simple::SQL
|
8
10
|
SCHEMA_NAME = ::Postjob::Queue::SCHEMA_NAME
|
9
11
|
CHANNEL = ::Postjob::Queue::Notifications::CHANNEL
|
12
|
+
CLIENT_VERSION = "ruby/#{::Postjob::VERSION}"
|
10
13
|
|
11
14
|
# Note that the SCHEMA_NAME should not be the default name, since unmigrate!
|
12
15
|
# below drops that schema, and we don't want to drop the default schema.
|
@@ -0,0 +1,7 @@
|
|
1
|
+
CREATE TABLE IF NOT EXISTS {SCHEMA_NAME}.settings (
|
2
|
+
name VARCHAR PRIMARY KEY NOT NULL,
|
3
|
+
value VARCHAR
|
4
|
+
);
|
5
|
+
|
6
|
+
INSERT INTO {SCHEMA_NAME}.settings (name, value) VALUES('version', '0.4.0') ON CONFLICT DO NOTHING;
|
7
|
+
INSERT INTO {SCHEMA_NAME}.settings (name, value) VALUES('client_version', '{CLIENT_VERSION}') ON CONFLICT DO NOTHING;
|
data/lib/postjob/queue.rb
CHANGED
data/lib/postjob/queue/search.rb
CHANGED
@@ -1,81 +1,57 @@
|
|
1
1
|
module Postjob::Queue
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
2
|
+
DEFAULT_ATTRIBUTES = [
|
3
|
+
"id",
|
4
|
+
"full_id",
|
5
|
+
"workflow || COALESCE('@' || workflow_version, '') || args AS job",
|
6
|
+
"workflow_status",
|
7
|
+
"status",
|
8
|
+
"error",
|
9
|
+
"COALESCE((results->0)::varchar, error_message) AS result",
|
10
|
+
"next_run_at",
|
11
|
+
"error_backtrace",
|
12
|
+
"(now() at time zone 'utc') - created_at AS age",
|
13
|
+
"updated_at - created_at AS runtime",
|
14
|
+
"tags"
|
15
|
+
]
|
16
|
+
|
17
|
+
# Builds a search scope (see Simple::SQL::Scope) for the passed in filter criteria.
|
18
|
+
def search(filter = {})
|
19
|
+
expect! filter => Hash
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
# extract options
|
22
|
+
filter = filter.dup
|
23
|
+
root_only = filter.delete(:root_only) || false
|
24
|
+
attributes = filter.delete(:attributes) || DEFAULT_ATTRIBUTES
|
25
|
+
expect! attributes => Array
|
26
|
+
|
27
|
+
# build Scope
|
28
|
+
scope = Simple::SQL::Scope.new("SELECT #{attributes.join(", ")} FROM #{SCHEMA_NAME}.postjobs")
|
29
|
+
scope = scope.where("root_id=id") if root_only
|
30
|
+
scope = apply_filters(scope, filter) if filter && !filter.empty?
|
31
|
+
scope
|
17
32
|
end
|
18
33
|
|
19
34
|
private
|
20
35
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
expect! { page >= 0 && per > 0 }
|
26
|
-
expect! filter => Hash
|
27
|
-
|
28
|
-
conditions = []
|
29
|
-
conditions << "id=#{id}" if id
|
30
|
-
conditions << "root_id=id" if root_only
|
31
|
-
conditions << tags_condition(filter)
|
32
|
-
|
33
|
-
query = base_query(conditions)
|
34
|
-
query = paginated_query query, per: per, page: page
|
35
|
-
query
|
36
|
-
end
|
37
|
-
|
38
|
-
def paginated_query(query, per:, page:)
|
39
|
-
expect! per => Integer
|
40
|
-
expect! page => Integer
|
36
|
+
def apply_filters(scope, filter)
|
37
|
+
filter.each_key do |key|
|
38
|
+
expect! key => [Symbol, String]
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
SQL
|
45
|
-
end
|
41
|
+
column_names = Simple::SQL::Reflection.columns("#{SCHEMA_NAME}.postjobs")
|
42
|
+
column_names += column_names.map(&:to_sym)
|
46
43
|
|
47
|
-
|
48
|
-
conditions.compact!
|
49
|
-
conditions << "TRUE"
|
50
|
-
condition_fragment = conditions
|
51
|
-
.compact
|
52
|
-
.map { |s| "(#{s})" }
|
53
|
-
.join(" AND ")
|
44
|
+
column_filters, tags_filters = filter.partition { |key, _| column_names.include?(key) }
|
54
45
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
full_id,
|
59
|
-
workflow || COALESCE('@' || workflow_version, '') || args AS job,
|
60
|
-
workflow_status,
|
61
|
-
status,
|
62
|
-
error,
|
63
|
-
COALESCE((results->0)::varchar, error_message) AS result,
|
64
|
-
next_run_at,
|
65
|
-
error_backtrace,
|
66
|
-
(now() at time zone 'utc') - created_at AS age,
|
67
|
-
updated_at - created_at AS runtime,
|
68
|
-
tags
|
69
|
-
FROM postjob.postjobs
|
70
|
-
WHERE #{condition_fragment}
|
71
|
-
ORDER BY id
|
72
|
-
SQL
|
73
|
-
end
|
46
|
+
scope = column_filters.inject(scope) do |sc, (key, value)|
|
47
|
+
sc.where(key => value)
|
48
|
+
end
|
74
49
|
|
75
|
-
|
76
|
-
|
77
|
-
|
50
|
+
unless tags_filters.empty?
|
51
|
+
tags_filters = Hash[tags_filters]
|
52
|
+
scope = scope.where "tags @> '#{Postjob::Queue::Encoder.encode(tags_filters)}'"
|
53
|
+
end
|
78
54
|
|
79
|
-
|
55
|
+
scope
|
80
56
|
end
|
81
57
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Postjob::Queue
|
2
|
+
def settings?
|
3
|
+
tables = SQL::Reflection.tables(schema: "postjob")
|
4
|
+
tables.include?("postjob.settings")
|
5
|
+
end
|
6
|
+
|
7
|
+
# returns the version of the Postjob queue.
|
8
|
+
def version
|
9
|
+
return "0.3.*" unless settings?
|
10
|
+
|
11
|
+
SQL.ask("SELECT value FROM postjob.settings WHERE name=$1", "version") || "unknown"
|
12
|
+
end
|
13
|
+
end
|
@@ -19,32 +19,22 @@ module SearchWorkflow
|
|
19
19
|
Postjob.register_workflow self
|
20
20
|
end
|
21
21
|
|
22
|
-
describe "Postjob::Queue
|
23
|
-
let!(:id) { Postjob.enqueue! "SearchWorkflow", tags: { "initial" => "yay" } }
|
24
|
-
|
22
|
+
describe "Postjob::Queue.search" do
|
25
23
|
include TestHelper
|
26
24
|
|
27
|
-
Search = Postjob::Queue::Search
|
28
|
-
|
29
25
|
before do
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def load_child_job
|
34
|
-
TestHelper.load_job "SELECT * FROM postjobs WHERE parent_id=$1", id
|
26
|
+
Simple::SQL.ask("DELETE FROM postjob.postjobs")
|
35
27
|
end
|
36
28
|
|
37
|
-
|
38
|
-
load_token(load_child_job)
|
39
|
-
end
|
29
|
+
let!(:id) { Postjob.enqueue! "SearchWorkflow", tags: { "initial" => "yay" } }
|
40
30
|
|
41
|
-
|
42
|
-
expect! token => /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[a-fA-F0-9]{4}-[A-F0-9]{12}/i
|
43
|
-
end
|
31
|
+
Queue = Postjob::Queue
|
44
32
|
|
45
|
-
|
33
|
+
context "attributes" do
|
46
34
|
it "returns a specific set of attributes" do
|
47
|
-
|
35
|
+
scope = Postjob::Queue.search(id: id)
|
36
|
+
result = Simple::SQL.ask scope, into: Hash
|
37
|
+
|
48
38
|
expected_keys = [
|
49
39
|
:id,
|
50
40
|
:full_id,
|
@@ -59,81 +49,59 @@ describe "Postjob::Queue::Search" do
|
|
59
49
|
:runtime,
|
60
50
|
:tags
|
61
51
|
]
|
52
|
+
expect(result.keys).to include(*expected_keys)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "with attributes: argument it only returns the specified attributes" do
|
56
|
+
scope = Postjob::Queue.search(attributes: %w(id))
|
57
|
+
result = Simple::SQL.ask scope, into: Hash
|
58
|
+
|
59
|
+
expected_keys = [
|
60
|
+
:id
|
61
|
+
]
|
62
62
|
expect(result.keys).to contain_exactly(*expected_keys)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
expect(
|
70
|
-
|
66
|
+
context "with multiple jobs" do
|
67
|
+
before do
|
68
|
+
Postjob.enqueue! "SearchWorkflow", tags: { "secondary" => "yay" }
|
69
|
+
expect(Simple::SQL.ask("SELECT COUNT(*) FROM postjob.postjobs")).to eq(2)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns all entries" do
|
73
|
+
scope = Postjob::Queue.search
|
74
|
+
result = Simple::SQL.all(scope, into: OpenStruct)
|
75
|
+
expect(result.length).to eq(2)
|
71
76
|
end
|
72
77
|
|
73
|
-
it "
|
74
|
-
|
75
|
-
|
76
|
-
|
78
|
+
it "sorts by id" do
|
79
|
+
scope = Postjob::Queue.search
|
80
|
+
result = Simple::SQL.all(scope, into: OpenStruct)
|
81
|
+
|
82
|
+
# Note that the second job has a id larger than the original job's id.
|
83
|
+
expect(result.first.id).to eq(id)
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
80
|
-
describe "
|
87
|
+
describe "filtering" do
|
81
88
|
it "can find a job by id" do
|
82
|
-
|
83
|
-
|
89
|
+
scope = Postjob::Queue.search(id: id)
|
90
|
+
result = Simple::SQL.ask scope, into: Hash
|
91
|
+
expect(result[:id]).to eq(id)
|
84
92
|
end
|
85
93
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
it "returns all entries" do
|
92
|
-
result = Search.all into: OpenStruct
|
93
|
-
expect(result.length).to eq(2)
|
94
|
-
end
|
95
|
-
|
96
|
-
it "honors page and per arguments" do
|
97
|
-
result = Search.all into: OpenStruct, page: 0, per: 1
|
98
|
-
expect(result.length).to eq(1)
|
99
|
-
expect(result.first.id).to eq(id)
|
100
|
-
|
101
|
-
result = Search.all into: OpenStruct, page: 1, per: 1
|
102
|
-
expect(result.length).to eq(1)
|
103
|
-
expect(result.first.id).not_to eq(id)
|
104
|
-
|
105
|
-
result = Search.all into: OpenStruct, page: 2, per: 1
|
106
|
-
expect(result.length).to eq(0)
|
107
|
-
|
108
|
-
expect do
|
109
|
-
Search.all into: OpenStruct, page: -10
|
110
|
-
end.to raise_error(ArgumentError)
|
111
|
-
|
112
|
-
expect do
|
113
|
-
Search.all into: OpenStruct, per: -10
|
114
|
-
end.to raise_error(ArgumentError)
|
115
|
-
end
|
116
|
-
|
117
|
-
it "sorts by id" do
|
118
|
-
# Note that the second job has a id larger than the original job's id.
|
119
|
-
result = Search.all into: OpenStruct
|
120
|
-
expect(result.first.id).to eq(id)
|
121
|
-
end
|
94
|
+
it "positive filters by tags" do
|
95
|
+
scope = Postjob::Queue.search("initial" => "yay")
|
96
|
+
result = Simple::SQL.all scope, into: OpenStruct
|
97
|
+
expect(result.length).to eq(1)
|
98
|
+
expect(result.first.id).to eq(id)
|
122
99
|
end
|
123
100
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
expect(result.length).to eq(1)
|
129
|
-
expect(result.first.id).to eq(id)
|
130
|
-
end
|
131
|
-
|
132
|
-
it "negative filters by tags" do
|
133
|
-
filter = { "initial" => "nay" }
|
134
|
-
result = Search.all filter: filter, into: OpenStruct
|
135
|
-
expect(result.length).to eq(0)
|
136
|
-
end
|
101
|
+
it "negative filters by tags" do
|
102
|
+
scope = Postjob::Queue.search("initial" => "nay")
|
103
|
+
result = Simple::SQL.all(scope)
|
104
|
+
expect(result.length).to eq(0)
|
137
105
|
end
|
138
106
|
end
|
139
107
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -29,6 +29,7 @@ RSpec.configure do |config|
|
|
29
29
|
config.filter_run focus: (ENV["CI"] != "true")
|
30
30
|
config.expect_with(:rspec) { |c| c.syntax = :expect }
|
31
31
|
config.order = "random"
|
32
|
+
config.example_status_persistence_file_path = ".rspec.persistence"
|
32
33
|
|
33
34
|
config.before(:all) {}
|
34
35
|
config.after {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postjob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
version: '0.4'
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
version: 0.4.
|
126
|
+
version: 0.4.5
|
127
127
|
type: :runtime
|
128
128
|
prerelease: false
|
129
129
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -133,7 +133,7 @@ dependencies:
|
|
133
133
|
version: '0.4'
|
134
134
|
- - ">="
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: 0.4.
|
136
|
+
version: 0.4.5
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
138
|
name: simple-cli
|
139
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- lib/postjob/cli/job.rb
|
211
211
|
- lib/postjob/cli/ps.rb
|
212
212
|
- lib/postjob/cli/run.rb
|
213
|
+
- lib/postjob/cli/version.rb
|
213
214
|
- lib/postjob/error.rb
|
214
215
|
- lib/postjob/job.rb
|
215
216
|
- lib/postjob/migrations.rb
|
@@ -225,10 +226,12 @@ files:
|
|
225
226
|
- lib/postjob/migrations/008_checkout_runnable.sql
|
226
227
|
- lib/postjob/migrations/008a_childjobs.sql
|
227
228
|
- lib/postjob/migrations/009_tokens.sql
|
229
|
+
- lib/postjob/migrations/010_settings.sql
|
228
230
|
- lib/postjob/queue.rb
|
229
231
|
- lib/postjob/queue/encoder.rb
|
230
232
|
- lib/postjob/queue/notifications.rb
|
231
233
|
- lib/postjob/queue/search.rb
|
234
|
+
- lib/postjob/queue/settings.rb
|
232
235
|
- lib/postjob/registry.rb
|
233
236
|
- lib/postjob/runner.rb
|
234
237
|
- lib/postjob/workflow.rb
|