Repository: rails/solid_queue (Ruby)

Issue:
Add environment variable to turn off recurring jobs
Hello, thank you for Solid Queue!

We're in the process of migrating an older app form Sidekiq to Solid Queue. We're using Heroku Review apps, and we don't want any recurring jobs to run there. It would be nice if we could completely skip recurring tasks by setting an environment variable.

In searching for a workaround, I found that I could make it work if I added this line to `bin/jobs`:

```diff
  require_relative "../config/environment"
  require "solid_queue/cli"

+ ARGV << "--skip-recurring" if ENV["SOLID_QUEUE_SKIP_RECURRING"]

  SolidQueue::Cli.start(ARGV)
```

(This is of course not the _right_ way to add this, but as a workaround, it's okay.)

Is an option like this something you'd be interested in? I could try to implement it properly, similar to how the `SOLID_QUEUE_RECURRING_SCHEDULE` environment variable works, and send a PR.

Thank you again!


Discussion:
Hey @daniel-nerdgeschoss, sure thing! Feel free to open a pull request for this. 

I wonder, however, whether it'd be sufficient for you to call `bin/jobs` like this: 
```
bin/jobs --skip-recurring
```
Or do you really need the environment variable rather than the command-line option? 
Hey @rosa, thanks for the positive reply! I will take a look when I find the time.

Sadly, adding the flag is not quite sufficient because in Heroku, you can only set one `Procfile` for _all_ environments, which looks like this:

```
web: bin/rails serve
worker: bin/jobs
release: bin/rails db:migrate
```

This file is used for Production, Staging, and Review Apps – so the flag would either always be set, or never. The best way to be environment specific in Heroku is … to use environment variables. :D 



Patch:
diff --git a/README.md b/README.md
index c7a2ef2c..9c3c44c7 100644
--- a/README.md
+++ b/README.md
@@ -192,6 +192,8 @@ By default, Solid Queue will try to find your configuration under `config/queue.
 bin/jobs -c config/calendar.yml
 ```
 
+You can also skip all recurring tasks by setting the environment variable `SOLID_QUEUE_SKIP_RECURRING=true`. This is useful for environments like staging, review apps, or development where you don't want any recurring jobs to run. This is equivalent to using the `--skip-recurring` option with `bin/jobs`.
+
 This is what this configuration looks like:
 
 ```yml
@@ -571,6 +573,8 @@ Solid Queue supports defining recurring tasks that run at specific times in the
 bin/jobs --recurring_schedule_file=config/schedule.yml
 ```
 
+You can completely disable recurring tasks by setting the environment variable `SOLID_QUEUE_SKIP_RECURRING=true` or by using the `--skip-recurring` option with `bin/jobs`.
+
 The configuration itself looks like this:
 
 ```yml
diff --git a/lib/solid_queue/cli.rb b/lib/solid_queue/cli.rb
index 33d2588b..404c7e72 100644
--- a/lib/solid_queue/cli.rb
+++ b/lib/solid_queue/cli.rb
@@ -13,7 +13,8 @@ class Cli < Thor
       banner: "SOLID_QUEUE_RECURRING_SCHEDULE"
 
     class_option :skip_recurring, type: :boolean, default: false,
-      desc: "Whether to skip recurring tasks scheduling"
+      desc: "Whether to skip recurring tasks scheduling",
+      banner: "SOLID_QUEUE_SKIP_RECURRING"
 
     def self.exit_on_failure?
       true
diff --git a/lib/solid_queue/configuration.rb b/lib/solid_queue/configuration.rb
index ba13f0f4..a002b41d 100644
--- a/lib/solid_queue/configuration.rb
+++ b/lib/solid_queue/configuration.rb
@@ -88,7 +88,7 @@ def default_options
           recurring_schedule_file: Rails.root.join(ENV["SOLID_QUEUE_RECURRING_SCHEDULE"] || DEFAULT_RECURRING_SCHEDULE_FILE_PATH),
           only_work: false,
           only_dispatch: false,
-          skip_recurring: false
+          skip_recurring: ActiveModel::Type::Boolean.new.cast(ENV["SOLID_QUEUE_SKIP_RECURRING"])
         }
       end
 


Test patch:
diff --git a/test/test_helpers/configuration_test_helper.rb b/test/test_helpers/configuration_test_helper.rb
index 24b95e6b..fa3a402a 100644
--- a/test/test_helpers/configuration_test_helper.rb
+++ b/test/test_helpers/configuration_test_helper.rb
@@ -4,4 +4,18 @@ module ConfigurationTestHelper
   def config_file_path(name)
     Rails.root.join("config/#{name}.yml")
   end
+
+  def with_env(env_vars)
+    original_values = {}
+    env_vars.each do |key, value|
+      original_values[key] = ENV[key]
+      ENV[key] = value
+    end
+
+    yield
+  ensure
+    original_values.each do |key, value|
+      ENV[key] = value
+    end
+  end
 end
diff --git a/test/unit/configuration_test.rb b/test/unit/configuration_test.rb
index 68a693e3..2ccaa728 100644
--- a/test/unit/configuration_test.rb
+++ b/test/unit/configuration_test.rb
@@ -85,6 +85,30 @@ class ConfigurationTest < ActiveSupport::TestCase
     assert_processes configuration, :dispatcher, 1, polling_interval: 0.1, recurring_tasks: nil
   end
 
+  test "skip recurring tasks when SOLID_QUEUE_SKIP_RECURRING environment variable is set" do
+    with_env("SOLID_QUEUE_SKIP_RECURRING" => "true") do
+      configuration = SolidQueue::Configuration.new(dispatchers: [ { polling_interval: 0.1 } ])
+      assert_processes configuration, :dispatcher, 1, polling_interval: 0.1
+      assert_processes configuration, :scheduler, 0
+    end
+  end
+
+  test "include recurring tasks when SOLID_QUEUE_SKIP_RECURRING environment variable is false" do
+    with_env("SOLID_QUEUE_SKIP_RECURRING" => "false") do
+      configuration = SolidQueue::Configuration.new(dispatchers: [ { polling_interval: 0.1 } ])
+      assert_processes configuration, :dispatcher, 1, polling_interval: 0.1
+      assert_processes configuration, :scheduler, 1
+    end
+  end
+
+  test "include recurring tasks when SOLID_QUEUE_SKIP_RECURRING environment variable is not set" do
+    with_env("SOLID_QUEUE_SKIP_RECURRING" => nil) do
+      configuration = SolidQueue::Configuration.new(dispatchers: [ { polling_interval: 0.1 } ])
+      assert_processes configuration, :dispatcher, 1, polling_interval: 0.1
+      assert_processes configuration, :scheduler, 1
+    end
+  end
+
   test "validate configuration" do
     # Valid and invalid recurring tasks
     configuration = SolidQueue::Configuration.new(recurring_schedule_file: config_file_path(:recurring_with_invalid))