mission_control-jobs 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -9
  3. data/app/controllers/concerns/mission_control/jobs/adapter_features.rb +10 -6
  4. data/app/controllers/concerns/mission_control/jobs/failed_jobs_bulk_operations.rb +1 -1
  5. data/app/controllers/concerns/mission_control/jobs/not_found_redirections.rb +9 -1
  6. data/app/controllers/concerns/mission_control/jobs/queue_scoped.rb +1 -1
  7. data/app/controllers/mission_control/jobs/bulk_discards_controller.rb +1 -1
  8. data/app/controllers/mission_control/jobs/discards_controller.rb +1 -1
  9. data/app/controllers/mission_control/jobs/dispatches_controller.rb +13 -0
  10. data/app/controllers/mission_control/jobs/jobs_controller.rb +3 -3
  11. data/app/controllers/mission_control/jobs/queues_controller.rb +4 -4
  12. data/app/controllers/mission_control/jobs/recurring_tasks_controller.rb +23 -0
  13. data/app/controllers/mission_control/jobs/retries_controller.rb +1 -1
  14. data/app/controllers/mission_control/jobs/workers_controller.rb +6 -1
  15. data/app/helpers/mission_control/jobs/jobs_helper.rb +6 -2
  16. data/app/helpers/mission_control/jobs/navigation_helper.rb +2 -1
  17. data/app/models/mission_control/jobs/page.rb +8 -8
  18. data/app/models/mission_control/jobs/recurring_task.rb +17 -0
  19. data/app/views/layouts/mission_control/jobs/_application_selection.html.erb +1 -1
  20. data/app/views/mission_control/jobs/jobs/_error_information.html.erb +0 -1
  21. data/app/views/mission_control/jobs/jobs/_general_information.html.erb +1 -1
  22. data/app/views/mission_control/jobs/jobs/_jobs_page.html.erb +8 -10
  23. data/app/views/mission_control/jobs/jobs/_title.html.erb +3 -0
  24. data/app/views/mission_control/jobs/jobs/blocked/_actions.html.erb +3 -0
  25. data/app/views/mission_control/jobs/jobs/blocked/_job.html.erb +3 -0
  26. data/app/views/mission_control/jobs/jobs/index.html.erb +2 -2
  27. data/app/views/mission_control/jobs/jobs/scheduled/_actions.html.erb +4 -0
  28. data/app/views/mission_control/jobs/jobs/scheduled/_job.html.erb +4 -1
  29. data/app/views/mission_control/jobs/queues/_queue_title.html.erb +1 -1
  30. data/app/views/mission_control/jobs/queues/show.html.erb +2 -2
  31. data/app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb +16 -0
  32. data/app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb +14 -0
  33. data/app/views/mission_control/jobs/recurring_tasks/_title.html.erb +7 -0
  34. data/app/views/mission_control/jobs/recurring_tasks/index.html.erb +16 -0
  35. data/app/views/mission_control/jobs/recurring_tasks/show.html.erb +14 -0
  36. data/app/views/mission_control/jobs/{workers → shared}/_job.html.erb +8 -1
  37. data/app/views/mission_control/jobs/shared/_jobs.html.erb +14 -0
  38. data/app/views/mission_control/jobs/shared/_pagination_toolbar.html.erb +3 -3
  39. data/app/views/mission_control/jobs/workers/_workers_page.html.erb +15 -0
  40. data/app/views/mission_control/jobs/workers/index.html.erb +2 -13
  41. data/app/views/mission_control/jobs/workers/show.html.erb +9 -2
  42. data/config/routes.rb +2 -2
  43. data/lib/active_job/executing.rb +3 -6
  44. data/lib/active_job/failed.rb +0 -4
  45. data/lib/active_job/job_proxy.rb +6 -0
  46. data/lib/active_job/jobs_relation.rb +17 -6
  47. data/lib/active_job/queue_adapters/resque_ext.rb +1 -1
  48. data/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb +43 -0
  49. data/lib/active_job/queue_adapters/solid_queue_ext/workers.rb +41 -0
  50. data/lib/active_job/queue_adapters/solid_queue_ext.rb +51 -55
  51. data/lib/mission_control/jobs/adapter.rb +67 -19
  52. data/lib/mission_control/jobs/console/helpers.rb +1 -1
  53. data/lib/mission_control/jobs/engine.rb +13 -3
  54. data/lib/mission_control/jobs/server/recurring_tasks.rb +15 -0
  55. data/lib/mission_control/jobs/server/serializable.rb +1 -1
  56. data/lib/mission_control/jobs/server/workers.rb +3 -5
  57. data/lib/mission_control/jobs/server.rb +1 -1
  58. data/lib/mission_control/jobs/version.rb +1 -1
  59. data/lib/mission_control/jobs/workers_relation.rb +78 -0
  60. data/lib/mission_control/jobs.rb +3 -0
  61. metadata +19 -6
  62. data/app/jobs/mission_control/jobs/application_job.rb +0 -6
  63. data/app/mailers/mission_control/jobs/application_mailer.rb +0 -8
  64. data/app/views/mission_control/jobs/workers/_jobs.html.erb +0 -20
@@ -11,7 +11,7 @@ module MissionControl::Jobs::Console::Helpers
11
11
  puts "You are currently connected to #{MissionControl::Jobs::Current.server}" if MissionControl::Jobs::Current.server
12
12
 
13
13
  puts "You can connect to a job server with"
14
- puts " connect_to <app_id>:<server_id>\n\n"
14
+ puts %( connect_to "<app_id>:<server_id>"\n\n)
15
15
 
16
16
  puts "Available job servers:\n"
17
17
 
@@ -20,8 +20,8 @@ module MissionControl
20
20
  MissionControl::Jobs.public_send("#{key}=", value)
21
21
  end
22
22
 
23
- if config.active_job.queue_adapter.present? && MissionControl::Jobs.adapters.empty?
24
- MissionControl::Jobs.adapters << config.active_job.queue_adapter
23
+ if MissionControl::Jobs.adapters.empty?
24
+ MissionControl::Jobs.adapters << (config.active_job.queue_adapter || :async)
25
25
  end
26
26
  end
27
27
 
@@ -43,6 +43,8 @@ module MissionControl
43
43
  if MissionControl::Jobs.adapters.include?(:solid_queue)
44
44
  ActiveJob::QueueAdapters::SolidQueueAdapter.prepend ActiveJob::QueueAdapters::SolidQueueExt
45
45
  end
46
+
47
+ ActiveJob::QueueAdapters::AsyncAdapter.include MissionControl::Jobs::Adapter
46
48
  end
47
49
 
48
50
  config.after_initialize do |app|
@@ -63,6 +65,7 @@ module MissionControl
63
65
  end
64
66
 
65
67
  console do
68
+ require "irb"
66
69
  require "irb/context"
67
70
 
68
71
  IRB::Context.prepend(MissionControl::Jobs::Console::Context)
@@ -71,7 +74,14 @@ module MissionControl
71
74
  MissionControl::Jobs.delay_between_bulk_operation_batches = 2
72
75
  MissionControl::Jobs.logger = ActiveSupport::Logger.new(STDOUT)
73
76
 
74
- puts "\n\nType 'jobs_help' to see how to connect to the available job servers to manage jobs\n\n"
77
+ if MissionControl::Jobs.applications.one? && (application = MissionControl::Jobs.applications.first) && application.servers.one?
78
+ MissionControl::Jobs::Current.application = application
79
+ MissionControl::Jobs::Current.server = application.servers.first
80
+ end
81
+
82
+ if MissionControl::Jobs.show_console_help
83
+ puts "\n\nType 'jobs_help' to see how to connect to the available job servers to manage jobs\n\n"
84
+ end
75
85
  end
76
86
 
77
87
  initializer "mission_control-jobs.assets" do |app|
