riverqueue-rails 0.0.0.reserved → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aafcf39071cd336e283033164f15128e0f3fc601c1711e57813894828d143d75
4
- data.tar.gz: 8cc01b3759c58443f903e49719f79dd690a2cd632fd10759a0fa1b62fc66631a
3
+ metadata.gz: ca9fae4ee65e198bdc794af928e1db7990ae73b9907094065b33b89d7da85050
4
+ data.tar.gz: fb340cbebbc096af53e530ad10cc927fb89c24b3a4b2e0256f2201403cb0b968
5
5
  SHA512:
6
- metadata.gz: 01bc308616ddd8c7cff4753fed534e4b18da7f7792af4c8c3e32a4d8cb556546f94f93d9fbf0192b3dafc86635e1deefd2b93e1d1947bf19d710fb71f54ee09c
7
- data.tar.gz: 3c3609e9e0fd583a78d16ce8329fca98d2a7aa4f37152322cea8db571c8b16be5b634b27ac497985f1ef83b5396acc8a32cb3862b06f664697dbaa3f785204bb
6
+ metadata.gz: 915401d890a4c38b642c4f3117d5c22d40104f2d1b8adcf155b1b41d0ac97242c056ed2e506052d690efcc9a659b838b9a788587e48d609502ae613e03133ad0
7
+ data.tar.gz: 7c4e3718bbc6760a68d9f1cd58afaf5a4f584bc5b142a20748b4dbfb5e611644a6b0385834a35c5e429e226cb4350506e8c0b76accb2f75498a169f942fe2ae5
data/README.md CHANGED
@@ -1,7 +1,191 @@
1
- # riverqueue-rails
1
+ # River for Rails
2
2
 
3
- This is an official name-reservation placeholder for Rails and Active Job integration for River.
4
- It is not a functional release and contains no implementation code.
5
- Do not use this placeholder in an application.
3
+ `riverqueue-rails` integrates Active Job with River's existing PostgreSQL/SQLite
4
+ runtime. It supports Rails 7.2, 8.0, and 8.1 and lives separately from the
5
+ Rails-independent core gem. Database gems remain application-selected.
6
6
 
