active_job_log 0.1.0

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.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +9 -0
  4. data/.hound.yml +4 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +1038 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +15 -0
  9. data/CHANGELOG.md +7 -0
  10. data/Gemfile +14 -0
  11. data/Gemfile.lock +215 -0
  12. data/Guardfile +15 -0
  13. data/LICENSE.txt +21 -0
  14. data/README.md +143 -0
  15. data/Rakefile +10 -0
  16. data/active_job_log.gemspec +32 -0
  17. data/app/assets/config/active_job_log_manifest.js +2 -0
  18. data/app/assets/images/active_job_log/.keep +0 -0
  19. data/app/assets/javascripts/active_job_log/application.js +13 -0
  20. data/app/assets/stylesheets/active_job_log/application.css +15 -0
  21. data/app/controllers/active_job_log/application_controller.rb +5 -0
  22. data/app/helpers/active_job_log/application_helper.rb +4 -0
  23. data/app/jobs/active_job_log/application_job.rb +4 -0
  24. data/app/mailers/active_job_log/application_mailer.rb +6 -0
  25. data/app/models/active_job_log/application_record.rb +5 -0
  26. data/app/models/active_job_log/job.rb +68 -0
  27. data/app/views/layouts/active_job_log/application.html.erb +14 -0
  28. data/bin/rails +14 -0
  29. data/config/routes.rb +2 -0
  30. data/db/migrate/20180511184635_create_active_job_log_jobs.rb +22 -0
  31. data/lib/active_job_log.rb +26 -0
  32. data/lib/active_job_log/engine.rb +14 -0
  33. data/lib/active_job_log/log_ext.rb +43 -0
  34. data/lib/active_job_log/version.rb +3 -0
  35. data/lib/generators/active_job_log/install/USAGE +5 -0
  36. data/lib/generators/active_job_log/install/install_generator.rb +19 -0
  37. data/lib/generators/active_job_log/install/templates/initializer.rb +2 -0
  38. data/lib/tasks/active_job_log_tasks.rake +4 -0
  39. data/spec/dummy/Rakefile +6 -0
  40. data/spec/dummy/app/assets/config/manifest.js +5 -0
  41. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  42. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  43. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  44. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  45. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  46. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  47. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  48. data/spec/dummy/app/jobs/application_job.rb +2 -0
  49. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  50. data/spec/dummy/app/models/application_record.rb +3 -0
  51. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  52. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  53. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  54. data/spec/dummy/bin/bundle +3 -0
  55. data/spec/dummy/bin/rails +4 -0
  56. data/spec/dummy/bin/rake +4 -0
  57. data/spec/dummy/bin/setup +38 -0
  58. data/spec/dummy/bin/update +29 -0
  59. data/spec/dummy/bin/yarn +11 -0
  60. data/spec/dummy/config.ru +5 -0
  61. data/spec/dummy/config/application.rb +27 -0
  62. data/spec/dummy/config/boot.rb +5 -0
  63. data/spec/dummy/config/cable.yml +10 -0
  64. data/spec/dummy/config/database.yml +25 -0
  65. data/spec/dummy/config/environment.rb +5 -0
  66. data/spec/dummy/config/environments/development.rb +54 -0
  67. data/spec/dummy/config/environments/production.rb +91 -0
  68. data/spec/dummy/config/environments/test.rb +42 -0
  69. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  70. data/spec/dummy/config/initializers/assets.rb +14 -0
  71. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  73. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  74. data/spec/dummy/config/initializers/inflections.rb +16 -0
  75. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/spec/dummy/config/locales/en.yml +33 -0
  78. data/spec/dummy/config/puma.rb +56 -0
  79. data/spec/dummy/config/routes.rb +3 -0
  80. data/spec/dummy/config/secrets.yml +32 -0
  81. data/spec/dummy/config/spring.rb +6 -0
  82. data/spec/dummy/db/schema.rb +33 -0
  83. data/spec/dummy/package.json +5 -0
  84. data/spec/dummy/public/404.html +67 -0
  85. data/spec/dummy/public/422.html +67 -0
  86. data/spec/dummy/public/500.html +66 -0
  87. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  88. data/spec/dummy/public/apple-touch-icon.png +0 -0
  89. data/spec/dummy/public/favicon.ico +0 -0
  90. data/spec/dummy/spec/assets/image.png +0 -0
  91. data/spec/dummy/spec/assets/video.mp4 +0 -0
  92. data/spec/dummy/spec/support/test_helpers.rb +5 -0
  93. data/spec/factories/active_job_log_jobs.rb +7 -0
  94. data/spec/lib/active_job_log/log_ext_spec.rb +84 -0
  95. data/spec/models/active_job_log/job_spec.rb +187 -0
  96. data/spec/rails_helper.rb +48 -0
  97. data/spec/spec_helper.rb +9 -0
  98. metadata +328 -0
@@ -0,0 +1,32 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain your gem"s version:
4
+ require "active_job_log/version"
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = "active_job_log"
9
+ s.version = ActiveJobLog::VERSION
10
+ s.authors = ["Platanus", "Leandro Segovia"]
11
+ s.email = ["rubygems@platan.us", "ldlsegovia@gmail.com"]
12
+ s.homepage = "https://github.com/platanus/active_job_log"
13
+ s.summary = "Rails engine to keep jobs history"
14
+ s.description = "Rails engine to register jobs history, adding: job state, error feedback, duration, etc."
15
+ s.license = "MIT"
16
+
17
+ s.files = `git ls-files`.split($/).reject { |fn| fn.start_with? "spec" }
18
+ s.bindir = "exe"
19
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ s.test_files = Dir["spec/**/*"]
21
+
22
+ s.add_dependency "rails", ">= 4.2.0"
23
+ s.add_dependency "enumerize", ">= 1.0"
24
+
25
+ s.add_development_dependency "pry"
26
+ s.add_development_dependency "pry-rails"
27
+ s.add_development_dependency "sqlite3"
28
+ s.add_development_dependency "rspec-rails"
29
+ s.add_development_dependency "guard-rspec"
30
+ s.add_development_dependency "factory_bot_rails"
31
+ s.add_development_dependency "coveralls"
32
+ end
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/active_job_log .js
2
+ //= link_directory ../stylesheets/active_job_log .css
File without changes
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ module ActiveJobLog
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveJobLog
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActiveJobLog
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module ActiveJobLog
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveJobLog
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ module ActiveJobLog
2
+ class Job < ApplicationRecord
3
+ extend Enumerize
4
+
5
+ STATUSES = %i{queued pending finished failed}
6
+
7
+ validates :job_id, presence: true
8
+
9
+ enumerize :status, in: STATUSES, scope: true
10
+
11
+ serialize :params, Array
12
+ serialize :stack_trace, Array
13
+
14
+ before_save :set_queued_duration
15
+ before_save :set_execution_duration
16
+ before_save :set_total_duration
17
+
18
+ def self.update_job!(job_id, status, params = {})
19
+ params.merge!(status_to_params(status))
20
+ job = Job.find_or_create_by(job_id: job_id)
21
+ job.update_attributes!(params)
22
+ job
23
+ end
24
+
25
+ class << self
26
+ private
27
+
28
+ def status_to_params(status)
29
+ time_attr = infer_duration_attr_from_status(status)
30
+ {
31
+ time_attr => DateTime.current,
32
+ status: status
33
+ }
34
+ end
35
+
36
+ def infer_duration_attr_from_status(status)
37
+ case status
38
+ when :queued
39
+ :queued_at
40
+ when :pending
41
+ :started_at
42
+ when :finished, :failed
43
+ :ended_at
44
+ else
45
+ fail "invalid status"
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def set_queued_duration
53
+ return if queued_at.blank? || started_at.blank?
54
+ self.queued_duration = (started_at.to_f - queued_at.to_f).to_i
55
+ end
56
+
57
+ def set_execution_duration
58
+ return if started_at.blank? || ended_at.blank?
59
+ self.execution_duration = (ended_at.to_f - started_at.to_f).to_i
60
+ end
61
+
62
+ def set_total_duration
63
+ from = queued_at || started_at
64
+ return if from.blank? || ended_at.blank?
65
+ self.total_duration = (ended_at.to_f - from.to_f).to_i
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Active job log</title>
5
+ <%= stylesheet_link_tag "active_job_log/application", media: "all" %>
6
+ <%= javascript_include_tag "active_job_log/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
6
+ ENGINE_PATH = File.expand_path('../../lib/active_job_log/engine', __FILE__)
7
+ APP_PATH = File.expand_path('../../spec/dummy/config/application', __FILE__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require 'rails/all'
14
+ require 'rails/engine/commands'
@@ -0,0 +1,2 @@
1
+ ActiveJobLog::Engine.routes.draw do
2
+ end
@@ -0,0 +1,22 @@
1
+ class CreateActiveJobLogJobs < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :active_job_log_jobs do |t|
4
+ t.string :job_id, index: true
5
+ t.text :params
6
+ t.string :status
7
+ t.string :job_class
8
+ t.string :error
9
+ t.text :stack_trace
10
+ t.datetime :queued_at
11
+ t.datetime :started_at
12
+ t.datetime :ended_at
13
+ t.integer :queued_duration
14
+ t.integer :execution_duration
15
+ t.integer :total_duration
16
+ t.integer :executions
17
+ t.string :queue_name
18
+
19
+ t.timestamps
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ require "active_job_log/engine"
2
+ require "enumerize"
3
+
4
+ module ActiveJobLog
5
+ extend self
6
+
7
+ # You can add, in this module, your own configuration options as in the example below...
8
+ #
9
+ # attr_writer :my_option
10
+ #
11
+ # def my_option
12
+ # return "Default Value" unless @my_option
13
+ # @my_option
14
+ # end
15
+ #
16
+ # Then, you can customize the default behaviour (typically in a Rails initializer) like this:
17
+ #
18
+ # ActiveJobLog.setup do |config|
19
+ # config.root_url = "Another value"
20
+ # end
21
+
22
+ def setup
23
+ yield self
24
+ require "active_job_log"
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ module ActiveJobLog
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ActiveJobLog
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec, fixture: false
7
+ g.fixture_replacement :factory_bot, dir: "spec/factories"
8
+ end
9
+
10
+ initializer "initialize" do
11
+ require_relative "./log_ext"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ module ActiveJobLog
2
+ module LogExt
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_enqueue { |job| enqueue_job(job) }
7
+ before_perform { |job| execute_job(job) }
8
+ after_perform { |job| finish_job(job) }
9
+
10
+ rescue_from(Exception) do |exception|
11
+ fail_job(exception)
12
+ raise exception
13
+ end
14
+
15
+ def enqueue_job(job)
16
+ Job.update_job!(job.job_id, :queued, init_params(job))
17
+ end
18
+
19
+ def execute_job(job)
20
+ Job.update_job!(job.job_id, :pending, init_params(job))
21
+ end
22
+
23
+ def finish_job(job)
24
+ Job.update_job!(job.job_id, :finished)
25
+ end
26
+
27
+ def fail_job(exception)
28
+ Job.update_job!(job_id, :failed, error: exception.message, stack_trace: exception.backtrace)
29
+ end
30
+
31
+ def init_params(job)
32
+ {
33
+ job_class: self.class.name,
34
+ params: job.arguments,
35
+ executions: job.try(:executions),
36
+ queue_name: job.queue_name
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ActiveJob::Base.send(:include, ActiveJobLog::LogExt)
@@ -0,0 +1,3 @@
1
+ module ActiveJobLog
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Install the engine in host app.
3
+
4
+ Example:
5
+ rails generate active_job_log:install
@@ -0,0 +1,19 @@
1
+ class ActiveJobLog::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def create_initializer
5
+ template "initializer.rb", "config/initializers/active_job_log.rb"
6
+ end
7
+
8
+ def mount_routes
9
+ line = "Rails.application.routes.draw do\n"
10
+ inject_into_file "config/routes.rb", after: line do <<-"HERE".gsub(/^ {4}/, '')
11
+ mount ActiveJobLog::Engine => "/active_job_log"
12
+ HERE
13
+ end
14
+ end
15
+
16
+ def copy_engine_migrations
17
+ rake "railties:install:migrations"
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ ActiveJobLog.setup do |config|
2
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :active_job_log do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,5 @@
1
+
2
+ //= link_tree ../images
3
+ //= link_directory ../javascripts .js
4
+ //= link_directory ../stylesheets .css
5
+ //= link active_job_log_manifest.js
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ // Action Cable provides the framework to deal with WebSockets in Rails.
2
+ // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3
+ //
4
+ //= require action_cable
5
+ //= require_self
6
+ //= require_tree ./channels
7
+
8
+ (function() {
9
+ this.App || (this.App = {});
10
+
11
+ App.cable = ActionCable.createConsumer();
12
+
13
+ }).call(this);
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ end