Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
First draft of an active_admin-based view for Delayed::Job
ActiveAdmin::Dashboards.build do
# Add this section in your dashboard...
section "Background Jobs" do
now = Time.now.getgm
ul do
li do
jobs = Delayed::Job.where('failed_at is not null').count(:id)
link_to "#{jobs} failing jobs", admin_jobs_path(q: {failed_at_is_not_null: true}), style: 'color: red'
end
li do
jobs = Delayed::Job.where('run_at <= ?', now).count(:id)
link_to "#{jobs} late jobs", admin_jobs_path(q: {run_at_lte: now.to_s(:db)}), style: 'color: hsl(40, 100%, 40%)'
end
li do
jobs = Delayed::Job.where('run_at >= ?', now).count(:id)
link_to "#{jobs} scheduled jobs", admin_jobs_path(q: {run_at_gte: now.to_s(:db)}), style: 'color: green'
end
end
end
# ...
end
ActiveAdmin.register Delayed::Job, as: 'Job' do
menu parent: 'Admin'
actions :index, :show, :edit, :update, :destroy
index do
column :id
column :queue
column :priority
column :attempts
column :failed_at
column :run_at
column :created_at
column :locked_by
column :locked_at
default_actions
end
form do |f|
f.inputs "Scheduling" do
f.input :priority
f.input :queue
f.input :run_at
end
f.inputs "Details" do
f.input :id, input_html: {disabled: true}
f.input :created_at, input_html: {disabled: true}
f.input :updated_at, input_html: {disabled: true}
f.input :handler, input_html: {disabled: true}
end
f.inputs "Diagnostics" do
f.input :attempts, input_html: {disabled: true}
f.input :failed_at, input_html: {disabled: true}
f.input :last_error, input_html: {disabled: true}
f.input :locked_at, input_html: {disabled: true}
f.input :locked_by, input_html: {disabled: true}
end
f.buttons
end
action_item :only => [:edit] do
link_to 'Delete Job', admin_job_path(resource),
'data-method' => :delete, 'data-confirm' => 'Are you sure?'
end
action_item :only => [:show, :edit] do
link_to 'Schedule now', run_now_admin_job_path(resource), 'data-method' => :post,
:title => 'Cause a job scheduled in the future to run now.'
end
action_item :only => [:show, :edit] do
link_to 'Reset Job', reset_admin_job_path(resource), 'data-method' => :post,
:title => 'Resets the state caused by errors. Lets a worker give it another go ASAP.'
end
member_action :run_now, :method => :post do
resource.update_attributes run_at: Time.now
redirect_to action: :index
end
member_action :reset, :method => :post do
resource.update_attributes locked_at: nil, locked_by: nil, attempts: 0, last_error: nil
resource.update_attribute :attempts, 0
redirect_to action: :index
end
end
@jancel

This comment has been minimized.

Show comment Hide comment
@jancel

jancel Feb 22, 2012

That looks like a pretty awesome piece... I'm assuming (or at least it looks like) it might be similar to resque for redis? Can you re-kick failed tasks? I don't use Delayed::Jobs, so I have no where I can plug in quickly.

jancel commented Feb 22, 2012

That looks like a pretty awesome piece... I'm assuming (or at least it looks like) it might be similar to resque for redis? Can you re-kick failed tasks? I don't use Delayed::Jobs, so I have no where I can plug in quickly.

@webmat

This comment has been minimized.

Show comment Hide comment
@webmat

webmat Feb 23, 2012

@jancel yes, that's what the last part is about (sidebar and member_action).

It assumes that the workers are running properly (it only re-schedules the task to "right now"). But by default, Delayed::Job retries 20 times with exponential re-scheduling. My retry is simplistic in that it doesn't try to address the case where the max amount of retries is already reached.

It would also be possible to force the task to be performed in-request. That would make sense for an admin trying to fix the task and not minding that the email is going to happen in-request, for example.

That would look like job.handler.perform, iirc. But there's potential issues with that. The objects are serialized with YAML and if something fancier than pure Ruby or basic Rails classes are in there, you'd need to require them in the controller. I didn't wanna get into that. I don't need it yet.

