good_job 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/README.md +1 -1
  4. data/engine/app/assets/vendor/rails_ujs.js +747 -0
  5. data/engine/app/controllers/good_job/assets_controller.rb +4 -0
  6. data/engine/app/controllers/good_job/cron_entries_controller.rb +19 -0
  7. data/engine/app/filters/good_job/base_filter.rb +6 -5
  8. data/engine/app/filters/good_job/executions_filter.rb +1 -1
  9. data/engine/app/filters/good_job/jobs_filter.rb +1 -1
  10. data/engine/app/views/good_job/cron_entries/index.html.erb +51 -0
  11. data/engine/app/views/good_job/cron_entries/show.html.erb +4 -0
  12. data/engine/app/views/good_job/{shared/_executions_table.erb → executions/_table.erb} +1 -1
  13. data/engine/app/views/good_job/executions/index.html.erb +1 -1
  14. data/engine/app/views/good_job/{shared/_jobs_table.erb → jobs/_table.erb} +3 -3
  15. data/engine/app/views/good_job/jobs/index.html.erb +1 -1
  16. data/engine/app/views/good_job/jobs/show.html.erb +2 -2
  17. data/engine/app/views/good_job/shared/_filter.erb +9 -10
  18. data/engine/app/views/good_job/shared/icons/_play.html.erb +4 -0
  19. data/engine/app/views/layouts/good_job/base.html.erb +2 -1
  20. data/engine/config/routes.rb +8 -1
  21. data/{engine/app/models → lib}/good_job/active_job_job.rb +0 -0
  22. data/lib/good_job/configuration.rb +1 -1
  23. data/lib/good_job/cron_entry.rb +75 -4
  24. data/lib/good_job/cron_manager.rb +1 -5
  25. data/lib/good_job/current_thread.rb +26 -8
  26. data/lib/good_job/execution.rb +15 -13
  27. data/lib/good_job/version.rb +1 -1
  28. metadata +14 -11
  29. data/engine/app/controllers/good_job/cron_schedules_controller.rb +0 -9
  30. data/engine/app/views/good_job/cron_schedules/index.html.erb +0 -72
@@ -23,6 +23,10 @@ module GoodJob
23
23
  render file: GoodJob::Engine.root.join("app", "assets", "vendor", "chartist", "chartist.js")
24
24
  end
25
25
 
26
+ def rails_ujs_js
27
+ render file: GoodJob::Engine.root.join("app", "assets", "vendor", "rails_ujs.js")
28
+ end
29
+
26
30
  def style_css
27
31
  render file: GoodJob::Engine.root.join("app", "assets", "style.css")
28
32
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ module GoodJob
3
+ class CronEntriesController < GoodJob::BaseController
4
+ def index
5
+ @cron_entries = CronEntry.all
6
+ end
7
+
8
+ def show
9
+ @cron_entry = CronEntry.find(params[:id])
10
+ @jobs_filter = JobsFilter.new(params, @cron_entry.jobs)
11
+ end
12
+
13
+ def enqueue
14
+ @cron_entry = CronEntry.find(params[:id])
15
+ @cron_entry.enqueue(Time.current)
16
+ redirect_back(fallback_location: cron_entries_path, notice: "Cron entry has been enqueued.")
17
+ end
18
+ end
19
+ end
@@ -3,10 +3,11 @@ module GoodJob
3
3
  class BaseFilter
4
4
  DEFAULT_LIMIT = 25
5
5
 
6
- attr_accessor :params
6
+ attr_accessor :params, :base_query
7
7
 
8
- def initialize(params)
8
+ def initialize(params, base_query = nil)
9
9
  @params = params
10
+ @base_query = base_query || default_base_query
10
11
  end
11
12
 
12
13
  def records
@@ -24,13 +25,13 @@ module GoodJob
24
25
 
25
26
  def job_classes
26
27
  base_query.group("serialized_params->>'job_class'").count
27
- .sort_by { |name, _count| name }
28
+ .sort_by { |name, _count| name.to_s }
28
29
  .to_h
