que-web 0.7.2 → 0.9.3

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
- SHA1:
3
- metadata.gz: 70f3a29ddd4f76bdfb0a2aa84d663874366639a4
4
- data.tar.gz: e6887380327c8e50a8a4e3aeb682d4d7408c81f9
2
+ SHA256:
3
+ metadata.gz: ebaed73a196599d197e408d743f11878983bd41946128b414a761f41212f798b
4
+ data.tar.gz: cbf8d59327853afaea14ffc79d6b6633bd56c046b64b8b2200ca29251bc4b2ae
5
5
  SHA512:
6
- metadata.gz: 90343c4a7898f6085ae331a3062006032ff299704431f6e255818b9325423c54902df5f52191574bd840617953e1b6a21477083ca7c47f8922c6cd82403e6025
7
- data.tar.gz: e2b62a44728afe7c43c3d5f14fc873e3c090c792de35a589d7c1dc57df98b2bee8808bd61b88b6d4ed26cf9f4cf8a7ff25597e420fb10a0a3a78e9040a4698e1
6
+ metadata.gz: 6674c985452e1bf8c7aaf159b6efd1d0ef3008bb0020abe7625799a422e76246443c953ff5d4eb7676f8bf0cf4a39e1bee71fcdf3ac97bafafd8f9aa292f6c96
7
+ data.tar.gz: 39c94ab7f64cb5bf20c2e978aa369fd675dde28b058f52ffb4e2af4fec7c91f8d4d14b904b86d0e2f5c35ef02053be68e3b3d1a8edc02aa4d8a1e8941733436f
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1
3
+ - 2.4
4
+ - 2.5
5
+ - 2.6
6
6
  - jruby
7
7
  notifications:
8
8
  email: false
@@ -1,4 +1,32 @@
1
- ### Unreleased
1
+ ### 0.9.3 - 2020-06-17
2
+ #### Added:
3
+ - Set expired_at=NULL when rescheduling job
4
+ - Make job search case-insensitive
5
+ - Allow to search by ActiveJob class name
6
+
7
+ ### 0.9.2 - 2020-04-24
8
+ #### Fixed:
9
+ - Fixed rendering "running" page
10
+ - Fixed displaying relative time on "failing" page
11
+
12
+ ### 0.9.1 - 2020-04-01
13
+ #### Fixed:
14
+ - Fixed rendering HTML
15
+
16
+ ### 0.9.0 - 2020-03-31
17
+ #### Added:
18
+ - Display real job class when wrapped by ActiveJob
19
+ - Updated foundation CSS to latest 5.x version
20
+ - Removed erubis gem dependency
21
+
22
+ #### Fixed:
23
+ - Fixed minitest deprecation warnings
24
+
25
+ ### 0.8 - 2018-09-21
26
+
27
+ #### Compatibility with 1.0.0.beta3 Que:
28
+ - Changed job_id to id
29
+ - Removed pg_* attributes
2
30
 
3
31
  ### 0.7.1 - 2018-03-02
4
32
 
data/README.md CHANGED
@@ -43,18 +43,6 @@ require "que/web"
43
43
  mount Que::Web => "/que"