And all of that niceness is just ActiveAdmin itself. I have no merit for that :-) I only picked the order in which the fields made most sense to be viewed.

Owner

webmat commented Feb 23, 2012

@jancel yes, that's what the last part is about (sidebar and member_action).

It assumes that the workers are running properly (it only re-schedules the task to "right now"). But by default, Delayed::Job retries 20 times with exponential re-scheduling. My retry is simplistic in that it doesn't try to address the case where the max amount of retries is already reached.

It would also be possible to force the task to be performed in-request. That would make sense for an admin trying to fix the task and not minding that the email is going to happen in-request, for example.

That would look like job.handler.perform, iirc. But there's potential issues with that. The objects are serialized with YAML and if something fancier than pure Ruby or basic Rails classes are in there, you'd need to require them in the controller. I didn't wanna get into that. I don't need it yet.

And all of that niceness is just ActiveAdmin itself. I have no merit for that :-) I only picked the order in which the fields made most sense to be viewed.

@pcreux

This comment has been minimized.

Show comment Hide comment
@pcreux

pcreux Feb 23, 2012

That's great. For the permalink, try out:

ActiveAdmin.register Delayed::Job, :as => "Job" do
  #...
end

pcreux commented Feb 23, 2012

That's great. For the permalink, try out:

ActiveAdmin.register Delayed::Job, :as => "Job" do
  #...
end
@webmat

This comment has been minimized.

Show comment Hide comment
@webmat

webmat Feb 23, 2012

Ah, nice! Thanks for the pointer :-)

Owner

webmat commented Feb 23, 2012

Ah, nice! Thanks for the pointer :-)

@davestephens

This comment has been minimized.

Show comment Hide comment
@davestephens

davestephens Apr 24, 2012

Works great, thanks!

You should package this up as a gem...

Works great, thanks!

You should package this up as a gem...

@webmat

This comment has been minimized.

Show comment Hide comment
@webmat

webmat Apr 24, 2012

Owner

webmat commented Apr 24, 2012

@amolpujari

This comment has been minimized.

Show comment Hide comment
@amolpujari

amolpujari Oct 22, 2012

ActiveAdmin.register_page "Dashboard" do

...

content :title => proc{ I18n.t("active_admin.dashboard") } do
# ...
section "Background Jobs" do ....# section should be covered by content else undefined method `section' for #ActiveAdmin::PageDSL:0x000000076d9d48 (NoMethodError)
# ...
end

...

end

ActiveAdmin.register_page "Dashboard" do

...

content :title => proc{ I18n.t("active_admin.dashboard") } do
# ...
section "Background Jobs" do ....# section should be covered by content else undefined method `section' for #ActiveAdmin::PageDSL:0x000000076d9d48 (NoMethodError)
# ...
end

...

end

@amolpujari

This comment has been minimized.

Show comment Hide comment
@amolpujari

amolpujari Oct 25, 2012

did you define any custom paths? because I am getting below on view

undefined method `run_now_admin_job_path' for #ActiveAdmin::Views::ActionItems:0x00000007fae2e8

did you define any custom paths? because I am getting below on view

undefined method `run_now_admin_job_path' for #ActiveAdmin::Views::ActionItems:0x00000007fae2e8

@alesthome

This comment has been minimized.

Show comment Hide comment
@alesthome

alesthome Feb 12, 2013

Hello. This looks great. I keep getting this message though: "undefined method `per_page_kaminari' for []:ActiveRecord::Relation"
I'm using will_paginate in the app. I added the kaminari.rb initializer in the documentation. All the other pages work fine, but not this one. For some reason the config file seems to be ignored here.
Any ideas?
Thanks!
Alexandre

rails (3.2.11)
activeadmin (0.5.1)
kaminari (>= 0.13.0)

Hello. This looks great. I keep getting this message though: "undefined method `per_page_kaminari' for []:ActiveRecord::Relation"
I'm using will_paginate in the app. I added the kaminari.rb initializer in the documentation. All the other pages work fine, but not this one. For some reason the config file seems to be ignored here.
Any ideas?
Thanks!
Alexandre

