flight_control 2.0.0.beta.1
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 +7 -0
- data/CHANGELOG.md +12 -0
- data/MIT-LICENSE +20 -0
- data/README.md +265 -0
- data/Rakefile +6 -0
- data/lib/active_job/errors/invalid_operation.rb +5 -0
- data/lib/active_job/errors/job_not_found_error.rb +14 -0
- data/lib/active_job/errors/query_error.rb +5 -0
- data/lib/active_job/executing.rb +41 -0
- data/lib/active_job/execution_error.rb +8 -0
- data/lib/active_job/failed.rb +7 -0
- data/lib/active_job/job_proxy.rb +39 -0
- data/lib/active_job/jobs_relation.rb +321 -0
- data/lib/active_job/querying.rb +45 -0
- data/lib/active_job/queue.rb +63 -0
- data/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb +53 -0
- data/lib/active_job/queue_adapters/solid_queue_ext/workers.rb +42 -0
- data/lib/active_job/queue_adapters/solid_queue_ext.rb +309 -0
- data/lib/active_job/queues.rb +34 -0
- data/lib/flight_control/adapter.rb +155 -0
- data/lib/flight_control/application.rb +20 -0
- data/lib/flight_control/applications.rb +8 -0
- data/lib/flight_control/arguments_filter.rb +25 -0
- data/lib/flight_control/authentication.rb +68 -0
- data/lib/flight_control/console/connect_to.rb +15 -0
- data/lib/flight_control/console/context.rb +11 -0
- data/lib/flight_control/console/jobs_help.rb +23 -0
- data/lib/flight_control/engine.rb +102 -0
- data/lib/flight_control/errors/incompatible_adapter.rb +2 -0
- data/lib/flight_control/errors/resource_not_found.rb +2 -0
- data/lib/flight_control/errors/unsupported_adapter.rb +2 -0
- data/lib/flight_control/i18n_config.rb +17 -0
- data/lib/flight_control/identified_by_name.rb +18 -0
- data/lib/flight_control/identified_elements.rb +24 -0
- data/lib/flight_control/server/recurring_tasks.rb +15 -0
- data/lib/flight_control/server/serializable.rb +24 -0
- data/lib/flight_control/server/workers.rb +13 -0
- data/lib/flight_control/server.rb +33 -0
- data/lib/flight_control/tasks.rb +6 -0
- data/lib/flight_control/version.rb +3 -0
- data/lib/flight_control/workers_relation.rb +79 -0
- data/lib/flight_control.rb +39 -0
- metadata +377 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1ad093eeb61f357dc4aead0c094eb413607dfa234cd7cdf4ed15579a0fa0af51
|
|
4
|
+
data.tar.gz: a7774ba9273438d984569b4f739795019caaea77d1f1e42b033cd862e0af9231
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9ce93746fa317b44831c7fa4d12bca2590d25a76f4eeb375041df08895f326d1e8c25a414d10da06638b0c072c933c84bdbbe338bbf27a04dd77d0e93e8c9324
|
|
7
|
+
data.tar.gz: 986514c76126354436fe67b584289a17cf864314f126c9f7c159f1207e48c7dd3816860b82fde3115cc04ecde18e7e483528ae3b93a7d3f8127c2264f89053c5
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [2.0.0] - 2026-07-20
|
|
6
|
+
|
|
7
|
+
- Drops support for Resque and Async adapters to focus on Solid Queue.
|
|
8
|
+
- Drops support for Rails versions below 8.1.
|
|
9
|
+
- Lists newest jobs first on all pages.
|
|
10
|
+
- Adds a way to run any Active Job and set parameters for it.
|
|
11
|
+
- Shows job run duration in tables with failed and finished jobs.
|
|
12
|
+
- Shows Enqueued and Finished as timestamps in addition to relative time.
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 37signals, LLC
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Flight Control
|
|
2
|
+
|
|
3
|
+
A Rails-based frontend for managing [Solid Queue](https://github.com/rails/solid_queue) jobs through Active Job. It lets you inspect job queues and jobs in every status, retry or discard failed jobs, manage recurring tasks and workers, and enqueue any job defined in your application straight from the UI.
|
|
4
|
+
|
|
5
|
+
Flight Control is a fork of [Mission Control — Jobs](https://github.com/rails/mission_control-jobs) that focuses exclusively on Solid Queue. Resque support has been removed.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
Add this line to your application's Gemfile:
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
gem "flight_control"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
And then execute:
|
|
15
|
+
```bash
|
|
16
|
+
$ bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Flight Control requires Solid Queue (>= 1.0) configured as your Active Job queue adapter.
|
|
20
|
+
|
|
21
|
+
## Basic configuration
|
|
22
|
+
|
|
23
|
+
Mount the Flight Control engine where you wish to have it accessible from your app, in your `routes.rb` file:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
Rails.application.routes.draw do
|
|
27
|
+
# ...
|
|
28
|
+
mount FlightControl::Engine, at: "/jobs"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Once you set up [Authentication](#authentication), you should be able to access Flight Control's UI, where you can browse the existing queues, jobs pending in these queues, jobs in different statuses, and discard and retry failed jobs:
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
### API-only apps or apps using `vite_rails` and other asset pipelines outside Rails
|
|
38
|
+
|
|
39
|
+
If you want to use this gem with an [API-only Rails app](https://guides.rubyonrails.org/api_app.html) or an app that's using `vite_ruby`/`vite_rails`, or some other custom asset pipeline different from Sprockets and Propshaft, you need one more thing: configure an asset pipeline so you can serve the JavaScript and CSS included in this gem. We recommend to use [`Propshaft`](https://github.com/rails/propshaft). You simply need to add this line to your application's Gemfile:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
gem "propshaft"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then execute
|
|
46
|
+
```bash
|
|
47
|
+
$ bundle install
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then, make sure you add a step to your deployment pipeline to precompile assets:
|
|
51
|
+
```
|
|
52
|
+
RAILS_ENV=production rails assets:precompile
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For example, if you're using the Dockerfile generated by Rails with an API-only app or having skipped the assets pipeline, re-add:
|
|
56
|
+
```
|
|
57
|
+
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
|
|
58
|
+
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Authentication
|
|
62
|
+
|
|
63
|
+
Flight Control comes with **HTTP basic authentication enabled and closed** by default. Credentials are stored in [Rails's credentials](https://edgeguides.rubyonrails.org/security.html#custom-credentials) like this:
|
|
64
|
+
```yml
|
|
65
|
+
flight_control:
|
|
66
|
+
http_basic_auth_user: dev
|
|
67
|
+
http_basic_auth_password: secret
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If no credentials are configured, Flight Control won't be accessible. To set these up, you can run the generator provided like this:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
bin/rails flight_control:authentication:configure
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
To set them up for different environments you can use the `RAILS_ENV` environment variable, like this:
|
|
77
|
+
```
|
|
78
|
+
RAILS_ENV=production bin/rails flight_control:authentication:configure
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
User and password can also be configured by hand like this:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
Rails.application.configure do
|
|
85
|
+
FlightControl.http_basic_auth_user = "dev"
|
|
86
|
+
FlightControl.http_basic_auth_password = "secret"
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Custom authentication
|
|
91
|
+
|
|
92
|
+
You can provide your own authentication mechanism, for example, if you have a certain type of admin user in your app that can access Flight Control. To make this easier, you can specify a different controller as the base class for Flight Control's controllers. By default, Flight Control's controllers will extend the host app's `ApplicationController`, but you can change this easily:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
Rails.application.configure do
|
|
96
|
+
FlightControl.base_controller_class = "AdminController"
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or, in your environment config or `application.rb`:
|
|
101
|
+
```ruby
|
|
102
|
+
config.flight_control.base_controller_class = "AdminController"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If you do this, you can disable the default HTTP Basic Authentication using the following option:
|
|
106
|
+
```ruby
|
|
107
|
+
config.flight_control.http_basic_auth_enabled = false
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Other configuration settings
|
|
111
|
+
|
|
112
|
+
Besides `base_controller_class`, you can also set the following for `FlightControl` or `config.flight_control`:
|
|
113
|
+
|
|
114
|
+
- `logger`: the logger you want Flight Control to use. Defaults to `ActiveSupport::Logger.new(nil)` (no logging). Notice that this is different from Active Job's logger or Active Job's backend's configured logger.
|
|
115
|
+
- `delay_between_bulk_operation_batches`: how long to wait between batches when performing bulk operations, such as _discard all_ or _retry all_ jobs—defaults to `0`
|
|
116
|
+
- `internal_query_count_limit`: in count queries, the maximum number of records that will be counted if the adapter needs to limit these queries. True counts above this number will be returned as `INFINITY`. This keeps count queries fast—defaults to `500,000`
|
|
117
|
+
- `scheduled_job_delay_threshold`: the time duration before a scheduled job is considered delayed. Defaults to `1.minute` (a job is considered delayed if it hasn't transitioned from the `scheduled` status 1 minute after the scheduled time).
|
|
118
|
+
- `show_console_help`: whether to show the console help. If you don't want the console help message, set this to `false`—defaults to `true`.
|
|
119
|
+
- `backtrace_cleaner`: a backtrace cleaner used for optionally filtering backtraces on the Failed Jobs detail page. Defaults to `Rails::BacktraceCleaner.new`. See the [Advanced configuration](#advanced-configuration) section for how to configure/override this setting on a per application/server basis.
|
|
120
|
+
- `filter_arguments`: an array of strings representing the job argument keys you want to filter out in the UI. This is useful for hiding sensitive user data. Currently, only root-level hash keys are supported.
|
|
121
|
+
|
|
122
|
+
This library extends Active Job with a querying interface and the following setting:
|
|
123
|
+
- `config.active_job.default_page_size`: the internal batch size that Active Job will use when sending queries to the underlying adapter and the batch size for the bulk operations defined above—defaults to `1000`.
|
|
124
|
+
|
|
125
|
+
## Advanced configuration
|
|
126
|
+
|
|
127
|
+
Without adding any additional configuration to [the one described before](#basic-configuration), Flight Control will be configured with one single app and a single Solid Queue server.
|
|
128
|
+
|
|
129
|
+
If you manage multiple apps' job backends from a single, centralized app, you can configure the different apps and/or different servers in an initializer like this:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
FlightControl.applications.add("hey", solid_queue: ActiveJob::QueueAdapters::SolidQueueAdapter.new)
|
|
133
|
+
FlightControl.applications.add("campfire", solid_queue: ActiveJob::QueueAdapters::SolidQueueAdapter.new)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
When you have multiple apps and servers configured, you can choose between them with select and toggle menus:
|
|
137
|
+
|
|
138
|
+

|
|
139
|
+
|
|
140
|
+
## Basic UI usage
|
|
141
|
+
|
|
142
|
+
Besides inspecting the queues and the jobs in them, and discarding and retrying failed jobs, you can inspect jobs in different statuses, filter them by _queue name_ and _job class name_, pause and un-pause queues, inspect workers, know which jobs are being run by what worker, check a specific job or a specific worker, and manage recurring tasks.
|
|
143
|
+
|
|
144
|
+
Job lists are sorted newest first: the most recently enqueued (or finished) jobs appear at the top. Scheduled jobs are the exception; they're listed in the order they will run.
|
|
145
|
+
|
|
146
|
+
### Running jobs from the UI
|
|
147
|
+
|
|
148
|
+
The **Run job** tab lets you enqueue any job class defined in your application. Pick the job class, provide its arguments as a JSON array, and optionally override the queue. A trailing JSON object is passed to the job as keyword arguments; for example, for a job defined as `def perform(post_id, notify: false)` you'd enter:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
[ 123, { "notify": true } ]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Arguments must be expressible as JSON, so jobs that take records or other rich objects as arguments can't be launched this way.
|
|
155
|
+
|
|
156
|
+

|
|
157
|
+
|
|
158
|
+

|
|
159
|
+
|
|
160
|
+

|
|
161
|
+
|
|
162
|
+

|
|
163
|
+
|
|
164
|
+

|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## Console helpers, scripting and dealing with big sets of jobs
|
|
168
|
+
|
|
169
|
+
Besides the UI, Flight Control provides a light console helper to switch between applications and servers. Some potentially destructive actions aren't exposed via the UI (for example, discarding jobs that aren't failed, although this might change in the future), but you can always perform these from the console if you know very well what you're doing.
|
|
170
|
+
|
|
171
|
+
It's also possible that you need to deal with very big sets of jobs that are unmanageable via the UI or that you wish to write a script to deal with an incident, some cleanup or some data migration. The console helpers and the querying API with which we've extended Active Job come in handy here.
|
|
172
|
+
|
|
173
|
+
First, when connecting to the Rails console, you'll see this new message:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
bin/rails c
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
Type 'jobs_help' to see how to connect to the available job servers to manage jobs
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Typing `jobs_help`, you'll get clear instructions about how to switch between applications and servers:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
>> jobs_help
|
|
186
|
+
You can connect to a job server with
|
|
187
|
+
connect_to "<app_id>:<server_id>"
|
|
188
|
+
|
|
189
|
+
Available job servers:
|
|
190
|
+
* hey:solid_queue
|
|
191
|
+
* campfire:solid_queue
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
And then:
|
|
195
|
+
```
|
|
196
|
+
>> connect_to hey:solid_queue
|
|
197
|
+
Connected to hey:solid_queue
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Now you're ready to query and operate over jobs for this server via the API. Some examples of queries:
|
|
201
|
+
|
|
202
|
+
```ruby
|
|
203
|
+
|
|
204
|
+
# All jobs
|
|
205
|
+
ActiveJob.jobs
|
|
206
|
+
|
|
207
|
+
# All failed jobs
|
|
208
|
+
ActiveJob.jobs.failed
|
|
209
|
+
|
|
210
|
+
# All pending jobs in some queue
|
|
211
|
+
ActiveJob.jobs.pending.where(queue_name: "some_queue")
|
|
212
|
+
|
|
213
|
+
# All failed jobs of a given class
|
|
214
|
+
ActiveJob.jobs.failed.where(job_class_name: "SomeJob")
|
|
215
|
+
|
|
216
|
+
# All pending jobs of a given class with limit and offset
|
|
217
|
+
ActiveJob.jobs.pending.where(job_class_name: "SomeJob").limit(10).offset(5)
|
|
218
|
+
|
|
219
|
+
# All scheduled/in-progress/finished jobs of a given class
|
|
220
|
+
ActiveJob.jobs.scheduled.where(job_class_name: "SomeJob")
|
|
221
|
+
ActiveJob.jobs.in_progress.where(job_class_name: "SomeJob")
|
|
222
|
+
ActiveJob.jobs.finished.where(job_class_name: "SomeJob")
|
|
223
|
+
|
|
224
|
+
# All jobs in progress being run by a given worker
|
|
225
|
+
ActiveJob.jobs.in_progress.where(worker_id: 42)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Some examples of bulk operations:
|
|
229
|
+
|
|
230
|
+
```ruby
|
|
231
|
+
# Retry all the jobs (only possible for failed jobs)
|
|
232
|
+
ActiveJob.jobs.failed.retry_all
|
|
233
|
+
|
|
234
|
+
# Retry all the jobs of a given class (only possible for failed jobs)
|
|
235
|
+
ActiveJob.jobs.failed.where(job_class_name: "SomeJob").retry_all
|
|
236
|
+
|
|
237
|
+
# Discard all failed jobs
|
|
238
|
+
ActiveJob.jobs.failed.discard_all
|
|
239
|
+
|
|
240
|
+
# Discard all pending jobs of a given class
|
|
241
|
+
ActiveJob.jobs.pending.where(job_class_name: "SomeJob").discard_all
|
|
242
|
+
# Or all pending jobs in a given queue:
|
|
243
|
+
ActiveJob.jobs.pending.where(queue_name: "some-queue").discard_all
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
When performing these bulk operations in the console, a delay of 2 seconds between batches processed will be introduced, set via [`delay_between_bulk_operation_batches`](#other-configuration-settings). You can modify it as
|
|
247
|
+
```ruby
|
|
248
|
+
FlightControl.delay_between_bulk_operation_batches = 5.seconds
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Contributing
|
|
252
|
+
|
|
253
|
+
Thanks for your interest in contributing! To get the app running locally, just run:
|
|
254
|
+
```
|
|
255
|
+
bin/setup
|
|
256
|
+
```
|
|
257
|
+
This will load a bunch of jobs as seeds.
|
|
258
|
+
|
|
259
|
+
We have both unit and functional tests and system tests. If you want to run system tests, you'd need to install [ChromeDriver](https://chromedriver.chromium.org/). Then, you'll be able to run the tests as:
|
|
260
|
+
```
|
|
261
|
+
bin/rails test test/system
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). Flight Control is a fork of [Mission Control — Jobs](https://github.com/rails/mission_control-jobs), © 37signals, also MIT-licensed.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module ActiveJob
|
|
2
|
+
module Errors
|
|
3
|
+
class JobNotFoundError < StandardError
|
|
4
|
+
attr_reader :job_relation
|
|
5
|
+
|
|
6
|
+
def initialize(job_or_job_id, job_relation)
|
|
7
|
+
@job_relation = job_relation
|
|
8
|
+
|
|
9
|
+
job_id = job_or_job_id.is_a?(ActiveJob::Base) ? job_or_job_id.job_id : job_or_job_id
|
|
10
|
+
super("Job with id '#{job_id}' not found")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# TODO: These (or a version of them) should be moved to +ActiveJob::Core+
|
|
2
|
+
# and related concerns when upstreamed.
|
|
3
|
+
module ActiveJob::Executing
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
attr_accessor :raw_data, :position, :finished_at, :blocked_by, :blocked_until, :worker_id, :started_at, :status
|
|
8
|
+
attr_reader :serialized_arguments
|
|
9
|
+
|
|
10
|
+
thread_cattr_accessor :current_queue_adapter
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class_methods do
|
|
14
|
+
def queue_adapter
|
|
15
|
+
ActiveJob::Base.current_queue_adapter || super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def retry
|
|
20
|
+
ActiveJob.jobs.failed.retry_job(self)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def discard
|
|
24
|
+
jobs_relation_for_discarding.discard_job(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def dispatch
|
|
28
|
+
ActiveJob.jobs.dispatch_job(self)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def jobs_relation_for_discarding
|
|
34
|
+
case status
|
|
35
|
+
when :failed then ActiveJob.jobs.failed
|
|
36
|
+
when :pending then ActiveJob.jobs.pending.where(queue_name: queue_name)
|
|
37
|
+
else
|
|
38
|
+
ActiveJob.jobs
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Information about a given error when executing a job.
|
|
2
|
+
#
|
|
3
|
+
# It's attached to failed jobs at +ActiveJob::Base#last_execution_error+.
|
|
4
|
+
ActiveJob::ExecutionError = Struct.new(:error_class, :message, :backtrace) do
|
|
5
|
+
def to_s
|
|
6
|
+
"ERROR #{error_class}: #{message}\n#{backtrace&.collect { |line| "\t#{line}" }&.join("\n")}"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# A proxy for managing jobs without having to load the corresponding
|
|
2
|
+
# job class.
|
|
3
|
+
#
|
|
4
|
+
# This is useful for managing jobs without having the job classes
|
|
5
|
+
# present in the code base.
|
|
6
|
+
class ActiveJob::JobProxy < ActiveJob::Base
|
|
7
|
+
class UnsupportedError < StandardError; end
|
|
8
|
+
|
|
9
|
+
attr_reader :job_class_name
|
|
10
|
+
# Raw data with the sensitive user data filtered out.
|
|
11
|
+
attr_accessor :filtered_raw_data
|
|
12
|
+
|
|
13
|
+
def initialize(job_data)
|
|
14
|
+
super
|
|
15
|
+
@job_class_name = job_data["job_class"]
|
|
16
|
+
deserialize(job_data)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def serialize
|
|
20
|
+
super.tap do |json|
|
|
21
|
+
json["job_class"] = @job_class_name
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def perform_now
|
|
26
|
+
raise UnsupportedError, "A JobProxy doesn't support immediate execution, only enqueuing."
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def duration
|
|
30
|
+
ended_at = finished_at || failed_at
|
|
31
|
+
ended_at - scheduled_at if ended_at && scheduled_at
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
ActiveJob::JobsRelation::STATUSES.each do |status|
|
|
35
|
+
define_method "#{status}?" do
|
|
36
|
+
self.status == status
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|