29
30
  end
30
31
 
31
32
  def queues
32
33
  base_query.group(:queue_name).count
33
- .sort_by { |name, _count| name }
34
+ .sort_by { |name, _count| name.to_s }
34
35
  .to_h
35
36
  end
36
37
 
@@ -94,7 +95,7 @@ module GoodJob
94
95
 
95
96
  private
96
97
 
97
- def base_query
98
+ def default_base_query
98
99
  raise NotImplementedError
99
100
  end
100
101
 
@@ -12,7 +12,7 @@ module GoodJob
12
12
 
13
13
  private
14
14
 
15
- def base_query
15
+ def default_base_query
16
16
  GoodJob::Execution.all
17
17
  end
18
18
 
@@ -14,7 +14,7 @@ module GoodJob
14
14
 
15
15
  private
16
16
 
17
- def base_query
17
+ def default_base_query
18
18
  GoodJob::ActiveJobJob.all
19
19
  end
20
20
 
@@ -0,0 +1,51 @@
1
+ <% if @cron_entries.present? %>
2
+ <div class="card my-3">
3
+ <div class="table-responsive">
4
+ <table class="table card-table table-bordered table-hover table-sm mb-0">
5
+ <thead>
6
+ <th>Key</th>
7
+ <th>Schedule</th>
8
+ <th>
9
+ Properties
10
+ <%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
11
+ data: { bs_toggle: "collapse", bs_target: ".cron-entry-properties" },
12
+ aria: { expanded: false, controls: @cron_entries.map { |cron_entry| "##{dom_id(cron_entry, 'properties')}" }.join(" ") }
13
+ %>
14
+ </th>
15
+ <th>Description</th>
16
+ <th>Next scheduled</th>
17
+ <th>Last run</th>
18
+ <th>Actions</th>
19
+ </thead>
20
+ <tbody>
21
+ <% @cron_entries.each do |cron_entry| %>
22
+ <tr id="<%= dom_id(cron_entry) %>">
23
+ <td class="font-monospace"><%= cron_entry.key %></td>
24
+ <td class="font-monospace"><%= cron_entry.schedule %></td>
25
+ <td>
26
+ <%= tag.button("Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
27
+ data: { bs_toggle: "collapse", bs_target: "##{dom_id(cron_entry, 'properties')}" },
28
+ aria: { expanded: false, controls: dom_id(cron_entry, 'properties') }) %>
29
+ <%= tag.pre(JSON.pretty_generate(cron_entry.display_properties), id: dom_id(cron_entry, 'properties'), class: "collapse cron-entry-properties") %>
30
+ </td>
31
+ <td><%= cron_entry.description %></td>
32
+ <td><%= cron_entry.next_at %></td>
33
+ <td>
34
+ <% if cron_entry.last_job.present? %>
35
+ <%= link_to cron_entry.last_at, cron_entry_path(cron_entry), title: "Job #{cron_entry.last_job.id}" %>
36
+ <% end %>
37
+ </td>
38
+ <td>
39
+ <%= button_to enqueue_cron_entry_path(cron_entry.id), method: :post, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Run cron entry now" }, title: "Run cron entry now", data: { confirm: "Confirm run cron entry now" } do %>
40
+ <%= render "good_job/shared/icons/play" %>
41
+ <% end %>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ </tbody>
46
+ </table>
47
+ </div>
48
+ </div>
49
+ <% else %>
50
+ <em>No cron schedules present.</em>
51
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <h1 class="mb-3">Cron Entry Key: <code><%= @cron_entry.id %></code></h1>
2
+
3
+ <%= render 'good_job/shared/filter', filter: @jobs_filter %>
4
+ <%= render 'good_job/jobs/table', jobs: @jobs_filter.records %>
@@ -44,7 +44,7 @@
44
44
  <%= tag.pre JSON.pretty_generate(execution.serialized_params), id: dom_id(execution, "params"), class: "collapse job-params" %>
45
45
  </td>
46
46
  <td>
47
- <%= button_to execution_path(execution.id), method: :delete, class: "btn btn-sm btn-outline-danger", title: "Delete execution" do %>
47
+ <%= button_to execution_path(execution.id), method: :delete, class: "btn btn-sm btn-outline-danger", title: "Delete execution", data: { confirm: "Confirm delete" } do %>
48
48
  <%= render "good_job/shared/icons/trash" %>
49
49
  <% end %>
50
50
  </td>
@@ -5,7 +5,7 @@
5
5
  <%= render 'good_job/shared/filter', filter: @filter %>
6
6
 
7
7
  <% if @filter.records.present? %>
8
- <%= render 'good_job/shared/executions_table', executions: @filter.records %>
8
+ <%= render 'good_job/executions/table', executions: @filter.records %>
9
9
 
10
10
  <nav aria-label="Job pagination" class="mt-3">
11
11
  <ul class="pagination">
@@ -46,16 +46,16 @@
46
46
  <td>
47
47
  <div class="text-nowrap">
48
48
  <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
49
- <%= button_to reschedule_job_path(job.id), method: :put, class: "btn btn-sm #{job_reschedulable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_reschedulable, aria: { label: "Reschedule job" }, title: "Reschedule job" do %>
49
+ <%= button_to reschedule_job_path(job.id), method: :put, class: "btn btn-sm #{job_reschedulable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_reschedulable, aria: { label: "Reschedule job" }, title: "Reschedule job", data: { confirm: "Confirm reschedule" } do %>
50
50
  <%= render "good_job/shared/icons/skip_forward" %>
51
51
  <% end %>
52
52
 
53
53
  <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
54
- <%= button_to discard_job_path(job.id), method: :put, class: "btn btn-sm #{job_discardable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_discardable, aria: { label: "Discard job" }, title: "Discard job" do %>
54
+ <%= button_to discard_job_path(job.id), method: :put, class: "btn btn-sm #{job_discardable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_discardable, aria: { label: "Discard job" }, title: "Discard job", data: { confirm: "Confirm discard" } do %>
55
55
  <%= render "good_job/shared/icons/stop" %>
56
56
  <% end %>
57
57
 
58
- <%= button_to retry_job_path(job.id), method: :put, class: "btn btn-sm #{job.status == :discarded ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: job.status != :discarded, aria: { label: "Retry job" }, title: "Retry job" do %>
58
+ <%= button_to retry_job_path(job.id), method: :put, class: "btn btn-sm #{job.status == :discarded ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: job.status != :discarded, aria: { label: "Retry job" }, title: "Retry job", data: { confirm: "Confirm retry" } do %>
59
59
  <%= render "good_job/shared/icons/arrow_clockwise" %>
60
60
  <% end %>
61
61
  </div>
@@ -5,7 +5,7 @@
5
5
  <%= render 'good_job/shared/filter', filter: @filter %>
6
6
 
7
7
  <% if @filter.records.present? %>
8
- <%= render 'good_job/shared/jobs_table', jobs: @filter.records %>
8
+ <%= render 'good_job/jobs/table', jobs: @filter.records %>
9
9
  <nav aria-label="Job pagination" class="mt-3">
10
10
  <ul class="pagination">
11
11
  <li class="page-item">
@@ -1,3 +1,3 @@
1
- <h1>ActiveJob ID: <code><%= @executions.first.id %></code></h1>
1
+ <h1 class="mb-3">ActiveJob ID: <code><%= @executions.first.id %></code></h1>
2
2
 
3
- <%= render 'good_job/shared/executions_table', executions: @executions %>
3
+ <%= render 'good_job/executions/table', executions: @executions %>
@@ -1,16 +1,15 @@
1
1
  <div class='card mb-2'>
2
2
  <div class='card-body d-flex flex-wrap'>
3
-
4
3
  <div class='me-4'>
5
4
  <small>Filter by job class</small>
6
5
  <br>
7
- <% @filter.job_classes.each do |name, count| %>
6
+ <% filter.job_classes.each do |name, count| %>
8
7
  <% if params[:job_class] == name %>