rails (3.2.11)
activeadmin (0.5.1)
kaminari (>= 0.13.0)

@kylemacey

This comment has been minimized.

Show comment Hide comment
@kylemacey

kylemacey Apr 17, 2013

+1 @alesthome Same issue here...

+1 @alesthome Same issue here...

@nicholas-johnson

This comment has been minimized.

Show comment Hide comment
@nicholas-johnson

nicholas-johnson May 1, 2013

@alesthome and @kylemacey,

modify your kaminari.rb initialiser like this:

if defined?(WillPaginate)
  module WillPaginate
    module ActiveRecord
      module RelationMethods
        def per(value = nil) per_page(value) end
        def total_count() count end
      end
    end
    module CollectionMethods
      alias_method :num_pages, :total_pages
    end
  end
end

@alesthome and @kylemacey,

modify your kaminari.rb initialiser like this:

if defined?(WillPaginate)
  module WillPaginate
    module ActiveRecord
      module RelationMethods
        def per(value = nil) per_page(value) end
        def total_count() count end
      end
    end
    module CollectionMethods
      alias_method :num_pages, :total_pages
    end
  end
end
@nicholas-johnson

This comment has been minimized.

Show comment Hide comment
@nicholas-johnson

nicholas-johnson May 1, 2013

@amoulpujari, the code assumes you are using the default admin namespace. If you've changed config.default_namespace in your active_admin initialiser, you'll need to change the routes accordingly.

@amoulpujari, the code assumes you are using the default admin namespace. If you've changed config.default_namespace in your active_admin initialiser, you'll need to change the routes accordingly.

@nicholas-johnson

This comment has been minimized.

Show comment Hide comment
@nicholas-johnson

nicholas-johnson May 1, 2013

Really nice, thanks @webmat! You've saved me a big job :)

Really nice, thanks @webmat! You've saved me a big job :)

@crystianwendel

This comment has been minimized.

Show comment Hide comment
@crystianwendel

crystianwendel May 9, 2013

@trivially genius!
Saved my day, thank you!

@trivially genius!
Saved my day, thank you!

@tommoor

This comment has been minimized.

Show comment Hide comment
@tommoor

tommoor May 17, 2013

Strange, this just isn't working in our setup - I get "You are not authorized to perform this action." and it doesn't appear in the menu... struggling to see why!

If I change 'Delayed::Job' to one of our other models it works fine, seems like it might not be able to find the model for some reason.

tommoor commented May 17, 2013

Strange, this just isn't working in our setup - I get "You are not authorized to perform this action." and it doesn't appear in the menu... struggling to see why!

If I change 'Delayed::Job' to one of our other models it works fine, seems like it might not be able to find the model for some reason.

@alexandru-calinoiu

This comment has been minimized.

Show comment Hide comment
@alexandru-calinoiu

alexandru-calinoiu Jun 4, 2013

Very nice, thank you,

I've forked it and added 2 scopes that allow you to easily see the failed and completed jobs

https://gist.github.com/balauru/5706272

Very nice, thank you,

I've forked it and added 2 scopes that allow you to easily see the failed and completed jobs

https://gist.github.com/balauru/5706272

@mrstif

This comment has been minimized.

Show comment Hide comment
@mrstif

mrstif Nov 21, 2013

@webmat
Very helpful gist! Thank you! Saved me a lot of trouble...

mrstif commented Nov 21, 2013

@webmat
Very helpful gist! Thank you! Saved me a lot of trouble...

@pbmolini

This comment has been minimized.

Show comment Hide comment
@pbmolini

pbmolini May 19, 2016

@forwardadvance
thanks a lot it worked! I think it's worth noticing that I had to replace the code suggested in the gem documentation, i.e.

Kaminari.configure do |config|
  config.page_method_name = :per_page_kaminari
end

with the code you suggested.

@forwardadvance
thanks a lot it worked! I think it's worth noticing that I had to replace the code suggested in the gem documentation, i.e.

Kaminari.configure do |config|
  config.page_method_name = :per_page_kaminari
end

with the code you suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment