journaled 2.5.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 895598e96b01aad6c51bd55355c5d7d0fab963b97326c2943bcb76450dd7cdb7
4
- data.tar.gz: 61073882361fbb34ca243d8cc4dbedb494f798bcaaf2bde124f820eb8e175439
3
+ metadata.gz: 358c3ced2b976724c62e951ca88b635709d1fb7da0276ed4538bdc44bc02f468
4
+ data.tar.gz: ca65a5b0531ba4540de1b79fd36d247c7c164f3aef8b397254ed7b34503ebf0f
5
5
  SHA512:
6
- metadata.gz: 4564bc7e637fc2d032ee00b1f2b9e21282d65a531ae758ac374f863b1964100c3ea755db1e558c43d3503a74b995ffc310bb6343f255591357bf4d7ffe556e54
7
- data.tar.gz: b456385727f88392465553ff9c63f313902536a9a13cae00fae011e40c7afb2490f3f5ff5fb1012346c18cedfb5cfabcbd20ed2dcaf1cd039dc27551d756647c
6
+ metadata.gz: 236c6169ef41b1af9043f2549248ae43fad665a91d43cdd2f579e891685788aa5a008cf4f1dc8aba13abcce5dccfa6513c82232fdaaf3ab4f42f8a7b1b222bf7
7
+ data.tar.gz: 9e325f6c1e41eb577f5e0d7320517f5435b9570d7b0274c5b6ad9c593abc2a4a66dc6b6eb10d668617e645e5731804ecd65d4b6403fda63005de129443ed9332
data/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # Journaled
2
2
 
3
- A Rails engine to durably deliver schematized events to Amazon Kinesis via DelayedJob.
3
+ A Rails engine to durably deliver schematized events to Amazon Kinesis via ActiveJob.
4
4
 
5
5
  More specifically, `journaled` is composed of three opinionated pieces:
6
6
  schema definition/validation via JSON Schema, transactional enqueueing
7
- via Delayed::Job (specifically `delayed_job_active_record`), and event
7
+ via ActiveJob (specifically, via a DB-backed queue adapter), and event
8
8
  transmission via Amazon Kinesis. Our current use-cases include
9
9
  transmitting audit events for durable storage in S3 and/or analytical
10
10
  querying in Amazon Redshift.
11
11
 
12
12
  Journaled provides an at-least-once event delivery guarantee assuming
13
- Delayed::Job is configured not to delete jobs on failure.
13
+ ActiveJob's queue adapter is not configured to delete jobs on failure.
14
14
 
15
15
  Note: Do not use the journaled gem to build an event sourcing solution
16
16
  as it does not guarantee total ordering of events. It's possible we'll
@@ -20,9 +20,20 @@ durable, eventually consistent record that discrete events happened.
20
20
 
21
21
  ## Installation
22
22
 
23
- 1. [Install `delayed_job_active_record`](https://github.com/collectiveidea/delayed_job_active_record#installation)
24
- if you haven't already.
23
+ 1. If you haven't already,
24
+ [configure ActiveJob](https://guides.rubyonrails.org/active_job_basics.html)
25
+ to use one of the following queue adapters:
25
26
 
27
+ - `:delayed_job` (via `delayed_job_active_record`)
28
+ - `:que`
29
+ - `:good_job`
30
+ - `:delayed`
31
+
32
+ Ensure that your queue adapter is not configured to delete jobs on failure.
33
+
34
+ **If you launch your application in production mode and the gem detects that
35
+ `ActiveJob::Base.queue_adapter` is not in the above list, it will raise an exception
36
+ and prevent your application from performing unsafe journaling.**
26
37
 
27
38
  2. To integrate Journaled into your application, simply include the gem in your
28
39
  app's Gemfile.
@@ -85,9 +96,11 @@ Journaling provides a number of different configuation options that can be set i
85
96
 
86
97
  #### `Journaled.job_priority` (default: 20)
87
98
 
88
- This can be used to configure what `priority` the Delayed Jobs are enqueued with. This will be applied to all the Journaled::Devivery jobs that are created by this application.
99
+ This can be used to configure what `priority` the ActiveJobs are enqueued with. This will be applied to all the `Journaled::DeliveryJob`s that are created by this application.
89
100
  Ex: `Journaled.job_priority = 14`
90
101
 
102
+ _Note that job priority is only supported on Rails 6.0+. Prior Rails versions will ignore this parameter and enqueue jobs with the underlying ActiveJob adapter's default priority._
103
+
91
104
  #### `Journaled.http_idle_timeout` (default: 1 second)
92
105
 
93
106
  The number of seconds a persistent connection is allowed to sit idle before it should no longer be used.
@@ -100,9 +113,9 @@ Journaling provides a number of different configuation options that can be set i
100
113
 
101
114
  The number of seconds before the :http_handler should timeout while waiting for a HTTP response.
102
115
 
103
- #### DJ `enqueue` options
116
+ #### ActiveJob `set` options
104
117
 
105
- Both model-level directives accept additional options to be passed into DelayedJob's `enqueue` method:
118
+ Both model-level directives accept additional options to be passed into ActiveJob's `set` method:
106
119
 
107
120
  ```ruby
108
121
  # For change journaling:
data/Rakefile CHANGED
@@ -28,7 +28,13 @@ if %w(development test).include? Rails.env
28
28
  RuboCop::RakeTask.new
29
29
 
30
30
  task(:default).clear
31
- task default: %i(rubocop spec)
31
+ if ENV['APPRAISAL_INITIALIZED'] || ENV['CI']
32
+ task default: %i(rubocop spec)
33
+ else
34
+ require 'appraisal'
35
+ Appraisal::Task.new
36
+ task default: :appraisal
37
+ end
32
38
 
33
39
  task 'db:test:prepare' => 'db:setup'
34
40
  end
@@ -0,0 +1,4 @@
1
+ module Journaled
2
+ class ApplicationJob < Journaled.job_base_class_name.constantize
3
+ end
4
+ end
@@ -0,0 +1,96 @@
1
+ module Journaled
2
+ class DeliveryJob < ApplicationJob
3
+ DEFAULT_REGION = 'us-east-1'.freeze
4
+
5
+ rescue_from(Aws::Kinesis::Errors::InternalFailure, Aws::Kinesis::Errors::ServiceUnavailable, Aws::Kinesis::Errors::Http503Error) do |e|
6
+ Rails.logger.error "Kinesis Error - Server Error occurred - #{e.class}"
7
+ raise KinesisTemporaryFailure
8
+ end
9
+
10
+ rescue_from(Seahorse::Client::NetworkingError) do |e|
11
+ Rails.logger.error "Kinesis Error - Networking Error occurred - #{e.class}"
12
+ raise KinesisTemporaryFailure
13
+ end
14
+
15
+ def perform(serialized_event:, partition_key:, app_name:)
16
+ @serialized_event = serialized_event
17
+ @partition_key = partition_key
18
+ @app_name = app_name
19
+
20
+ journal!
21
+ end
22
+
23
+ def self.stream_name(app_name:)
24
+ env_var_name = [app_name&.upcase, 'JOURNALED_STREAM_NAME'].compact.join('_')
25
+ ENV.fetch(env_var_name)
26
+ end
27
+
28
+ def kinesis_client_config
29
+ {
30
+ region: ENV.fetch('AWS_DEFAULT_REGION', DEFAULT_REGION),
31
+ retry_limit: 0,
32
+ http_idle_timeout: Journaled.http_idle_timeout,
33
+ http_open_timeout: Journaled.http_open_timeout,
34
+ http_read_timeout: Journaled.http_read_timeout,
35
+ }.merge(credentials)
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :serialized_event, :partition_key, :app_name
41
+
42
+ def journal!
43
+ kinesis_client.put_record record if Journaled.enabled?
44
+ end
45
+
46
+ def record
47
+ {
48
+ stream_name: self.class.stream_name(app_name: app_name),
49
+ data: serialized_event,
50
+ partition_key: partition_key,
51
+ }
52
+ end
53
+
54
+ def kinesis_client
55
+ Aws::Kinesis::Client.new(kinesis_client_config)
56
+ end
57
+
58
+ def credentials
59
+ if ENV.key?('JOURNALED_IAM_ROLE_ARN')
60
+ {
61
+ credentials: iam_assume_role_credentials,
62
+ }
63
+ else
64
+ legacy_credentials_hash_if_present
65
+ end
66
+ end
67
+
68
+ def legacy_credentials_hash_if_present
69
+ if ENV.key?('RUBY_AWS_ACCESS_KEY_ID')
70
+ {
71
+ access_key_id: ENV.fetch('RUBY_AWS_ACCESS_KEY_ID'),
72
+ secret_access_key: ENV.fetch('RUBY_AWS_SECRET_ACCESS_KEY'),
73
+ }
74
+ else
75
+ {}
76
+ end
77
+ end
78
+
79
+ def sts_client
80
+ Aws::STS::Client.new({
81
+ region: ENV.fetch('AWS_DEFAULT_REGION', DEFAULT_REGION),
82
+ }.merge(legacy_credentials_hash_if_present))
83
+ end
84
+
85
+ def iam_assume_role_credentials
86
+ @iam_assume_role_credentials ||= Aws::AssumeRoleCredentials.new(
87
+ client: sts_client,
88
+ role_arn: ENV.fetch('JOURNALED_IAM_ROLE_ARN'),
89
+ role_session_name: "JournaledAssumeRoleAccess",
90
+ )
91
+ end
92
+
93
+ class KinesisTemporaryFailure < NotTrulyExceptionalError
94
+ end
95
+ end
96
+ end
@@ -83,6 +83,6 @@ class Journaled::Delivery # rubocop:disable Betterment/ActiveJobPerformable
83
83
  )
84
84
  end
85
85
 
86
- class KinesisTemporaryFailure < NotTrulyExceptionalError
86
+ class KinesisTemporaryFailure < ::Journaled::NotTrulyExceptionalError
87
87
  end
88
88
  end
@@ -27,7 +27,9 @@ class Journaled::Writer
27
27
  def journal!
28
28
  base_event_json_schema_validator.validate! serialized_event
29
29
  json_schema_validator.validate! serialized_event
30
- Journaled.enqueue!(journaled_delivery, journaled_enqueue_opts)
30
+ Journaled::DeliveryJob
31
+ .set(journaled_enqueue_opts.reverse_merge(priority: Journaled.job_priority))
32
+ .perform_later(delivery_perform_args)
31
33
  end
32
34
 
33
35
  private
@@ -35,12 +37,12 @@ class Journaled::Writer
35
37
  attr_reader :journaled_event
36
38
  delegate(*EVENT_METHOD_NAMES, to: :journaled_event)
37
39
 
38
- def journaled_delivery
39
- @journaled_delivery ||= Journaled::Delivery.new(
40
+ def delivery_perform_args
41
+ {
40
42
  serialized_event: serialized_event,
41
43
  partition_key: journaled_partition_key,
42
44
  app_name: journaled_app_name,
43
- )
45
+ }
44
46
  end
45
47
 
46
48
  def serialized_event
data/lib/journaled.rb CHANGED
@@ -1,17 +1,19 @@
1
1
  require "aws-sdk-kinesis"
2
- require "delayed_job"
2
+ require "active_job"
3
3
  require "json-schema"
4
4
  require "request_store"
5
5
 
6
6
  require "journaled/engine"
7
- require 'journaled/enqueue'
8
7
 
9
8
  module Journaled
9
+ SUPPORTED_QUEUE_ADAPTERS = %w(delayed delayed_job good_job que).freeze
10
+
10
11
  mattr_accessor :default_app_name
11
12
  mattr_accessor(:job_priority) { 20 }
12
13
  mattr_accessor(:http_idle_timeout) { 5 }
13
14
  mattr_accessor(:http_open_timeout) { 2 }
14
15
  mattr_accessor(:http_read_timeout) { 60 }
16
+ mattr_accessor(:job_base_class_name) { 'ActiveJob::Base' }
15
17
 
16
18
  def development_or_test?
17
19
  %w(development test).include?(Rails.env)
@@ -33,5 +35,21 @@ module Journaled
33
35
  Journaled::ActorUriProvider.instance.actor_uri
34
36
  end
35
37
 
36
- module_function :development_or_test?, :enabled?, :schema_providers, :commit_hash, :actor_uri
38
+ def detect_queue_adapter!
39
+ adapter = job_base_class_name.constantize.queue_adapter.class.name.split('::').last.underscore.gsub("_adapter", "")
40
+ unless SUPPORTED_QUEUE_ADAPTERS.include?(adapter)
41
+ raise <<~MSG
42
+ Journaled has detected an unsupported ActiveJob queue adapter: `:#{adapter}`
43
+
44
+ Journaled jobs must be enqueued transactionally to your primary database.
45
+
46
+ Please install the appropriate gems and set `queue_adapter` to one of the following:
47
+ #{SUPPORTED_QUEUE_ADAPTERS.map { |a| "- `:#{a}`" }.join("\n")}
48
+
49
+ Read more at https://github.com/Betterment/journaled
50
+ MSG
51
+ end
52
+ end
53
+
54
+ module_function :development_or_test?, :enabled?, :schema_providers, :commit_hash, :actor_uri, :detect_queue_adapter!
37
55
  end
@@ -1,4 +1,9 @@
1
1
  module Journaled
2
2
  class Engine < ::Rails::Engine
3
+ config.after_initialize do
4
+ ActiveSupport.on_load(:active_job) do
5
+ Journaled.detect_queue_adapter! unless Journaled.development_or_test?
6
+ end
7
+ end
3
8
  end
4
9
  end
@@ -1,3 +1,3 @@
1
1
  module Journaled
2
- VERSION = "2.5.0".freeze
2
+ VERSION = "3.0.0".freeze
3
3
  end
@@ -1,10 +1,9 @@
1
1
  require File.expand_path('boot', __dir__)
2
2
 
3
3
  require "active_record/railtie"
4
+ require "active_job/railtie"
4
5
  require "active_model/railtie"
5
6
  require "action_controller/railtie"
6
- require "action_mailer/railtie"
7
- require "sprockets/railtie"
8
7
 
9
8
  Bundler.require(*Rails.groups)
10
9
  require "journaled"
@@ -1,21 +1,6 @@
1
- default: &default
2
- pool: 5
3
- encoding: unicode
4
-
5
- postgresql:
6
- default: &postgres_default
7
- adapter: postgresql
8
- url: <%= ENV['DATABASE_URL'] %>
9
- test: &postgres_test
10
- <<: *postgres_default
11
- url: <%= ENV['DATABASE_URL'] || "postgresql://localhost:#{ENV.fetch('PGPORT', 5432)}/journaled_test" %>
12
- database: journaled_test
13
- development: &postgres_development
14
- <<: *postgres_default
15
- url: <%= ENV['DATABASE_URL'] || "postgresql://localhost:#{ENV.fetch('PGPORT', 5432)}/journaled_development" %>
16
- database: journaled_development
17
-
18
1
  development:
19
- <<: *postgres_development
2
+ adapter: sqlite3
3
+ database: ":memory:"
20
4
  test:
21
- <<: *postgres_test
5
+ adapter: sqlite3
6
+ database: ":memory:"
@@ -13,25 +13,12 @@ Rails.application.configure do
13
13
  config.consider_all_requests_local = true
14
14
  config.action_controller.perform_caching = false
15
15
 
16
- # Don't care if the mailer can't send.
17
- config.action_mailer.raise_delivery_errors = false
18
-
19
16
  # Print deprecation notices to the Rails logger.
20
17
  config.active_support.deprecation = :log
21
18
 
22
19
  # Raise an error on page load if there are pending migrations.
23
20
  config.active_record.migration_error = :page_load
24
21
 
25
- # Debug mode disables concatenation and preprocessing of assets.
26
- # This option may cause significant delays in view rendering with a large
27
- # number of complex assets.
28
- config.assets.debug = true
29
-
30
- # Adds additional error checking when serving assets at runtime.
31
- # Checks for improperly declared sprockets dependencies.
32
- # Raises helpful error messages.
33
- config.assets.raise_runtime_errors = true
34
-
35
22
  # Raises error for missing translations
36
23
  # config.action_view.raise_on_missing_translations = true
37
24
  end
@@ -26,14 +26,12 @@ Rails.application.configure do
26
26
  # Disable request forgery protection in test environment.
27
27
  config.action_controller.allow_forgery_protection = false
28
28
 
29
- # Tell Action Mailer not to deliver emails to the real world.
30
- # The :test delivery method accumulates sent emails in the
31
- # ActionMailer::Base.deliveries array.
32
- config.action_mailer.delivery_method = :test
33
-
34
29
  # Print deprecation notices to the stderr.
35
30
  config.active_support.deprecation = :stderr
36
31
 
37
32
  # Raises error for missing translations
38
33
  # config.action_view.raise_on_missing_translations = true
34
+
35
+ # Use ActiveJob test adapter
36
+ config.active_job.queue_adapter = :test
39
37
  end
@@ -11,21 +11,8 @@
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
13
  ActiveRecord::Schema.define(version: 20180606205114) do
14
- # These are extensions that must be enabled in order to support this database
15
- enable_extension "plpgsql"
16
-
17
- create_table "delayed_jobs", force: :cascade do |t|
18
- t.integer "priority", default: 0, null: false
19
- t.integer "attempts", default: 0, null: false
20
- t.text "handler", null: false
21
- t.text "last_error"
22
- t.datetime "run_at"
23
- t.datetime "locked_at"
24
- t.datetime "failed_at"
25
- t.string "locked_by"
26
- t.string "queue"
27
- t.datetime "created_at"
28
- t.datetime "updated_at"
29
- t.index ["priority", "run_at"], name: "delayed_jobs_priority"
14
+ create_table "widgets", force: :cascade do |t|
15
+ t.string "name"
16
+ t.string "other_column"
30
17
  end
31
18
  end
@@ -0,0 +1,221 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Journaled::DeliveryJob do
4
+ let(:stream_name) { 'test_events' }
5
+ let(:partition_key) { 'fake_partition_key' }
6
+ let(:serialized_event) { '{"foo":"bar"}' }
7
+ let(:kinesis_client) { Aws::Kinesis::Client.new(stub_responses: true) }
8
+ let(:args) { { serialized_event: serialized_event, partition_key: partition_key, app_name: nil } }
9
+
10
+ around do |example|
11
+ with_env(JOURNALED_STREAM_NAME: stream_name) { example.run }
12
+ end
13
+
14
+ describe '#perform' do
15
+ let(:return_status_body) { { shard_id: '101', sequence_number: '101123' } }
16
+ let(:return_object) { instance_double Aws::Kinesis::Types::PutRecordOutput, return_status_body }
17
+
18
+ before do
19
+ allow(Aws::AssumeRoleCredentials).to receive(:new).and_call_original
20
+ allow(Aws::Kinesis::Client).to receive(:new).and_return kinesis_client
21
+ kinesis_client.stub_responses(:put_record, return_status_body)
22
+
23
+ allow(Journaled).to receive(:enabled?).and_return(true)
24
+ end
25
+
26
+ it 'makes requests to AWS to put the event on the Kinesis with the correct body' do
27
+ event = described_class.perform_now(args)
28
+
29
+ expect(event.shard_id).to eq '101'
30
+ expect(event.sequence_number).to eq '101123'
31
+ end
32
+
33
+ context 'when JOURNALED_IAM_ROLE_ARN is defined' do
34
+ let(:aws_sts_client) { Aws::STS::Client.new(stub_responses: true) }
35
+
36
+ around do |example|
37
+ with_env(JOURNALED_IAM_ROLE_ARN: 'iam-role-arn-for-assuming-kinesis-access') { example.run }
38
+ end
39
+
40
+ before do
41
+ allow(Aws::STS::Client).to receive(:new).and_return aws_sts_client
42
+ aws_sts_client.stub_responses(:assume_role, assume_role_response)
43
+ end
44
+
45
+ let(:assume_role_response) do
46
+ {
47
+ assumed_role_user: {
48
+ arn: 'iam-role-arn-for-assuming-kinesis-access',
49
+ assumed_role_id: "ARO123EXAMPLE123:Bob",
50
+ },
51
+ credentials: {
52
+ access_key_id: "AKIAIOSFODNN7EXAMPLE",
53
+ secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
54
+ session_token: "EXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI",
55
+ expiration: Time.zone.parse("2011-07-15T23:28:33.359Z"),
56
+ },
57
+ }
58
+ end
59
+
60
+ it 'initializes a Kinesis client with assume role credentials' do
61
+ described_class.perform_now(args)
62
+
63
+ expect(Aws::AssumeRoleCredentials).to have_received(:new).with(
64
+ client: aws_sts_client,
65
+ role_arn: "iam-role-arn-for-assuming-kinesis-access",
66
+ role_session_name: "JournaledAssumeRoleAccess",
67
+ )
68
+ end
69
+ end
70
+
71
+ context 'when the stream name env var is NOT set' do
72
+ let(:stream_name) { nil }
73
+
74
+ it 'raises an KeyError error' do
75
+ expect { described_class.perform_now(args) }.to raise_error KeyError
76
+ end
77
+ end
78
+
79
+ context 'when Amazon responds with an InternalFailure' do
80
+ before do
81
+ kinesis_client.stub_responses(:put_record, 'InternalFailure')
82
+ end
83
+
84
+ it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
85
+ allow(Rails.logger).to receive(:error)
86
+ expect { described_class.perform_now(args) }.to raise_error described_class::KinesisTemporaryFailure
87
+ expect(Rails.logger).to have_received(:error).with(
88
+ "Kinesis Error - Server Error occurred - Aws::Kinesis::Errors::InternalFailure",
89
+ ).once
90
+ end
91
+ end
92
+
93
+ context 'when Amazon responds with a ServiceUnavailable' do
94
+ before do
95
+ kinesis_client.stub_responses(:put_record, 'ServiceUnavailable')
96
+ end
97
+
98
+ it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
99
+ allow(Rails.logger).to receive(:error)
100
+ expect { described_class.perform_now(args) }.to raise_error described_class::KinesisTemporaryFailure
101
+ expect(Rails.logger).to have_received(:error).with(/\AKinesis Error/).once
102
+ end
103
+ end
104
+
105
+ context 'when we receive a 504 Gateway timeout' do
106
+ before do
107
+ kinesis_client.stub_responses(:put_record, 'Aws::Kinesis::Errors::ServiceError')
108
+ end
109
+
110
+ it 'raises an error that subclasses Aws::Kinesis::Errors::ServiceError' do
111
+ expect { described_class.perform_now(args) }.to raise_error Aws::Kinesis::Errors::ServiceError
112
+ end
113
+ end
114
+
115
+ context 'when the IAM user does not have permission to put_record to the specified stream' do
116
+ before do
117
+ kinesis_client.stub_responses(:put_record, 'AccessDeniedException')
118
+ end
119
+
120
+ it 'raises an AccessDeniedException error' do
121
+ expect { described_class.perform_now(args) }.to raise_error Aws::Kinesis::Errors::AccessDeniedException
122
+ end
123
+ end
124
+
125
+ context 'when the request timesout' do
126
+ before do
127
+ kinesis_client.stub_responses(:put_record, Seahorse::Client::NetworkingError.new(Timeout::Error.new))
128
+ end
129
+
130
+ it 'catches the error and re-raises a subclass of NotTrulyExceptionalError and logs about the failure' do
131
+ allow(Rails.logger).to receive(:error)
132
+ expect { described_class.perform_now(args) }.to raise_error described_class::KinesisTemporaryFailure
133
+ expect(Rails.logger).to have_received(:error).with(
134
+ "Kinesis Error - Networking Error occurred - Seahorse::Client::NetworkingError",
135
+ ).once
136
+ end
137
+ end
138
+ end
139
+
140
+ describe ".stream_name" do
141
+ context "when app_name is unspecified" do
142
+ it "is fetched from a prefixed ENV var if specified" do
143
+ allow(ENV).to receive(:fetch).and_return("expected_stream_name")
144
+ expect(described_class.stream_name(app_name: nil)).to eq("expected_stream_name")
145
+ expect(ENV).to have_received(:fetch).with("JOURNALED_STREAM_NAME")
146
+ end
147
+ end
148
+
149
+ context "when app_name is specified" do
150
+ it "is fetched from a prefixed ENV var if specified" do
151
+ allow(ENV).to receive(:fetch).and_return("expected_stream_name")
152
+ expect(described_class.stream_name(app_name: "my_funky_app_name")).to eq("expected_stream_name")
153
+ expect(ENV).to have_received(:fetch).with("MY_FUNKY_APP_NAME_JOURNALED_STREAM_NAME")
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "#kinesis_client_config" do
159
+ it "is in us-east-1 by default" do
160
+ with_env(AWS_DEFAULT_REGION: nil) do
161
+ expect(subject.kinesis_client_config).to include(region: 'us-east-1')
162
+ end
163
+ end
164
+
165
+ it "respects AWS_DEFAULT_REGION env var" do
166
+ with_env(AWS_DEFAULT_REGION: 'us-west-2') do
167
+ expect(subject.kinesis_client_config).to include(region: 'us-west-2')
168
+ end
169
+ end
170
+
171
+ it "doesn't limit retry" do
172
+ expect(subject.kinesis_client_config).to include(retry_limit: 0)
173
+ end
174
+
175
+ it "provides no AWS credentials by default" do
176
+ with_env(RUBY_AWS_ACCESS_KEY_ID: nil, RUBY_AWS_SECRET_ACCESS_KEY: nil) do
177
+ expect(subject.kinesis_client_config).not_to have_key(:access_key_id)
178
+ expect(subject.kinesis_client_config).not_to have_key(:secret_access_key)
179
+ end
180
+ end
181
+
182
+ it "will use legacy credentials if specified" do
183
+ with_env(RUBY_AWS_ACCESS_KEY_ID: 'key_id', RUBY_AWS_SECRET_ACCESS_KEY: 'secret') do
184
+ expect(subject.kinesis_client_config).to include(access_key_id: 'key_id', secret_access_key: 'secret')
185
+ end
186
+ end
187
+
188
+ it "will set http_idle_timeout by default" do
189
+ expect(subject.kinesis_client_config).to include(http_idle_timeout: 5)
190
+ end
191
+
192
+ it "will set http_open_timeout by default" do
193
+ expect(subject.kinesis_client_config).to include(http_open_timeout: 2)
194
+ end
195
+
196
+ it "will set http_read_timeout by default" do
197
+ expect(subject.kinesis_client_config).to include(http_read_timeout: 60)
198
+ end
199
+
200
+ context "when Journaled.http_idle_timeout is specified" do
201
+ it "will set http_idle_timeout by specified value" do
202
+ allow(Journaled).to receive(:http_idle_timeout).and_return(2)
203
+ expect(subject.kinesis_client_config).to include(http_idle_timeout: 2)
204
+ end
205
+ end
206
+
207
+ context "when Journaled.http_open_timeout is specified" do
208
+ it "will set http_open_timeout by specified value" do
209
+ allow(Journaled).to receive(:http_open_timeout).and_return(1)
210
+ expect(subject.kinesis_client_config).to include(http_open_timeout: 1)
211
+ end
212
+ end
213
+
214
+ context "when Journaled.http_read_timeout is specified" do
215
+ it "will set http_read_timeout by specified value" do
216
+ allow(Journaled).to receive(:http_read_timeout).and_return(2)
217
+ expect(subject.kinesis_client_config).to include(http_read_timeout: 2)
218
+ end
219
+ end
220
+ end
221
+ end
@@ -49,4 +49,43 @@ RSpec.describe Journaled do
49
49
  expect(described_class.actor_uri).to eq "my actor uri"
50
50
  end
51
51
  end
52
+
53
+ describe '.detect_queue_adapter!' do
54
+ it 'raises an error unless the queue adapter is DB-backed' do
55
+ expect { described_class.detect_queue_adapter! }.to raise_error <<~MSG
56
+ Journaled has detected an unsupported ActiveJob queue adapter: `:test`
57
+
58
+ Journaled jobs must be enqueued transactionally to your primary database.
59
+
60
+ Please install the appropriate gems and set `queue_adapter` to one of the following:
61
+ - `:delayed`
62
+ - `:delayed_job`
63
+ - `:good_job`
64
+ - `:que`
65
+
66
+ Read more at https://github.com/Betterment/journaled
67
+ MSG
68
+ end
69
+
70
+ context 'when the queue adapter is supported' do
71
+ before do
72
+ stub_const("ActiveJob::QueueAdapters::DelayedAdapter", Class.new)
73
+ ActiveJob::Base.disable_test_adapter
74
+ ActiveJob::Base.queue_adapter = :delayed
75
+ end
76
+
77
+ around do |example|
78
+ begin
79
+ example.run
80
+ ensure
81
+ ActiveJob::Base.queue_adapter = :test
82
+ ActiveJob::Base.enable_test_adapter(ActiveJob::QueueAdapters::TestAdapter.new)
83
+ end
84
+ end
85
+
86
+ it 'does not raise an error' do
87
+ expect { described_class.detect_queue_adapter! }.not_to raise_error
88
+ end
89
+ end
90
+ end
52
91
  end
@@ -4,38 +4,42 @@ if Rails::VERSION::MAJOR > 5 || (Rails::VERSION::MAJOR == 5 && Rails::VERSION::M
4
4
  # rubocop:disable Rails/SkipsModelValidations
5
5
  RSpec.describe "Raw database change protection" do
6
6
  let(:journaled_class) do
7
- Class.new(Delayed::Job) do
7
+ Class.new(ActiveRecord::Base) do
8
8
  include Journaled::Changes
9
9
 
10
- journal_changes_to :locked_at, as: :attempt
10
+ self.table_name = 'widgets'
11
+
12
+ journal_changes_to :name, as: :attempt
11
13
  end
12
14
  end
13
15
 
14
16
  let(:journaled_class_with_no_journaled_columns) do
15
- Class.new(Delayed::Job) do
17
+ Class.new(ActiveRecord::Base) do
16
18
  include Journaled::Changes
19
+
20
+ self.table_name = 'widgets'
17
21
  end
18
22
  end
19
23
 
20
24
  describe "the relation" do
21
25
  describe "#update_all" do
22
26
  it "refuses on journaled columns passed as hash" do
23
- expect { journaled_class.update_all(locked_at: nil) }.to raise_error(/aborted by Journaled/)
27
+ expect { journaled_class.update_all(name: nil) }.to raise_error(/aborted by Journaled/)
24
28
  end
25
29
 
26
30
  it "refuses on journaled columns passed as string" do
27
- expect { journaled_class.update_all("\"locked_at\" = NULL") }.to raise_error(/aborted by Journaled/)
28
- expect { journaled_class.update_all("locked_at = null") }.to raise_error(/aborted by Journaled/)
29
- expect { journaled_class.update_all("delayed_jobs.locked_at = null") }.to raise_error(/aborted by Journaled/)
30
- expect { journaled_class.update_all("last_error = 'locked_at'") }.not_to raise_error
31
+ expect { journaled_class.update_all("\"name\" = NULL") }.to raise_error(/aborted by Journaled/)
32
+ expect { journaled_class.update_all("name = null") }.to raise_error(/aborted by Journaled/)
33
+ expect { journaled_class.update_all("widgets.name = null") }.to raise_error(/aborted by Journaled/)
34
+ expect { journaled_class.update_all("other_column = 'name'") }.not_to raise_error
31
35
  end
32
36
 
33
37
  it "succeeds on unjournaled columns" do
34
- expect { journaled_class.update_all(handler: "") }.not_to raise_error
38
+ expect { journaled_class.update_all(other_column: "") }.not_to raise_error
35
39
  end
36
40
 
37
41
  it "succeeds when forced on journaled columns" do
38
- expect { journaled_class.update_all({ locked_at: nil }, force: true) }.not_to raise_error
42
+ expect { journaled_class.update_all({ name: nil }, force: true) }.not_to raise_error
39
43
  end
40
44
  end
41
45
 
@@ -69,29 +73,19 @@ if Rails::VERSION::MAJOR > 5 || (Rails::VERSION::MAJOR == 5 && Rails::VERSION::M
69
73
  end
70
74
 
71
75
  describe "an instance" do
72
- let(:job) do
73
- module TestJob
74
- def perform
75
- "foo"
76
- end
77
-
78
- module_function :perform
79
- end
80
- end
81
-
82
- subject { journaled_class.enqueue(job) }
76
+ subject { journaled_class.create!(name: 'foo') }
83
77
 
84
78
  describe "#update_columns" do
85
79
  it "refuses on journaled columns" do
86
- expect { subject.update_columns(locked_at: nil) }.to raise_error(/aborted by Journaled/)
80
+ expect { subject.update_columns(name: nil) }.to raise_error(/aborted by Journaled/)
87
81
  end
88
82
 
89
83
  it "succeeds on unjournaled columns" do
90
- expect { subject.update_columns(handler: "") }.not_to raise_error
84
+ expect { subject.update_columns(other_column: "") }.not_to raise_error
91
85
  end
92
86
 
93
87
  it "succeeds when forced on journaled columns" do
94
- expect { subject.update_columns({ locked_at: nil }, force: true) }.not_to raise_error
88
+ expect { subject.update_columns({ name: nil }, force: true) }.not_to raise_error
95
89
  end
96
90
  end
97
91
 
@@ -101,7 +95,7 @@ if Rails::VERSION::MAJOR > 5 || (Rails::VERSION::MAJOR == 5 && Rails::VERSION::M
101
95
  end
102
96
 
103
97
  it "succeeds if no journaled columns exist" do
104
- instance = journaled_class_with_no_journaled_columns.enqueue(job)
98
+ instance = journaled_class_with_no_journaled_columns.create!
105
99
  expect { instance.delete }.not_to raise_error
106
100
  end
107
101
 
@@ -80,16 +80,12 @@ RSpec.describe Journaled::Writer do
80
80
  )
81
81
  end
82
82
 
83
- around do |example|
84
- with_jobs_delayed { example.run }
85
- end
86
-
87
83
  context 'when the journaled event does NOT comply with the base_event schema' do
88
84
  let(:journaled_event_attributes) { { foo: 1 } }
89
85
 
90
86
  it 'raises an error and does not enqueue anything' do
91
87
  expect { subject.journal! }.to raise_error JSON::Schema::ValidationError
92
- expect(Delayed::Job.where('handler like ?', '%Journaled::Delivery%').count).to eq 0
88
+ expect(enqueued_jobs.count).to eq 0
93
89
  end
94
90
  end
95
91
 
@@ -99,7 +95,7 @@ RSpec.describe Journaled::Writer do
99
95
 
100
96
  it 'raises an error and does not enqueue anything' do
101
97
  expect { subject.journal! }.to raise_error JSON::Schema::ValidationError
102
- expect(Delayed::Job.where('handler like ?', '%Journaled::Delivery%').count).to eq 0
98
+ expect(enqueued_jobs.count).to eq 0
103
99
  end
104
100
  end
105
101
 
@@ -107,9 +103,8 @@ RSpec.describe Journaled::Writer do
107
103
  let(:journaled_event_attributes) { { id: 'FAKE_UUID', event_type: 'fake_event', created_at: Time.zone.now, foo: :bar } }
108
104
 
109
105
  it 'creates a delivery with the app name passed through' do
110
- allow(Journaled::Delivery).to receive(:new).and_call_original
111
- subject.journal!
112
- expect(Journaled::Delivery).to have_received(:new).with(hash_including(app_name: 'my_app'))
106
+ expect { subject.journal! }.to change { enqueued_jobs.count }.from(0).to(1)
107
+ expect(enqueued_jobs.first[:args].first).to include('app_name' => 'my_app')
113
108
  end
114
109
 
115
110
  context 'when there is no job priority specified in the enqueue opts' do
@@ -122,7 +117,11 @@ RSpec.describe Journaled::Writer do
122
117
 
123
118
  it 'defaults to the global default' do
124
119
  expect { subject.journal! }.to change {
125
- Delayed::Job.where('handler like ?', '%Journaled::Delivery%').where(priority: 999).count
120
+ if Rails::VERSION::MAJOR < 6
121
+ enqueued_jobs.select { |j| j[:job] == Journaled::DeliveryJob }.count
122
+ else
123
+ enqueued_jobs.select { |j| j['job_class'] == 'Journaled::DeliveryJob' && j['priority'] == 999 }.count
124
+ end
126
125
  }.from(0).to(1)
127
126
  end
128
127
  end
@@ -130,9 +129,13 @@ RSpec.describe Journaled::Writer do
130
129
  context 'when there is a job priority specified in the enqueue opts' do
131
130
  let(:journaled_enqueue_opts) { { priority: 13 } }
132
131
 
133
- it 'enqueues a Journaled::Delivery object with the given priority' do
132
+ it 'enqueues a Journaled::DeliveryJob with the given priority' do
134
133
  expect { subject.journal! }.to change {
135
- Delayed::Job.where('handler like ?', '%Journaled::Delivery%').where(priority: 13).count
134
+ if Rails::VERSION::MAJOR < 6
135
+ enqueued_jobs.select { |j| j[:job] == Journaled::DeliveryJob }.count
136
+ else
137
+ enqueued_jobs.select { |j| j['job_class'] == 'Journaled::DeliveryJob' && j['priority'] == 13 }.count
138
+ end
136
139
  }.from(0).to(1)
137
140
  end
138
141
  end
data/spec/rails_helper.rb CHANGED
@@ -6,7 +6,6 @@ require 'rspec/rails'
6
6
  require 'timecop'
7
7
  require 'webmock/rspec'
8
8
  require 'journaled/rspec'
9
- require 'pry-rails'
10
9
 
11
10
  Dir[Rails.root.join('..', 'support', '**', '*.rb')].each { |f| require f }
12
11
 
@@ -15,6 +14,6 @@ RSpec.configure do |config|
15
14
 
16
15
  config.infer_spec_type_from_file_location!
17
16
 
18
- config.include DelayedJobSpecHelper
17
+ config.include ActiveJob::TestHelper
19
18
  config.include EnvironmentSpecHelper
20
19
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,7 @@
1
- require 'delayed_job_active_record'
2
1
  rails_env = ENV['RAILS_ENV'] ||= 'test'
3
- db_adapter = ENV['DB_ADAPTER'] ||= 'postgresql'
4
2
  require File.expand_path('dummy/config/environment.rb', __dir__)
5
3
 
6
- Rails.configuration.database_configuration[db_adapter][rails_env].tap do |c|
4
+ Rails.configuration.database_configuration[rails_env].tap do |c|
7
5
  ActiveRecord::Tasks::DatabaseTasks.create(c)
8
6
  ActiveRecord::Base.establish_connection(c)
9
7
  load File.expand_path('dummy/db/schema.rb', __dir__)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: journaled
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Lipson
@@ -11,24 +11,24 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2021-02-02 00:00:00.000000000 Z
14
+ date: 2021-05-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: aws-sdk-kinesis
17
+ name: activejob
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - "<"
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: '2'
22
+ version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "<"
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '2'
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: delayed_job
31
+ name: activerecord
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - ">="
@@ -41,6 +41,20 @@ dependencies:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: aws-sdk-kinesis
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '2'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "<"
56
+ - !ruby/object:Gem::Version
57
+ version: '2'
44
58
  - !ruby/object:Gem::Dependency
45
59
  name: json-schema
46
60
  requirement: !ruby/object:Gem::Requirement
@@ -56,7 +70,7 @@ dependencies:
56
70
  - !ruby/object:Gem::Version
57
71
  version: '0'
58
72
  - !ruby/object:Gem::Dependency
59
- name: rails
73
+ name: railties
60
74
  requirement: !ruby/object:Gem::Requirement
61
75
  requirements:
62
76
  - - ">="
@@ -103,48 +117,6 @@ dependencies:
103
117
  - - "~>"
104
118
  - !ruby/object:Gem::Version
105
119
  version: 2.2.0
106
- - !ruby/object:Gem::Dependency
107
- name: delayed_job_active_record
108
- requirement: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: '0'
113
- type: :development
114
- prerelease: false
115
- version_requirements: !ruby/object:Gem::Requirement
116
- requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- version: '0'
120
- - !ruby/object:Gem::Dependency
121
- name: pg
122
- requirement: !ruby/object:Gem::Requirement
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- version: '0'
127
- type: :development
128
- prerelease: false
129
- version_requirements: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- - !ruby/object:Gem::Dependency
135
- name: pry-rails
136
- requirement: !ruby/object:Gem::Requirement
137
- requirements:
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- version: '0'
141
- type: :development
142
- prerelease: false
143
- version_requirements: !ruby/object:Gem::Requirement
144
- requirements:
145
- - - ">="
146
- - !ruby/object:Gem::Version
147
- version: '0'
148
120
  - !ruby/object:Gem::Dependency
149
121
  name: rspec-rails
150
122
  requirement: !ruby/object:Gem::Requirement
@@ -216,19 +188,19 @@ dependencies:
216
188
  - !ruby/object:Gem::Version
217
189
  version: '0'
218
190
  - !ruby/object:Gem::Dependency
219
- name: sprockets
191
+ name: sqlite3
220
192
  requirement: !ruby/object:Gem::Requirement
221
193
  requirements:
222
- - - "<"
194
+ - - ">="
223
195
  - !ruby/object:Gem::Version
224
- version: '4.0'
196
+ version: '0'
225
197
  type: :development
226
198
  prerelease: false
227
199
  version_requirements: !ruby/object:Gem::Requirement
228
200
  requirements:
229
- - - "<"
201
+ - - ">="
230
202
  - !ruby/object:Gem::Version
231
- version: '4.0'
203
+ version: '0'
232
204
  - !ruby/object:Gem::Dependency
233
205
  name: timecop
234
206
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +244,8 @@ files:
272
244
  - README.md
273
245
  - Rakefile
274
246
  - app/controllers/concerns/journaled/actor.rb
247
+ - app/jobs/journaled/application_job.rb
248
+ - app/jobs/journaled/delivery_job.rb
275
249
  - app/models/concerns/journaled/changes.rb
276
250
  - app/models/journaled/actor_uri_provider.rb
277
251
  - app/models/journaled/change.rb
@@ -283,13 +257,11 @@ files:
283
257
  - app/models/journaled/not_truly_exceptional_error.rb
284
258
  - app/models/journaled/writer.rb
285
259
  - config/initializers/change_protection.rb
286
- - config/routes.rb
287
260
  - config/spring.rb
288
261
  - journaled_schemas/base_event.json
289
262
  - journaled_schemas/journaled/change.json
290
263
  - lib/journaled.rb
291
264
  - lib/journaled/engine.rb
292
- - lib/journaled/enqueue.rb
293
265
  - lib/journaled/relation_change_protection.rb
294
266
  - lib/journaled/rspec.rb
295
267
  - lib/journaled/version.rb
@@ -304,9 +276,7 @@ files:
304
276
  - spec/dummy/config/database.yml
305
277
  - spec/dummy/config/environment.rb
306
278
  - spec/dummy/config/environments/development.rb
307
- - spec/dummy/config/environments/production.rb
308
279
  - spec/dummy/config/environments/test.rb
309
- - spec/dummy/config/initializers/assets.rb
310
280
  - spec/dummy/config/initializers/backtrace_silencers.rb
311
281
  - spec/dummy/config/initializers/cookies_serializer.rb
312
282
  - spec/dummy/config/initializers/filter_parameter_logging.rb
@@ -317,12 +287,12 @@ files:
317
287
  - spec/dummy/config/locales/en.yml
318
288
  - spec/dummy/config/routes.rb
319
289
  - spec/dummy/config/secrets.yml
320
- - spec/dummy/db/migrate/20180606205114_create_delayed_jobs.rb
321
290
  - spec/dummy/db/schema.rb
322
291
  - spec/dummy/public/404.html
323
292
  - spec/dummy/public/422.html
324
293
  - spec/dummy/public/500.html
325
294
  - spec/dummy/public/favicon.ico
295
+ - spec/jobs/journaled/delivery_job_spec.rb
326
296
  - spec/lib/journaled_spec.rb
327
297
  - spec/models/concerns/journaled/actor_spec.rb
328
298
  - spec/models/concerns/journaled/changes_spec.rb
@@ -335,7 +305,6 @@ files:
335
305
  - spec/models/journaled/writer_spec.rb
336
306
  - spec/rails_helper.rb
337
307
  - spec/spec_helper.rb
338
- - spec/support/delayed_job_spec_helper.rb
339
308
  - spec/support/environment_spec_helper.rb
340
309
  homepage: http://github.com/Betterment/journaled
341
310
  licenses:
@@ -368,7 +337,6 @@ test_files:
368
337
  - spec/dummy/config/secrets.yml
369
338
  - spec/dummy/config/routes.rb
370
339
  - spec/dummy/config/locales/en.yml
371
- - spec/dummy/config/environments/production.rb
372
340
  - spec/dummy/config/environments/development.rb
373
341
  - spec/dummy/config/environments/test.rb
374
342
  - spec/dummy/config/environment.rb
@@ -380,7 +348,6 @@ test_files:
380
348
  - spec/dummy/config/initializers/filter_parameter_logging.rb
381
349
  - spec/dummy/config/initializers/session_store.rb
382
350
  - spec/dummy/config/initializers/wrap_parameters.rb
383
- - spec/dummy/config/initializers/assets.rb
384
351
  - spec/dummy/config/initializers/cookies_serializer.rb
385
352
  - spec/dummy/config/initializers/inflections.rb
386
353
  - spec/dummy/config.ru
@@ -390,7 +357,6 @@ test_files:
390
357
  - spec/dummy/public/500.html
391
358
  - spec/dummy/public/404.html
392
359
  - spec/dummy/db/schema.rb
393
- - spec/dummy/db/migrate/20180606205114_create_delayed_jobs.rb
394
360
  - spec/dummy/README.rdoc
395
361
  - spec/models/journaled/json_schema_model/validator_spec.rb
396
362
  - spec/models/journaled/actor_uri_provider_spec.rb
@@ -401,7 +367,7 @@ test_files:
401
367
  - spec/models/database_change_protection_spec.rb
402
368
  - spec/models/concerns/journaled/changes_spec.rb
403
369
  - spec/models/concerns/journaled/actor_spec.rb
404
- - spec/support/delayed_job_spec_helper.rb
405
370
  - spec/support/environment_spec_helper.rb
406
371
  - spec/lib/journaled_spec.rb
372
+ - spec/jobs/journaled/delivery_job_spec.rb
407
373
  - spec/rails_helper.rb
data/config/routes.rb DELETED
@@ -1,2 +0,0 @@
1
- Rails.application.routes.draw do
2
- end
@@ -1,13 +0,0 @@
1
- module Journaled
2
- class << self
3
- def enqueue!(*args)
4
- delayed_job_enqueue(*args)
5
- end
6
-
7
- private
8
-
9
- def delayed_job_enqueue(*args, **opts)
10
- Delayed::Job.enqueue(*args, **opts.reverse_merge(priority: Journaled.job_priority))
11
- end
12
- end
13
- end
@@ -1,78 +0,0 @@
1
- Rails.application.configure do
2
- # Settings specified here will take precedence over those in config/application.rb.
3
-
4
- # Code is not reloaded between requests.
5
- config.cache_classes = true
6
-
7
- # Eager load code on boot. This eager loads most of Rails and
8
- # your application in memory, allowing both threaded web servers
9
- # and those relying on copy on write to perform better.
10
- # Rake tasks automatically ignore this option for performance.
11
- config.eager_load = true
12
-
13
- # Full error reports are disabled and caching is turned on.
14
- config.consider_all_requests_local = false
15
- config.action_controller.perform_caching = true
16
-
17
- # Enable Rack::Cache to put a simple HTTP cache in front of your application
18
- # Add `rack-cache` to your Gemfile before enabling this.
19
- # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
20
- # config.action_dispatch.rack_cache = true
21
-
22
- # Disable Rails's static asset server (Apache or nginx will already do this).
23
- config.serve_static_assets = false
24
-
25
- # Compress JavaScripts and CSS.
26
- config.assets.js_compressor = :uglifier
27
- # config.assets.css_compressor = :sass
28
-
29
- # Do not fallback to assets pipeline if a precompiled asset is missed.
30
- config.assets.compile = false
31
-
32
- # Generate digests for assets URLs.
33
- config.assets.digest = true
34
-
35
- # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
36
-
37
- # Specifies the header that your server uses for sending files.
38
- # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
39
- # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
40
-
41
- # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
42
- # config.force_ssl = true
43
-
44
- # Set to :debug to see everything in the log.
45
- config.log_level = :info
46
-
47
- # Prepend all log lines with the following tags.
48
- # config.log_tags = [ :subdomain, :uuid ]
49
-
50
- # Use a different logger for distributed setups.
51
- # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
52
-
53
- # Use a different cache store in production.
54
- # config.cache_store = :mem_cache_store
55
-
56
- # Enable serving of images, stylesheets, and JavaScripts from an asset server.
57
- # config.action_controller.asset_host = "http://assets.example.com"
58
-
59
- # Ignore bad email addresses and do not raise email delivery errors.
60
- # Set this to true and configure the email server for immediate delivery to raise delivery errors.
61
- # config.action_mailer.raise_delivery_errors = false
62
-
63
- # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
64
- # the I18n.default_locale when a translation cannot be found).
65
- config.i18n.fallbacks = true
66
-
67
- # Send deprecation notices to registered listeners.
68
- config.active_support.deprecation = :notify
69
-
70
- # Disable automatic flushing of the log to improve performance.
71
- # config.autoflush_log = false
72
-
73
- # Use default logging formatter so that PID and timestamp are not suppressed.
74
- config.log_formatter = ::Logger::Formatter.new
75
-
76
- # Do not dump schema after migrations.
77
- config.active_record.dump_schema_after_migration = false
78
- end
@@ -1,8 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # Version of your assets, change this if you want to expire all your assets.
4
- Rails.application.config.assets.version = '1.0'
5
-
6
- # Precompile additional assets.
7
- # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
8
- # Rails.application.config.assets.precompile += %w( search.js )
@@ -1,18 +0,0 @@
1
- class CreateDelayedJobs < ActiveRecord::Migration[5.1]
2
- def change
3
- create_table :delayed_jobs do |t|
4
- t.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue
5
- t.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually.
6
- t.text :handler, null: false # YAML-encoded string of the object that will do work
7
- t.text :last_error # reason for last failure (See Note below)
8
- t.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
9
- t.datetime :locked_at # Set when a client is working on this object
10
- t.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11
- t.string :locked_by # Who is working on this object (if locked)
12
- t.string :queue # The name of the queue this job is in
13
- t.timestamps null: true
14
- end
15
-
16
- add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority"
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- module DelayedJobSpecHelper
2
- def with_jobs_delayed(opts = {})
3
- work_off = opts.fetch(:work_off, true)
4
- original = Delayed::Worker.delay_jobs
5
- Delayed::Worker.delay_jobs = true
6
- yield
7
- ensure
8
- Delayed::Worker.delay_jobs = original
9
- Delayed::Worker.new.work_off if work_off
10
- end
11
- end