9
- <%= link_to(@filter.to_params(job_class: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
8
+ <%= link_to(filter.to_params(job_class: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
10
9
  <%= name %> (<%= count %>)
11
10
  <% end %>
12
11
  <% else %>
13
- <%= link_to(@filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
12
+ <%= link_to(filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
14
13
  <%= name %> (<%= count %>)
15
14
  <% end %>
16
15
  <% end %>
@@ -20,13 +19,13 @@
20
19
  <div class='me-4'>
21
20
  <small>Filter by state</small>
22
21
  <br>
23
- <% @filter.states.each do |name, count| %>
22
+ <% filter.states.each do |name, count| %>
24
23
  <% if params[:state] == name %>
25
- <%= link_to(@filter.to_params(state: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
24
+ <%= link_to(filter.to_params(state: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
26
25
  <%= name %> (<%= count %>)
27
26
  <% end %>
28
27
  <% else %>
29
- <%= link_to(@filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
28
+ <%= link_to(filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
30
29
  <%= name %> (<%= count %>)
31
30
  <% end %>
32
31
  <% end %>
@@ -36,13 +35,13 @@
36
35
  <div>
37
36
  <small>Filter by queue</small>
38
37
  <br>
39
- <% @filter.queues.each do |name, count| %>
38
+ <% filter.queues.each do |name, count| %>
40
39
  <% if params[:queue_name] == name %>
41
- <%= link_to(@filter.to_params(queue_name: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
40
+ <%= link_to(filter.to_params(queue_name: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
42
41
  <%= name %> (<%= count %>)
43
42
  <% end %>
44
43
  <% else %>
45
- <%= link_to(@filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
44
+ <%= link_to(filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
46
45
  <%= name %> (<%= count %>)
47
46
  <% end %>
48
47
  <% end %>
@@ -0,0 +1,4 @@
1
+ <!-- https://icons.getbootstrap.com/icons/play/ -->
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play" viewBox="0 0 16 16">
3
+ <path d="M10.804 8 5 4.633v6.734L10.804 8zm.792-.696a.802.802 0 0 1 0 1.392l-6.363 3.692C4.713 12.69 4 12.345 4 11.692V4.308c0-.653.713-.998 1.233-.696l6.363 3.692z" />
4
+ </svg>
@@ -11,6 +11,7 @@
11
11
 
12
12
  <%= javascript_include_tag bootstrap_path(format: :js, v: GoodJob::VERSION) %>
13
13
  <%= javascript_include_tag chartist_path(format: :js, v: GoodJob::VERSION) %>
14
+ <%= javascript_include_tag rails_ujs_path(format: :js, v: GoodJob::VERSION) %>
14
15
  </head>
15
16
  <body>
16
17
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
@@ -29,7 +30,7 @@
29
30
  <%= link_to "All Jobs", jobs_path, class: ["nav-link", ("active" if current_page?(jobs_path))] %>
30
31
  </li>
31
32
  <li class="nav-item">
32
- <%= link_to "Cron Schedules", cron_schedules_path, class: ["nav-link", ("active" if current_page?(cron_schedules_path))] %>
33
+ <%= link_to "Cron Schedules", cron_entries_path, class: ["nav-link", ("active" if current_page?(cron_entries_path))] %>
33
34
  </li>
34
35
  <li class="nav-item">
35
36
  <div class="nav-link">
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  GoodJob::Engine.routes.draw do
3
3
  root to: 'executions#index'
4
- resources :cron_schedules, only: %i[index]
4
+
5
+ resources :cron_entries, only: %i[index show] do
6
+ member do
7
+ post :enqueue
8
+ end
9
+ end
10
+
5
11
  resources :jobs, only: %i[index show] do
6
12
  member do
7
13
  put :discard
@@ -20,6 +26,7 @@ GoodJob::Engine.routes.draw do
20
26
 
21
27
  constraints(format: :js) do
22
28
  get :bootstrap, action: :bootstrap_js
29
+ get :rails_ujs, action: :rails_ujs_js
23
30
  get :chartist, action: :chartist_js
24
31
  end
25
32
  end
@@ -157,7 +157,7 @@ module GoodJob
157
157
  alias enable_cron? enable_cron
158
158
 
159
159
  def cron
160
- env_cron = JSON.parse(ENV['GOOD_JOB_CRON']) if ENV['GOOD_JOB_CRON'].present?
160
+ env_cron = JSON.parse(ENV['GOOD_JOB_CRON'], symbolize_names: true) if ENV['GOOD_JOB_CRON'].present?
161
161
 
162
162
  options[:cron] ||
163
163
  rails_config[:cron] ||
@@ -12,14 +12,29 @@ module GoodJob # :nodoc:
12
12
 
13
13
  attr_reader :params
14
14
 
15
+ def self.all(configuration: nil)
16
+ configuration ||= GoodJob::Configuration.new({})
17
+ configuration.cron_entries
18
+ end
19
+
20
+ def self.find(key, configuration: nil)
21
+ all(configuration: configuration).find { |entry| entry.key == key.to_sym }.tap do |cron_entry|
22
+ raise ActiveRecord::RecordNotFound unless cron_entry
23
+ end
24
+ end
25
+
15
26
  def initialize(params = {})
16
- @params = params.with_indifferent_access
27
+ @params = params
28
+
29
+ raise ArgumentError, "Invalid cron format: '#{cron}'" unless fugit.instance_of?(Fugit::Cron)
17
30
  end
18
31
 
19
32
  def key
20
33
  params.fetch(:key)
21
34
  end
35
+
22
36
  alias id key
37
+ alias to_param key
23
38
 
24
39
  def job_class
25
40
  params.fetch(:class)
@@ -42,16 +57,61 @@ module GoodJob # :nodoc:
42
57
  end
43
58
 
44
59
  def next_at
45
- fugit = Fugit::Cron.parse(cron)
46
60
  fugit.next_time.to_t
47
61
  end
48
62
 
49
- def enqueue
50
- job_class.constantize.set(set_value).perform_later(*args_value)
63
+ def schedule
64
+ fugit.original
65
+ end
66
+
67
+ def fugit
68
+ @_fugit ||= Fugit.parse(cron)
69
+ end
70
+
71
+ def jobs
72
+ GoodJob::ActiveJobJob.where(cron_key: key)
73
+ end
74
+
75
+ def last_at
76
+ return if last_job.blank?
77
+
78
+ if GoodJob::ActiveJobJob.column_names.include?('cron_at')
79
+ (last_job.cron_at || last_job.created_at).localtime
80
+ else
81
+ last_job.created_at
82
+ end
83
+ end
84
+
85
+ def enqueue(cron_at = nil)
86
+ GoodJob::CurrentThread.within do |current_thread|
87
+ current_thread.cron_key = key
88
+ current_thread.cron_at = cron_at
89
+
90
+ job_class.constantize.set(set_value).perform_later(*args_value)
91
+ end
51
92
  rescue ActiveRecord::RecordNotUnique
52
93
  false
53
94
  end
54
95
 
96
+ def last_job
97
+ if GoodJob::ActiveJobJob.column_names.include?('cron_at')
98
+ jobs.order("cron_at DESC NULLS LAST").first
99
+ else
100
+ jobs.order(created_at: :asc).last
101
+ end
102
+ end
103
+
104
+ def display_properties
105
+ {
106
+ key: key,
107
+ class: job_class,
108
+ cron: schedule,
109
+ set: display_property(set),
110
+ args: display_property(args),
111
+ description: display_property(description),
112
+ }
113
+ end
114
+
55
115
  private
56
116
 
57
117
  def set_value
@@ -63,5 +123,16 @@ module GoodJob # :nodoc:
63
123
  value = args || []
64
124
  value.respond_to?(:call) ? value.call : value
65
125
  end
126
+
127
+ def display_property(value)
128
+ case value
129
+ when NilClass
130
+ "None"
131
+ when Proc
132
+ "Lambda/Callable"
133
+ else
134
+ value
135
+ end
136
+ end
66
137
  end
67
138
  end
@@ -89,11 +89,7 @@ module GoodJob # :nodoc:
89
89
  thr_scheduler.create_task(thr_cron_entry)
90
90
 
91
91
  Rails.application.executor.wrap do
92
- CurrentThread.reset
93
- CurrentThread.cron_key = thr_cron_entry.key
94
- CurrentThread.cron_at = thr_cron_at
95
-
96
- cron_entry.enqueue
92
+ cron_entry.enqueue(thr_cron_at)
97
93
  end
98
94
  end
99
95
 
@@ -5,6 +5,15 @@ module GoodJob
5
5
  # Thread-local attributes for passing values from Instrumentation.
6
6
  # (Cannot use ActiveSupport::CurrentAttributes because ActiveJob resets it)
7
7
  module CurrentThread
8
+ # Resettable accessors for thread-local values.
9
+ ACCESSORS = %i[
10
+ cron_at
11
+ cron_key
12
+ error_on_discard
13
+ error_on_retry
14
+ execution
15
+ ].freeze
16
+
8
17
  # @!attribute [rw] cron_at
9
18
  # @!scope class
10
19
  # Cron At
@@ -36,13 +45,20 @@ module GoodJob
36
45
  thread_mattr_accessor :execution
37
46
 
38
47
  # Resets attributes
48
+ # @param [Hash] values to assign
39
49
  # @return [void]
40
- def self.reset
41
- self.cron_at = nil
42
- self.cron_key = nil
43
- self.execution = nil
44
- self.error_on_discard = nil
45
- self.error_on_retry = nil
50
+ def self.reset(values = {})
51
+ ACCESSORS.each do |accessor|
52
+ send("#{accessor}=", values[accessor])
53
+ end
54
+ end
55
+
56
+ # Exports values to hash
57
+ # @return [Hash]
58
+ def self.to_h
59
+ ACCESSORS.each_with_object({}) do |accessor, hash|
60
+ hash[accessor] = send(accessor)
61
+ end
46
62
  end
47
63
 
48
64
  # @return [String] UUID of the currently executing GoodJob::Execution
@@ -60,12 +76,14 @@ module GoodJob
60
76
  (Thread.current.name || Thread.current.object_id).to_s
61
77
  end
62
78
 
79
+ # Wrap the yielded block with CurrentThread values and reset after the block
80
+ # @yield [self]
63
81
  # @return [void]
64
82
  def self.within
65
- reset
83
+ original_values = to_h
66
84
  yield(self)
67
85
  ensure
68
- reset
86
+ reset(original_values)
69
87
  end
70
88
  end
71
89
  end
@@ -309,22 +309,24 @@ module GoodJob
309
309
 
310
310
  # @return [ExecutionResult]
311
311
  def execute
312
- GoodJob::CurrentThread.reset
313
- GoodJob::CurrentThread.execution = self
312
+ GoodJob::CurrentThread.within do |current_thread|
313
+ current_thread.reset
314
+ current_thread.execution = self
314
315
 
315
- # DEPRECATION: Remove deprecated `good_job:` parameter in GoodJob v3
316
- ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, execution: self, process_id: GoodJob::CurrentThread.process_id, thread_name: GoodJob::CurrentThread.thread_name }) do
317
- value = ActiveJob::Base.execute(active_job_data)
316
+ # DEPRECATION: Remove deprecated `good_job:` parameter in GoodJob v3
317
+ ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
318
+ value = ActiveJob::Base.execute(active_job_data)
318
319
 
319
- if value.is_a?(Exception)
320
- handled_error = value
321
- value = nil
322
- end
323
- handled_error ||= GoodJob::CurrentThread.error_on_retry || GoodJob::CurrentThread.error_on_discard
320
+ if value.is_a?(Exception)
321
+ handled_error = value
322
+ value = nil
323
+ end
324
+ handled_error ||= current_thread.error_on_retry || current_thread.error_on_discard
324
325
 
325
- ExecutionResult.new(value: value, handled_error: handled_error)
326
- rescue StandardError => e
327
- ExecutionResult.new(value: nil, unhandled_error: e)
326
+ ExecutionResult.new(value: value, handled_error: handled_error)
327
+ rescue StandardError => e
328
+ ExecutionResult.new(value: nil, unhandled_error: e)
329
+ end
328
330
  end
329
331
  end
330
332
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '2.5.0'
4
+ VERSION = '2.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: good_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-25 00:00:00.000000000 Z
11
+ date: 2021-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -126,16 +126,16 @@ dependencies:
126
126
  name: capybara
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: 3.35.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: 3.35.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: database_cleaner
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -351,27 +351,29 @@ files:
351
351
  - engine/app/assets/vendor/bootstrap/bootstrap.min.css
352
352
  - engine/app/assets/vendor/chartist/chartist.css
353
353
  - engine/app/assets/vendor/chartist/chartist.js
354
+ - engine/app/assets/vendor/rails_ujs.js
354
355
  - engine/app/controllers/good_job/assets_controller.rb
355
356
  - engine/app/controllers/good_job/base_controller.rb
356
- - engine/app/controllers/good_job/cron_schedules_controller.rb
357
+ - engine/app/controllers/good_job/cron_entries_controller.rb
357
358
  - engine/app/controllers/good_job/executions_controller.rb
358
359
  - engine/app/controllers/good_job/jobs_controller.rb
359
360
  - engine/app/filters/good_job/base_filter.rb
360
361
  - engine/app/filters/good_job/executions_filter.rb
361
362
  - engine/app/filters/good_job/jobs_filter.rb
362
363
  - engine/app/helpers/good_job/application_helper.rb
363
- - engine/app/models/good_job/active_job_job.rb
364
- - engine/app/views/good_job/cron_schedules/index.html.erb
364
+ - engine/app/views/good_job/cron_entries/index.html.erb
365
+ - engine/app/views/good_job/cron_entries/show.html.erb
366
+ - engine/app/views/good_job/executions/_table.erb
365
367
  - engine/app/views/good_job/executions/index.html.erb
368
+ - engine/app/views/good_job/jobs/_table.erb
366
369
  - engine/app/views/good_job/jobs/index.html.erb
367
370
  - engine/app/views/good_job/jobs/show.html.erb
368
371
  - engine/app/views/good_job/shared/_chart.erb
369
- - engine/app/views/good_job/shared/_executions_table.erb
370
372
  - engine/app/views/good_job/shared/_filter.erb
371
- - engine/app/views/good_job/shared/_jobs_table.erb
372
373
  - engine/app/views/good_job/shared/icons/_arrow_clockwise.html.erb
373
374
  - engine/app/views/good_job/shared/icons/_check.html.erb
374
375
  - engine/app/views/good_job/shared/icons/_exclamation.html.erb
376
+ - engine/app/views/good_job/shared/icons/_play.html.erb
375
377
  - engine/app/views/good_job/shared/icons/_skip_forward.html.erb
376
378
  - engine/app/views/good_job/shared/icons/_stop.html.erb
377
379
  - engine/app/views/good_job/shared/icons/_trash.html.erb
@@ -389,6 +391,7 @@ files:
389
391
  - lib/good_job.rb
390
392
  - lib/good_job/active_job_extensions.rb
391
393
  - lib/good_job/active_job_extensions/concurrency.rb
394
+ - lib/good_job/active_job_job.rb
392
395
  - lib/good_job/adapter.rb
393
396
  - lib/good_job/cli.rb
394
397
  - lib/good_job/configuration.rb
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
- module GoodJob
3
- class CronSchedulesController < GoodJob::BaseController
4
- def index
5
- configuration = GoodJob::Configuration.new({})
6
- @cron_entries = configuration.cron_entries
7
- end
8
- end
9
- end