@@ -0,0 +1,15 @@
1
+ module MissionControl::Jobs::Server::RecurringTasks
2
+ def recurring_tasks
3
+ queue_adapter.recurring_tasks.collect do |task|
4
+ MissionControl::Jobs::RecurringTask.new(queue_adapter: queue_adapter, **task)
5
+ end.sort_by(&:id)
6
+ end
7
+
8
+ def find_recurring_task(task_id)
9
+ if task = queue_adapter.find_recurring_task(task_id)
10
+ MissionControl::Jobs::RecurringTask.new(queue_adapter: queue_adapter, **task)
11
+ else
12
+ raise MissionControl::Jobs::Errors::ResourceNotFound, "Recurring task with id '#{task_id}' not found"
13
+ end
14
+ end
15
+ end
@@ -18,7 +18,7 @@ module MissionControl::Jobs::Server::Serializable
18
18
  end
19
19
 
20
20
  def to_global_id
21
- suffix = ":#{id}" if application.servers.length > 1
21
+ suffix = ":#{id}" if application.servers.many?
22
22
  "#{application&.id}#{suffix}"
23
23
  end
24
24
  end
@@ -1,15 +1,13 @@
1
1
  module MissionControl::Jobs::Server::Workers
2
- def workers
3
- queue_adapter.workers.collect do |worker|
4
- MissionControl::Jobs::Worker.new(queue_adapter: queue_adapter, **worker)
5
- end
2
+ def workers_relation
3
+ MissionControl::Jobs::WorkersRelation.new(queue_adapter: queue_adapter)
6
4
  end
7
5
 
8
6
  def find_worker(worker_id)
9
7
  if worker = queue_adapter.find_worker(worker_id)
10
8
  MissionControl::Jobs::Worker.new(queue_adapter: queue_adapter, **worker)
11
9
  else
12
- raise MissionControl::Jobs::Errors::ResourceNotFound, "No worker found with ID #{worker_id}"
10
+ raise MissionControl::Jobs::Errors::ResourceNotFound, "Worker with id '#{worker_id}' not found"
13
11
  end
14
12
  end
15
13
  end
@@ -2,7 +2,7 @@ require "active_job/queue_adapter"
2
2
 
3
3
  class MissionControl::Jobs::Server
4
4
  include MissionControl::Jobs::IdentifiedByName
5
- include Serializable, Workers
5
+ include Serializable, RecurringTasks, Workers
6
6
 
7
7
  attr_reader :name, :queue_adapter, :application
8
8
 
@@ -1,5 +1,5 @@
1
1
  module MissionControl
2
2
  module Jobs
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,78 @@
1
+ # A relation of workers.
2
+ #
3
+ # Relations are enumerable, so you can use +Enumerable+ methods on them.
4
+ # Notice however that using these methods will imply loading all the relation
5
+ # in memory, which could introduce performance concerns.
6
+ class MissionControl::Jobs::WorkersRelation
7
+ include Enumerable
8
+
9
+ attr_accessor :offset_value, :limit_value
10
+
11
+ delegate :last, :[], :to_s, :reverse, to: :to_a
12
+
13
+ ALL_WORKERS_LIMIT = 100_000_000 # When no limit value it defaults to "all workers"
14
+
15
+ def initialize(queue_adapter:)
16
+ @queue_adapter = queue_adapter
17
+
18
+ set_defaults
19
+ end
20
+
21
+ def offset(offset)
22
+ clone_with offset_value: offset
23
+ end
24
+
25
+ def limit(limit)
26
+ clone_with limit_value: limit
27
+ end
28
+
29
+ def each(&block)
30
+ workers.each(&block)
31
+ end
32
+
33
+ def reload
34
+ @count = @workers = nil
35
+ self
36
+ end
37
+
38
+ def count
39
+ if loaded?
40
+ to_a.length
41
+ else
42
+ query_count
43
+ end
44
+ end
45
+
46
+ def empty?
47
+ count == 0
48
+ end
49
+
50
+ alias length count
51
+ alias size count
52
+
53
+ private
54
+ def set_defaults
55
+ self.offset_value = 0
56
+ self.limit_value = ALL_WORKERS_LIMIT
57
+ end
58
+
59
+ def workers
60
+ @workers ||= @queue_adapter.fetch_workers(self)
61
+ end
62
+
63
+ def query_count
64
+ @count ||= @queue_adapter.count_workers(self)
65
+ end
66
+
67
+ def loaded?
68
+ !@workers.nil?
69
+ end
70
+
71
+ def clone_with(**properties)
72
+ dup.reload.tap do |relation|
73
+ properties.each do |key, value|
74
+ relation.send("#{key}=", value)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -15,5 +15,8 @@ module MissionControl
15
15
  mattr_accessor :base_controller_class, default: "::ApplicationController"
16
16
  mattr_accessor :delay_between_bulk_operation_batches, default: 0
17
17
  mattr_accessor :logger, default: ActiveSupport::Logger.new(nil)
18
+ mattr_accessor :internal_query_count_limit, default: 500_000 # Hard limit to keep unlimited count queries fast enough
19
+ mattr_accessor :show_console_help, default: true
20
+ mattr_accessor :scheduled_job_delay_threshold, default: 1.minute
18
21
  end
19
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mission_control-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jorge Manrubia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-31 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -245,9 +245,11 @@ files:
245
245
  - app/controllers/mission_control/jobs/bulk_discards_controller.rb
246
246
  - app/controllers/mission_control/jobs/bulk_retries_controller.rb
247
247
  - app/controllers/mission_control/jobs/discards_controller.rb
248
+ - app/controllers/mission_control/jobs/dispatches_controller.rb
248
249
  - app/controllers/mission_control/jobs/jobs_controller.rb
249
250
  - app/controllers/mission_control/jobs/queues/pauses_controller.rb
250
251
  - app/controllers/mission_control/jobs/queues_controller.rb
252
+ - app/controllers/mission_control/jobs/recurring_tasks_controller.rb
251
253
  - app/controllers/mission_control/jobs/retries_controller.rb
252
254
  - app/controllers/mission_control/jobs/workers_controller.rb
253
255
  - app/helpers/mission_control/jobs/application_helper.rb
@@ -261,11 +263,10 @@ files:
261
263
  - app/javascript/mission_control/jobs/controllers/index.js
262
264
  - app/javascript/mission_control/jobs/helpers/debounce_helpers.js
263
265
  - app/javascript/mission_control/jobs/helpers/index.js
264
- - app/jobs/mission_control/jobs/application_job.rb
265
- - app/mailers/mission_control/jobs/application_mailer.rb
266
266
  - app/models/mission_control/jobs/application_record.rb
267
267
  - app/models/mission_control/jobs/current.rb
268
268
  - app/models/mission_control/jobs/page.rb
269
+ - app/models/mission_control/jobs/recurring_task.rb
269
270
  - app/models/mission_control/jobs/worker.rb
270
271
  - app/views/layouts/mission_control/jobs/_application_selection.html.erb
271
272
  - app/views/layouts/mission_control/jobs/_flash.html.erb
@@ -281,12 +282,14 @@ files:
281
282
  - app/views/mission_control/jobs/jobs/_raw_data.html.erb
282
283
  - app/views/mission_control/jobs/jobs/_title.html.erb
283
284
  - app/views/mission_control/jobs/jobs/_toolbar.html.erb
285
+ - app/views/mission_control/jobs/jobs/blocked/_actions.html.erb
284
286
  - app/views/mission_control/jobs/jobs/blocked/_job.html.erb
285
287
  - app/views/mission_control/jobs/jobs/failed/_actions.html.erb
286
288
  - app/views/mission_control/jobs/jobs/failed/_job.html.erb
287
289
  - app/views/mission_control/jobs/jobs/finished/_job.html.erb
288
290
  - app/views/mission_control/jobs/jobs/in_progress/_job.html.erb
289
291
  - app/views/mission_control/jobs/jobs/index.html.erb
292
+ - app/views/mission_control/jobs/jobs/scheduled/_actions.html.erb
290
293
  - app/views/mission_control/jobs/jobs/scheduled/_job.html.erb
291
294
  - app/views/mission_control/jobs/jobs/show.html.erb
292
295
  - app/views/mission_control/jobs/queues/_actions.html.erb
@@ -295,13 +298,19 @@ files:
295
298
  - app/views/mission_control/jobs/queues/_queue_title.html.erb
296
299
  - app/views/mission_control/jobs/queues/index.html.erb
297
300
  - app/views/mission_control/jobs/queues/show.html.erb
301
+ - app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb
302
+ - app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb
303
+ - app/views/mission_control/jobs/recurring_tasks/_title.html.erb
304
+ - app/views/mission_control/jobs/recurring_tasks/index.html.erb
305
+ - app/views/mission_control/jobs/recurring_tasks/show.html.erb
306
+ - app/views/mission_control/jobs/shared/_job.html.erb
307
+ - app/views/mission_control/jobs/shared/_jobs.html.erb
298
308
  - app/views/mission_control/jobs/shared/_pagination_toolbar.html.erb
299
309
  - app/views/mission_control/jobs/workers/_configuration.html.erb
300
- - app/views/mission_control/jobs/workers/_job.html.erb
301
- - app/views/mission_control/jobs/workers/_jobs.html.erb
302
310
  - app/views/mission_control/jobs/workers/_raw_data.html.erb
303
311
  - app/views/mission_control/jobs/workers/_title.html.erb
304
312
  - app/views/mission_control/jobs/workers/_worker.html.erb
313
+ - app/views/mission_control/jobs/workers/_workers_page.html.erb
305
314
  - app/views/mission_control/jobs/workers/index.html.erb
306
315
  - app/views/mission_control/jobs/workers/show.html.erb
307
316
  - config/importmap.rb
@@ -318,6 +327,8 @@ files:
318
327
  - lib/active_job/queue.rb
319
328
  - lib/active_job/queue_adapters/resque_ext.rb
320
329
  - lib/active_job/queue_adapters/solid_queue_ext.rb
330
+ - lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb
331
+ - lib/active_job/queue_adapters/solid_queue_ext/workers.rb
321
332
  - lib/active_job/queues.rb
322
333
  - lib/mission_control/jobs.rb
323
334
  - lib/mission_control/jobs/adapter.rb
@@ -331,9 +342,11 @@ files:
331
342
  - lib/mission_control/jobs/identified_by_name.rb
332
343
  - lib/mission_control/jobs/identified_elements.rb
333
344
  - lib/mission_control/jobs/server.rb
345
+ - lib/mission_control/jobs/server/recurring_tasks.rb
334
346
  - lib/mission_control/jobs/server/serializable.rb
335
347
  - lib/mission_control/jobs/server/workers.rb
336
348
  - lib/mission_control/jobs/version.rb
349
+ - lib/mission_control/jobs/workers_relation.rb
337
350
  - lib/resque/thread_safe_redis.rb
338
351
  - lib/tasks/mission_control/jobs_tasks.rake
339
352
  homepage: https://github.com/basecamp/mission_control-jobs
@@ -1,6 +0,0 @@
1
- module MissionControl
2
- module Jobs
3
- class ApplicationJob < ActiveJob::Base
4
- end
5
- end
6
- end
@@ -1,8 +0,0 @@
1
- module MissionControl
2
- module Jobs
3
- class ApplicationMailer < ActionMailer::Base
4
- default from: "from@example.com"
5
- layout "mailer"
6
- end
7
- end
8
- end
@@ -1,20 +0,0 @@
1
- <% if @worker.jobs.empty? %>
2
- <%= blank_status_notice "This worker is idle" %>
3
- <% else %>
4
- <h2 class="subtitle">Running <%= worker.jobs.size %> jobs</h2>
5
-
6
- <table class="jobs table workers is-hoverable is-fullwidth">
7
- <tbody>
8
- <thead>
9
- <tr>
10
- <th style="width: 30%;">Job</th>
11
- <th></th>
12
- <th style="width: 15%;">Running for</th>
13
- </tr>
14
- </thead>
15
-
16
- <%= render partial: "mission_control/jobs/workers/job", collection: @worker.jobs %>
17
-
18
- </tbody>
19
- </table>
20
- <% end %>