7
- Visit https://riverqueue.com for project information.
7
+ ## Install
8
+
9
+ ```ruby
10
+ gem "riverqueue-rails"
11
+ gem "pg" # Or sqlite3.
12
+ ```
13
+
14
+ ```sh
15
+ bin/rails generate river:install
16
+ bin/rails river:migrate
17
+ bin/jobs start
18
+ ```
19
+
20
+ The generator installs `config/initializers/river.rb` and `bin/jobs`. Migration
21
+ tasks use the canonical bundled Go SQL through `River::Migrator`; no separate
22
+ Rails schema is created. `bin/rails river:status` shows migration status.
23
+ Migrate explicitly during deployment, not on every application boot.
24
+
25
+ ## Configuration
26
+
27
+ ```ruby
28
+ Rails.application.configure do
29
+ config.active_job.queue_adapter = :river unless Rails.env.test?
30
+ config.river.stop_timeout = 30
31
+
32
+ config.river.configure do
33
+ River::Config.new(
34
+ job_timeout: 300,
35
+ logger: Rails.logger,
36
+ queues: {default: 10, mailers: 5}
37
+ )
38
+ end
39
+ end
40
+ ```
41
+
42
+ The block runs lazily after application boot and again when constructing a
43
+ consumer. It must return a fresh `River::Config`. The integration registers the
44
+ reserved `active_job` worker and installs Rails execution wrapping automatically.
45
+ Web processes only insert; `river worker --rails` or `bin/jobs start` starts consumers. Configure all
46
+ actual queue names, including Active Job queue prefixes and Action Mailer queues.
47
+ Counts are per queue, per process. Size the database pool for application work,
48
+ producers, and maintenance as well as consumer threads.
49
+
50
+ Clients are rebuilt after a fork; Rails/the process server remains responsible
51
+ for its connection-pool fork lifecycle. Do not share clients across Ractors.
52
+
53
+ ## Dedicated worker process
54
+
55
+ From the Rails application root:
56
+
57
+ ```sh
58
+ RAILS_ENV=production bundle exec river worker --rails
59
+ # Override config.river.stop_timeout for this process:
60
+ RAILS_ENV=production bundle exec river worker --rails --stop-timeout 60
61
+ ```
62
+
63
+ The command boots Rails and builds a consumer using the configuration above.
64
+ Do not start it in a web initializer. Migrate before starting consumers, and use
65
+ an external supervisor for process counts and restarts.
66
+
67
+ TERM/INT request stop and drain active attempts. At the graceful deadline,
68
+ the runner interrupts attempts and allows five seconds for finalization before
69
+ forcing exit. TSTP requests `stop(wait: false)` but keeps the process alive until
70
+ a later TERM/INT. Successfully finalized interruptions make jobs available again;
71
+ forced termination may leave jobs for stuck-job recovery. Give the supervisor a
72
+ termination window longer than the grace period plus finalization and a margin.
73
+
74
+ See [Dedicated worker processes](../../docs/workers.md) for signal behavior,
75
+ exit statuses, pool sizing, and rolling replacements. The generated `bin/jobs
76
+ start` delegates to the same runner; CLI options belong to `river worker`.
77
+
78
+ ## Jobs and mail
79
+
80
+ ```ruby
81
+ class FulfillOrderJob < ApplicationJob
82
+ queue_as :default
83
+ retry_on PaymentGateway::Unavailable, attempts: 5, wait: 30.seconds
84
+ discard_on ActiveJob::DeserializationError
85
+
86
+ def perform(order)
87
+ FulfillOrder.call(order)
88
+ end
89
+ end
90
+
91
+ FulfillOrderJob.perform_later order
92
+ FulfillOrderJob.set(wait: 10.minutes).perform_later order
93
+ OrderMailer.receipt(order).deliver_later
94
+ ```
95
+
96
+ Active Job handles serialization, GlobalID, callbacks, locale, timezone, and
97
+ custom serializers. Bulk `ActiveJob.perform_all_later` uses River's atomic bulk
98
+ insertion. Priorities must be `nil` (River priority 1) or integers 1 through 4.
99
+ Unsupported priorities raise instead of silently changing meaning.
100
+
101
+ ## Transactions
102
+
103
+ The default connection class is `ActiveRecord::Base`. Select a different abstract
104
+ Active Record class for producers, consumers, and migration tasks together:
105
+
106
+ ```ruby
107
+ Rails.application.configure do
108
+ config.river.connection_class = "ApplicationRecord"
109
+ end
110
+ ```
111
+
112
+ Prefer a class name in Rails initializers: it is resolved lazily after boot and
113
+ the insertion client is rebuilt if Rails reloads the class. An actual class
114
+ object is also accepted. Configure its database through ordinary Active Record
115
+ `establish_connection` or `connects_to` configuration. Restart consumers after
116
+ changing connection configuration.
117
+
118
+ Without the Rails integration, select the class directly on the driver:
119
+
120
+ ```ruby
121
+ River::Driver::ActiveRecord.new(connection_class: ApplicationRecord)
122
+ ```
123
+
124
+ Insert jobs in the selected connection's transaction for atomicity. Sharing a
125
+ database URL alone does not provide atomicity across connections. A dedicated
126
+ queue connection class/database is supported, but does not commit atomically
127
+ with application writes on another connection.
128
+
129
+ Shard routing and worker management remain explicit. Inserts follow the selected
130
+ class's current Active Record role/shard; consumers need their own appropriate
131
+ connection configuration. A request's `connected_to` block is not propagated to
132
+ worker threads. Use the same database backend/schema layout across roles/shards
133
+ accessed by a driver; no automatic shard discovery or cross-shard transactions
134
+ are provided.
135
+
136
+ For Rails 8.x, disable after-commit deferral explicitly when relying on atomicity:
137
+
138
+ ```ruby
139
+ class ApplicationJob < ActiveJob::Base
140
+ self.enqueue_after_transaction_commit = false
141
+ end
142
+
143
+ ApplicationRecord.transaction do
144
+ order = Order.create!(status: "pending")
145
+ FulfillOrderJob.perform_later(order)
146
+ end
147
+ ```
148
+
149
+ The Rails 7.2 adapter default is immediate insertion; its explicit policies use
150
+ `:never` and `:always` instead of Rails 8's `false` and `true`. Explicit application
151
+ after-commit policies are respected on every supported version, but lose the
152
+ atomic-write guarantee. A returned provider ID does not prove an outer transaction
153
+ has committed. Job completion and business writes are not automatically atomic.
154
+
155
+ ## Retries and observability
156
+
157
+ Active Job owns application retries. `retry_on` creates a new River row with the
158
+ same Active Job UUID, while `provider_job_id` becomes the new River row ID string.
159
+ Unhandled errors, including exhausted `retry_on`, discard the current row without
160
+ an additional River retry cycle. Native River workers retain their normal policy.
161
+ The 25-attempt River budget is retained for crash recovery; stuck claims are
162
+ rescued by normal River maintenance (currently after an hour).
163
+
164
+ River interruption, cancellation, and snooze exceptions bypass Active Job's
165
+ retry/discard handlers, including `retry_on StandardError`. Avoid swallowing
166
+ these exceptions in broad Ruby `rescue` blocks inside application code.
167
+
168
+ Handled retries/discards complete the current delivery row. Its metadata records
169
+ `active_job_outcome` (`retried` or `discarded`), and retried deliveries record
170
+ `active_job_retry_id`. A completed delivery need not mean the logical job succeeded.
171
+ Active Job logging and notifications remain available. Rows store a versioned
172
+ Active Job envelope under the reserved `active_job` kind; Go can share the schema,
173
+ but Ruby must execute these jobs. Use native River kinds for cross-language jobs.
174
+
175
+ Retry enqueueing and predecessor finalization are not atomic. Crashes can cause
176
+ duplicates; jobs must remain idempotent. Rails' executor/reloader wraps each work
177
+ attempt and periodic constructor, cleaning context and connections. Active Job
178
+ classes are resolved per execution. Restart workers when changing native River
179
+ worker/plugin registrations or periodic configuration; these retain Ruby objects.
180
+
181
+ ## Testing
182
+
183
+ Keep Rails' `:test` adapter and `ActiveJob::TestHelper` for ordinary application
184
+ tests. Use `:river` and a migrated isolated database for persistence/runtime
185
+ integration tests. Disable transactional fixtures for threaded worker tests.
186
+ The repository's `make test` includes this gem's PostgreSQL and SQLite tests.
187
+ `RIVER_REQUIRE_DATABASES=1 make test` makes missing PostgreSQL an error.
188
+
189
+ Outside a Rails app, instantiate `ActiveJob::QueueAdapters::RiverAdapter.new(client:)`
190
+ and register `River::Rails::Worker` on your consuming River client. Rails-specific
191
+ boot, configuration, and execution wrapping are then your responsibility.
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module QueueAdapters
5
+ # Persists Active Job envelopes using the application's River client.
6
+ class RiverAdapter < AbstractAdapter
7
+ # An explicit client also allows using the adapter without a Rails app.
8
+ def initialize(client: nil)
9
+ @client = client
10
+ end
11
+
12
+ # Inserts an immediate Active Job delivery.
13
+ def enqueue(job)
14
+ enqueue_at(job, nil)
15
+ end
16
+
17
+ # Inserts the whole batch atomically and assigns provider IDs on success.
18
+ def enqueue_all(jobs)
19
+ results = client.insert_many(jobs.map { |job| params(job, job.scheduled_at) })
20
+ jobs.zip(results).each do |job, result|
21
+ job.provider_job_id = result.job.id.to_s
22
+ job.successfully_enqueued = true
23
+ record_retry(job)
24
+ end
25
+
26
+ results.length
27
+ end
28
+
29
+ # Inserts a delivery scheduled at an epoch timestamp (nil means now).
30
+ def enqueue_at(job, timestamp)
31
+ insertion = params(job, timestamp && Time.at(timestamp).utc)
32
+ result = client.insert(insertion.args, insert_opts: insertion.insert_opts)
33
+ job.provider_job_id = result.job.id.to_s
34
+ record_retry(job)
35
+ result
36
+ end
37
+
38
+ # Rails 7.2 adapter default: preserve same-connection atomic insertion.
39
+ def enqueue_after_transaction_commit? = false
40
+
41
+ private def client
42
+ @client || ::Rails.application.config.river.client
43
+ end
44
+
45
+ private def params(job, scheduled_at)
46
+ priority = job.priority
47
+ valid_priority = priority.nil? || (priority.is_a?(Integer) && (1..4).cover?(priority))
48
+ unless valid_priority
49
+ raise ArgumentError, "River Active Job priority must be nil or an integer from 1 to 4"
50
+ end
51
+
52
+ River::InsertManyParams.new(
53
+ River::JobArgsHash.new("active_job", {"job" => job.serialize, "version" => 1}),
54
+ max_attempts: 25, priority: priority || 1,
55
+ queue: job.queue_name, scheduled_at: scheduled_at
56
+ )
57
+ end
58
+
59
+ private def record_retry(job)
60
+ current = ActiveSupport::IsolatedExecutionState[:river_active_job]
61
+ if current && current.args.fetch("job").fetch("job_id") == job.job_id
62
+ current.update_metadata("active_job_outcome" => "retried", "active_job_retry_id" => job.provider_job_id)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module River
6
+ module Generators
7
+ # Installs configuration and the explicitly started worker entry point.
8
+ class InstallGenerator < ::Rails::Generators::Base
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ def install
12
+ copy_file "river.rb", "config/initializers/river.rb"
13
+ copy_file "jobs", "bin/jobs"
14
+ chmod "bin/jobs", 0o755
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../config/environment"
5
+ require "riverqueue-rails"
6
+
7
+ abort "Usage: bin/jobs start" unless ARGV == ["start"]
8
+ exit River::Rails::Runner.start
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.configure do
4
+ # Optional: select an abstract connection class by name, resolved after boot.
5
+ # config.river.connection_class = "ApplicationRecord"
6
+ config.active_job.queue_adapter = :river unless Rails.env.test?
7
+
8
+ config.river.configure do
9
+ River::Config.new(
10
+ job_timeout: 300,
11
+ logger: Rails.logger,
12
+ queues: {default: 10, mailers: 5}
13
+ )
14
+ end
15
+ end
16
+
17
+ # For atomic enqueueing on the same Active Record connection, set
18
+ # self.enqueue_after_transaction_commit = false in ApplicationJob (Rails 8.x).
19
+ # Explicit after-commit deferral is respected, but is not an atomic SQL write.
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module River
4
+ module Rails
5
+ # Application-owned configuration and per-process insertion client.
6
+ class Configuration
7
+ # Seconds allowed for graceful termination before attempts are interrupted.
8
+ attr_accessor :stop_timeout
9
+
10
+ def initialize
11
+ @connection_class = "ActiveRecord::Base"
12
+ @factory = -> { River::Config.new(logger: ::Rails.logger, queues: {"default" => 10}) }
13
+ @mutex = Mutex.new
14
+ @pid = Process.pid
15
+ @stop_timeout = 30
16
+ end
17
+
18
+ # Builds a consumer. Called after Rails boot, never in a web initializer.
19
+ def build_client
20
+ core = @factory.call
21
+ workers = River::Workers.new
22
+ core.workers.kinds.each { |kind| workers.add(kind, core.workers.fetch(kind)) }
23
+ workers.add(Worker)
24
+ periodic = core.periodic_jobs.map do |job|
25
+ River::PeriodicJob.new(id: job.id,
26
+ constructor: -> { ::Rails.application.reloader.wrap { job.constructor.call } },
27
+ run_on_start: job.run_on_start, schedule: job.schedule)
28
+ end
29
+
30
+ River::Client.new(build_driver,
31
+ config: core.with(periodic_jobs: periodic, plugins: [ExecutionPlugin.new] + core.plugins, workers: workers))
32
+ end
33
+
34
+ # Builds a driver for the configured connection class, including migrations.
35
+ def build_driver
36
+ River::Driver::ActiveRecord.new(connection_class: connection_class)
37
+ end
38
+
39
+ # Returns a lazy insertion-only client for this process.
40
+ def client
41
+ if @pid != Process.pid
42
+ @client = nil
43
+ @mutex = Mutex.new
44
+ @pid = Process.pid
45
+ end
46
+
47
+ @mutex.synchronize do
48
+ klass = connection_class
49
+ @client = nil if @client && !@client.driver.connection_class.equal?(klass)
50
+
51
+ @client ||= River::Client.new(River::Driver::ActiveRecord.new(connection_class: klass),
52
+ config: @factory.call.with(periodic_jobs: [], queues: {}))
53
+ end
54
+ end
55
+
56
+ # Resolves names lazily so Rails can reload application connection classes.
57
+ def connection_class
58
+ @connection_class.is_a?(String) ? @connection_class.constantize : @connection_class
59
+ end
60
+
61
+ # Selects an abstract Active Record class or its name. Prefer a name in
62
+ # initializers to avoid retaining a reloadable class object.
63
+ def connection_class=(value)
64
+ @mutex.synchronize do
65
+ @connection_class = value
66
+ @client = nil
67
+ end
68
+ end
69
+
70
+ # Supplies a block returning River::Config after application boot.
71
+ def configure(&block)
72
+ raise ArgumentError, "configuration block required" unless block
73
+
74
+ @factory = block
75
+ @client = nil
76
+ end
77
+ end
78
+
79
+ # Wraps each attempt in Rails' reload-safe execution boundary.
80
+ class ExecutionPlugin
81
+ def work(_job, operation)
82
+ ::Rails.application.reloader.wrap { operation.call }
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+
5
+ module River
6
+ module Rails
7
+ class Railtie < ::Rails::Railtie
8
+ config.river = Configuration.new
9
+
10
+ rake_tasks do
11
+ namespace :river do
12
+ desc "Apply River's canonical database migrations"
13
+ task migrate: :environment do
14
+ River::Migrator.new(::Rails.application.config.river.build_driver).migrate
15
+ end
16
+
17
+ desc "Show River migration status"
18
+ task status: :environment do
19
+ River::Migrator.new(::Rails.application.config.river.build_driver).status.each do |migration|
20
+ puts "#{migration.applied ? "applied" : "pending"} #{migration.version} #{migration.name}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module River
4
+ module Rails
5
+ # Runs one worker process; an external supervisor owns process restarts.
6
+ class Runner
7
+ # Boot Rails before calling. TERM/INT stop fetching and drain active jobs.
8
+ def self.start(out: $stdout, stop_timeout: nil)
9
+ config = ::Rails.application.config.river
10
+ River::WorkerRunner.new(config.build_client, out: out,
11
+ stop_timeout: stop_timeout || config.stop_timeout).run
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module River
4
+ module Rails
5
+ # Keep River's control-flow exceptions out of Active Job retry/discard
6
+ # handlers, including broad retry_on StandardError declarations.
7
+ module ExecutionControl
8
+ def rescue_with_handler(exception)
9
+ if ActiveSupport::IsolatedExecutionState[:river_active_job] &&
10
+ [River::ClientRuntime::Interrupted, River::JobCancelError, River::JobSnoozeError].any? { |type| exception.is_a?(type) }
11
+ raise exception
12
+ end
13
+
14
+ super
15
+ end
16
+ end
17
+
18
+ ActiveJob::Base.prepend(ExecutionControl)
19
+
20
+ # Dispatches serialized jobs through Active Job's own execution machinery.
21
+ class Worker
22
+ def self.kind = "active_job"
23
+
24
+ # Active Job owns retries for reported errors; River still rescues crashes.
25
+ def retry?(_job, _error) = false
26
+
27
+ def work(job)
28
+ previous = ActiveSupport::IsolatedExecutionState[:river_active_job]
29
+ ActiveSupport::IsolatedExecutionState[:river_active_job] = job
30
+ raise ArgumentError, "Unsupported Active Job envelope version" unless job.args.fetch("version") == 1
31
+
32
+ payload = job.args.fetch("job").merge("provider_job_id" => job.id.to_s)
33
+ ActiveJob::Base.execute(payload)
34
+ ensure
35
+ ActiveSupport::IsolatedExecutionState[:river_active_job] = previous
36
+ end
37
+ end
38
+
39
+ ActiveSupport::Notifications.subscribe("discard.active_job") do |*, payload|
40
+ job = ActiveSupport::IsolatedExecutionState[:river_active_job]
41
+ if job && payload.fetch(:job).job_id == job.args.fetch("job").fetch("job_id")
42
+ job.update_metadata("active_job_outcome" => "discarded")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_job"
4
+ require "riverqueue-activerecord"
5
+ require_relative "river/rails/configuration"
6
+ require_relative "river/rails/worker"
7
+ require_relative "river/rails/runner"
8
+ require_relative "active_job/queue_adapters/river_adapter"
9
+ require_relative "river/rails/railtie"
metadata CHANGED
@@ -1,28 +1,87 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riverqueue-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0.reserved
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
- - River Software
7
+ - Blake Gentry
8
+ - Brandur Leach
8
9
  bindir: bin