44
44
  ```
45
45
 
46
- #### Rails 5.0
47
-
48
- You must use the master branch of Sinatra for `que-web`.
49
- In your gemfile:
50
-
51
- ```
52
- gem 'que-web'
53
- gem 'sinatra', git: 'https://github.com/sinatra/sinatra'
54
- ```
55
-
56
- See https://github.com/sinatra/sinatra/issues/1071
57
-
58
46
  ### Authentication
59
47
 
60
48
  #### Devise
@@ -2,24 +2,24 @@ GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
4
  erubis (2.7.0)
5
- mustermann (1.0.1)
5
+ mustermann (1.0.3)
6
6
  pg (1.0.0)
7
- puma (3.11.2)
7
+ puma (3.12.3)
8
8
  que (0.14.2)
9
9
  que-web (0.7.0)
10
10
  erubis
11
11
  que (~> 0.8)
12
12
  sinatra
13
- rack (2.0.4)
14
- rack-protection (2.0.0)
13
+ rack (2.0.8)
14
+ rack-protection (2.0.7)
15
15
  rack
16
16
  sequel (5.5.0)
17
- sinatra (2.0.0)
17
+ sinatra (2.0.7)
18
18
  mustermann (~> 1.0)
19
19
  rack (~> 2.0)
20
- rack-protection (= 2.0.0)
20
+ rack-protection (= 2.0.7)
21
21
  tilt (~> 2.0)
22
- tilt (2.0.8)
22
+ tilt (2.0.10)
23
23
 
24
24
  PLATFORMS
25
25
  ruby
@@ -1,28 +1,28 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- que-web (0.7.0)
5
- erubis
6
- que (~> 0.8)
4
+ que-web (0.9.2)
5
+ que (~> 1.0.0.beta3)
7
6
  sinatra
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
- erubis (2.7.0)
13
- mustermann (1.0.1)
14
- pg (1.0.0)
15
- que (0.14.2)
16
- rack (2.0.4)
17
- rack-protection (2.0.0)
11
+ mustermann (1.1.1)
12
+ ruby2_keywords (~> 0.0.1)
13
+ pg (1.2.3)
14
+ que (1.0.0.beta4)
15
+ rack (2.2.2)
16
+ rack-protection (2.0.8.1)
18
17
  rack
19
- sequel (5.5.0)
20
- sinatra (2.0.0)
18
+ ruby2_keywords (0.0.2)
19
+ sequel (5.31.0)
20
+ sinatra (2.0.8.1)
21
21
  mustermann (~> 1.0)
22
22
  rack (~> 2.0)
23
- rack-protection (= 2.0.0)
23
+ rack-protection (= 2.0.8.1)
24
24
  tilt (~> 2.0)
25
- tilt (2.0.8)
25
+ tilt (2.0.10)
26
26
 
27
27
  PLATFORMS
28
28
  ruby
@@ -33,4 +33,4 @@ DEPENDENCIES
33
33
  sequel
34
34
 
35
35
  BUNDLED WITH
36
- 1.15.3
36
+ 2.1.4
@@ -7,9 +7,8 @@ require 'securerandom'
7
7
 
8
8
  Que.logger = Logger.new(STDOUT)
9
9
  Que.logger.level = Logger::INFO
10
- Que.connection = Sequel.connect "postgres://localhost/quewebtest", max_connections: Que.worker_count + 1
11
- Que.migrate!
12
- Que.mode = :async
10
+ Que.connection = Sequel.connect("postgres://localhost/quewebtest", max_connections: 1)
11
+ Que.migrate!(version: 4)
13
12
  $stdout.sync = true
14
13
 
15
14
  class FailJob < Que::Job
@@ -31,4 +30,3 @@ class SlowJob < Que::Job
31
30
  sleep 15
32
31
  end
33
32
  end
34
-
@@ -22,7 +22,7 @@ end
22
22
 
23
23
  map '/xss' do
24
24
  run lambda { |env|
25
- FailJob.enqueue '<script>alert("xss")</script>', {name: '<script>alert("xss")', age: 20, numbers: [10]*50}
25
+ FailJob.enqueue "<script>alert('xss')</script>", {name: "<script>alert('xss')", age: 20, numbers: [10]*50}
26
26
  [200, {}, ['Failing job queued']]
27
27
  }
28
28
  end
@@ -41,7 +41,6 @@ map '/slow' do
41
41
  }
42
42
  end
43
43
 
44
-
45
44
  map '/delayslow' do
46
45
  run lambda { |env|
47
46
  SlowJob.enqueue 'arg1', {name: 'delayslow', age: 20}, run_at: Time.now + 10
@@ -52,4 +51,3 @@ end
52
51
  run lambda { |env|
53
52
  [200, {}, ['Hello']]
54
53
  }
55
-
@@ -1,5 +1,5 @@
1
1
  require "sinatra/base"
2
- require "erubis"
2
+ require "cgi"
3
3
 
4
4
  module Que
5
5
  class Web < Sinatra::Base
@@ -11,7 +11,6 @@ module Que
11
11
  set :root, File.expand_path("../../../web", __FILE__)
12
12
  set :public_folder, proc { "#{root}/public" }
13
13
  set :views, proc { File.expand_path("views", root) }
14
- set :erb, :escape_html => true
15
14
 
16
15
  get "/" do
17
16
  stats = Que.execute SQL[:dashboard_stats], [search]
@@ -20,7 +19,7 @@ module Que
20
19
  end
21
20
 
22
21
  get "/running" do
23
- worker_states = search_running Que.worker_states
22
+ worker_states = search_running Que.job_states
24
23
  pager = get_pager worker_states.count
25
24
  @list = Viewmodels::JobList.new(worker_states, pager)
26
25
  erb :running
@@ -28,7 +27,7 @@ module Que
28
27
 
29
28
  get "/failing" do
30
29
  stats = Que.execute SQL[:dashboard_stats], [search]
31
- pager = get_pager stats[0]["failing"]
30
+ pager = get_pager stats[0][:failing]
32
31
  failing_jobs = Que.execute SQL[:failing_jobs], [pager.page_size, pager.offset, search]
33
32
  @list = Viewmodels::JobList.new(failing_jobs, pager)
34
33
  erb :failing
@@ -36,9 +35,8 @@ module Que
36
35
 
37
36
  get "/scheduled" do
38
37
  stats = Que.execute SQL[:dashboard_stats], [search]
39
- pager = get_pager stats[0]["scheduled"]
38
+ pager = get_pager stats[0][:scheduled]
40
39
  scheduled_jobs = Que.execute SQL[:scheduled_jobs], [pager.page_size, pager.offset, search]
41
-
42
40
  @list = Viewmodels::JobList.new(scheduled_jobs, pager)
43
41
  erb :scheduled
44
42
  end
@@ -62,12 +60,10 @@ module Que
62
60
  job_id = id.to_i
63
61
  if job_id > 0
64
62
  run_at = Time.now
65
-
66
63
  updated_rows = Que.execute SQL[:reschedule_job], [job_id, run_at]
67
-
68
64
  if updated_rows.empty?
69
65
  # Didn't get the advisory lock
70
- set_flash "warning", "Job #{job_id} not rescheduled as it was already runnning"
66
+ set_flash "warning", "Job #{job_id} not rescheduled as it was already running"
71
67
  else
72
68
  set_flash "info", "Job #{job_id} rescheduled for #{run_at}"
73
69
  end
@@ -105,7 +101,7 @@ module Que
105
101
 
106
102
  if updated_rows.empty?
107
103
  # Didn't get the advisory lock
108
- set_flash "warning", "Job #{job_id} not deleted as it was already runnning"
104
+ set_flash "warning", "Job #{job_id} not deleted as it was already running"
109
105
  else
110
106
  set_flash "info", "Job #{job_id} deleted"
111
107
  end
@@ -163,11 +159,11 @@ module Que
163
159
 
164
160
  def search_running(jobs)
165
161
  return jobs unless search_param
166
- jobs.select { |job| job.fetch('job_class').include? search_param }
162
+ jobs.select { |job| job.fetch(:job_class).include? search_param }
167
163
  end
168
164
 
169
165
  def search_param
170
- sanitised = (params['search'] || '').gsub(/[^0-9a-z:]i/, '')
166
+ sanitised = (params['search'] || '').gsub(/[^0-9a-z:]/i, '')
171
167
  return if sanitised.empty?
172
168
  sanitised
173
169
  end
@@ -183,8 +179,8 @@ module Que
183
179
  end
184
180
 
185
181
  def format_error(job)
186
- return unless job.last_error
187
- line = job.last_error.lines.first || ''
182
+ return unless job.last_error_message
183
+ line = job.last_error_message.lines.first || ''
188
184
  truncate line, 30
189
185
  end
190
186
 
@@ -209,6 +205,13 @@ module Que
209
205
  hash = session[FLASH_KEY] ||= {}
210
206
  hash[level] = val
211
207
  end
208
+
209
+ def html_escape(text)
210
+ return if text.nil?
211
+
212
+ CGI.escape_html(text)
213
+ end
214
+ alias h html_escape
212
215
  end
213
216
  helpers Helpers
214
217
  end
@@ -1,17 +1,17 @@
1
1
  lock_job_sql = <<-SQL.freeze
2
- SELECT job_id, pg_try_advisory_lock(job_id) AS locked
2
+ SELECT id, pg_try_advisory_lock(id) AS locked
3
3
  FROM que_jobs
4
- WHERE job_id = $1::bigint
4
+ WHERE id = $1::bigint
5
5
  SQL
6
6
 
7
7
  lock_all_failing_jobs_sql = <<-SQL.freeze
8
- SELECT job_id, pg_try_advisory_lock(job_id) AS locked
8
+ SELECT id, pg_try_advisory_lock(id) AS locked
9
9
  FROM que_jobs
10
10
  WHERE error_count > 0
11
11
  SQL
12
12
 
13
13
  lock_all_scheduled_jobs_sql = <<-SQL.freeze
14
- SELECT job_id, pg_try_advisory_lock(job_id) AS locked
14
+ SELECT id, pg_try_advisory_lock(id) AS locked
15
15
  FROM que_jobs
16
16
  WHERE error_count = 0
17
17
  SQL
@@ -20,11 +20,12 @@ def reschedule_all_jobs_query(scope)
20
20
  <<-SQL.freeze
21
21
  WITH target AS (#{scope})
22
22
  UPDATE que_jobs
23
- SET run_at = $1::timestamptz
23
+ SET run_at = $1::timestamptz,
24
+ expired_at = NULL
24
25
  FROM target
25
26
  WHERE target.locked
26
- AND target.job_id = que_jobs.job_id
27
- RETURNING pg_advisory_unlock(target.job_id)
27
+ AND target.id = que_jobs.id
28
+ RETURNING pg_advisory_unlock(target.id)
28
29
  SQL
29
30
  end
30
31
 
@@ -34,8 +35,8 @@ def delete_jobs_query(scope)
34
35
  DELETE FROM que_jobs
35
36
  USING target
36
37
  WHERE target.locked
37
- AND target.job_id = que_jobs.job_id
38
- RETURNING pg_advisory_unlock(target.job_id)
38
+ AND target.id = que_jobs.id
39
+ RETURNING pg_advisory_unlock(target.id)
39
40
  SQL
40
41
  end
41
42
 
@@ -50,9 +51,10 @@ Que::Web::SQL = {
50
51
  SELECT (classid::bigint << 32) + objid::bigint AS job_id
51
52
  FROM pg_locks
52
53
  WHERE locktype = 'advisory'
53
- ) locks USING (job_id)
54
+ ) locks ON (que_jobs.id=locks.job_id)
54
55
  WHERE
55
- job_class LIKE ($1)
56
+ job_class ILIKE ($1)
57
+ OR que_jobs.args #>> '{0, job_class}' ILIKE ($1)
56
58
  SQL
57
59
  failing_jobs: <<-SQL.freeze,
58
60
  SELECT que_jobs.*
@@ -61,8 +63,13 @@ Que::Web::SQL = {
61
63
  SELECT (classid::bigint << 32) + objid::bigint AS job_id
62
64
  FROM pg_locks
63
65
  WHERE locktype = 'advisory'
64
- ) locks USING (job_id)
65
- WHERE locks.job_id IS NULL AND error_count > 0 AND job_class LIKE ($3)
66
+ ) locks ON (que_jobs.id=locks.job_id)
67
+ WHERE locks.job_id IS NULL
68
+ AND error_count > 0
69
+ AND (
70
+ job_class ILIKE ($3)
71
+ OR que_jobs.args #>> '{0, job_class}' ILIKE ($3)
72
+ )
66
73
  ORDER BY run_at
67
74
  LIMIT $1::int
68
75
  OFFSET $2::int
@@ -74,8 +81,13 @@ Que::Web::SQL = {
74
81
  SELECT (classid::bigint << 32) + objid::bigint AS job_id
75
82
  FROM pg_locks
76
83
  WHERE locktype = 'advisory'
77
- ) locks USING (job_id)
78
- WHERE locks.job_id IS NULL AND error_count = 0 AND job_class LIKE ($3)
84
+ ) locks ON (que_jobs.id=locks.job_id)
85
+ WHERE locks.job_id IS NULL
86
+ AND error_count = 0
87
+ AND (
88
+ job_class ILIKE ($3)
89
+ OR que_jobs.args #>> '{0, job_class}' ILIKE ($3)
90
+ )
79
91
  ORDER BY run_at
80
92
  LIMIT $1::int
81
93
  OFFSET $2::int
@@ -86,18 +98,19 @@ Que::Web::SQL = {
86
98
  reschedule_job: <<-SQL.freeze,
87
99
  WITH target AS (#{lock_job_sql})
88
100
  UPDATE que_jobs
89
- SET run_at = $2::timestamptz
101
+ SET run_at = $2::timestamptz,
102
+ expired_at = NULL
90
103
  FROM target
91
104
  WHERE target.locked
92
- AND target.job_id = que_jobs.job_id
93
- RETURNING pg_advisory_unlock(target.job_id)
105
+ AND target.id = que_jobs.id
106
+ RETURNING pg_advisory_unlock(target.id)
94
107
  SQL
95
108
  reschedule_all_scheduled_jobs: reschedule_all_jobs_query(lock_all_scheduled_jobs_sql),
96
109
  reschedule_all_failing_jobs: reschedule_all_jobs_query(lock_all_failing_jobs_sql),
97
110
  fetch_job: <<-SQL.freeze,
98
111
  SELECT *
99
112
  FROM que_jobs
100
- WHERE job_id = $1::bigint
113
+ WHERE id = $1::bigint
101
114
  LIMIT 1
102
115
  SQL
103
116
  }.freeze
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  Dir[File.expand_path('../viewmodels/*.rb', __FILE__)].each {|f| require f}
2
4
  module Que::Web::Viewmodels
3
5
  end
@@ -2,7 +2,7 @@ module Que::Web::Viewmodels
2
2
  class Dashboard < Struct.new(:running, :scheduled, :failing)
3
3
  def initialize(stats)
4
4
  members.each do |m|
5
- self[m] = stats[m.to_s]
5
+ self[m] = stats[m]
6
6
  end
7
7
  end
8
8
  end
@@ -1,18 +1,26 @@
1
1
  module Que::Web::Viewmodels
2
2
  class Job < Struct.new(
3
- :args, :error_count, :job_class, :job_id, :last_error,
4
- :pg_backend_pid, :pg_last_query, :pg_last_query_started_at, :pg_state,
5
- :pg_state_changed_at, :pg_transaction_started_at, :pg_waiting_on_lock,
6
- :priority, :queue, :run_at)
3
+ :priority, :run_at, :id, :job_class, :error_count, :last_error_message,
4
+ :queue, :last_error_backtrace, :finished_at, :expired_at, :args, :data,
5
+ :backend_pid)
7
6
 
8
7
  def initialize(job)
9
8
  members.each do |m|
10
- self[m] = job[m.to_s]
9
+ self[m] = job[m]
11
10
  end
12
11
  end
13
12
 
14
13
  def past_due?(relative_to = Time.now)
15
14
  run_at < relative_to
16
15
  end
16
+
17
+ def humanized_job_class
18
+ case job_class
19
+ when "ActiveJob::QueueAdapters::QueAdapter::JobWrapper"
20
+ args.first[:job_class]
21
+ else
22
+ job_class
23
+ end
24
+ end
17
25
  end
18
26
  end