9
10
  cert_chain: []
10
11
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
12
- description: Reserved for Rails and Active Job integration for River. This prerelease
13
- contains documentation only, no implementation, and is not usable in applications.
14
- email: support@riverqueue.com
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activejob
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '8.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '7.2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '8.2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: railties
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '7.2'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '8.2'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '7.2'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '8.2'
53
+ - !ruby/object:Gem::Dependency
54
+ name: riverqueue-activerecord
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '='
58
+ - !ruby/object:Gem::Version
59
+ version: 0.12.0
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '='
65
+ - !ruby/object:Gem::Version
66
+ version: 0.12.0
15
67
  executables: []
16
68
  extensions: []
17
69
  extra_rdoc_files: []
18
70
  files:
19
71
  - README.md
72
+ - lib/active_job/queue_adapters/river_adapter.rb
73
+ - lib/generators/river/install_generator.rb
74
+ - lib/generators/river/templates/jobs
75
+ - lib/generators/river/templates/river.rb
76
+ - lib/river/rails/configuration.rb
77
+ - lib/river/rails/railtie.rb
78
+ - lib/river/rails/runner.rb
79
+ - lib/river/rails/worker.rb
80
+ - lib/riverqueue-rails.rb
20
81
  homepage: https://riverqueue.com
21
82
  licenses:
22
83
  - MPL-2.0
23
- metadata:
24
- allowed_push_host: https://rubygems.org
25
- rubygems_mfa_required: 'true'
84
+ metadata: {}
26
85
  rdoc_options: []
27
86
  require_paths:
28
87
  - lib
@@ -30,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
30
89
  requirements:
31
90
  - - ">="
32
91
  - !ruby/object:Gem::Version
33
- version: '0'
92
+ version: '3.2'
34
93
  required_rubygems_version: !ruby/object:Gem::Requirement
35
94
  requirements:
36
95
  - - ">="
@@ -39,5 +98,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
98
  requirements: []
40
99
  rubygems_version: 4.0.9
41
100
  specification_version: 4
42
- summary: Official name-reservation placeholder for riverqueue-rails.
101
+ summary: Active Job and Rails integration for River.
43
102
  test_files: []