Repository: rails/solid_queue (Ruby)

Issue:
Upgrading to 1.1.1 makes recurring job to fail
Ruby: 3.4.1
Rails: 8.0.1
`solid_queue` running as a plug_in
This simple recurring job fails:
```yaml
production:
  periodic_cleanup:
    class: CloseTripsJob
    queue: background
    schedule: every hour
```

with this error:
```console
10:48:03 web.1  | Invalid recurring tasks:
10:48:03 web.1  | - production: Schedule is not a supported recurring schedule, either command or class_name must be present
10:48:03 web.1  | Exiting...
10:48:07 web.1  | Detected Solid Queue has gone away, stopping Puma...
```

**EDIT: it only fails if the only environment declared is production and trying to run the app in development**


Discussion:
🤔  it seems that `CloseTripsJob` might not be defined? Does that exist? 
Same for me, I had remove the environment in order to boot solid queue.

See if this works:

```yaml
periodic_cleanup:
  class: CloseTripsJob
  queue: background
  schedule: every hour
```

> 🤔 it seems that `CloseTripsJob` might not be defined? Does that exist?

it started failing when upgraded to `1.1.1`, `1.1.0` works fine
Same issue for me. 
On examining Mission Control, my list of workers was empty. Reverting to `1.1.0` and things are back to normal.
To be clear, with 1.1.0, invalid recurring tasks would be silently ignored, leading to confusing situations where people didn't know why they weren't being run. With 1.1.1, these fail. If reverting to 1.1.0 works, fine, it might simply mean that they're ignored. 
@jnstq nothing has changed regarding the environment keys in `recurring.yml`. If you remove it and that works, it might be that the recurring tasks aren't being loaded at all. 
Oh, @max-chem-eng, I just realised that the recurring task failing for you is `production` 😕 That's very odd. Is this failing in `development` only? 
> To be clear, with 1.1.0, invalid recurring tasks would be silently ignored, leading to confusing situations where people didn't know why they weren't being run. With 1.1.1, these fail. If reverting to 1.1.0 works, fine, it might simply mean that they're ignored.

thanks for your input
with version 1.1.0 I can confirm that the recurring task is working just fine, if I update it to:
```yaml
development:
  periodic_cleanup:
    class: CloseTripsJob
    queue: background
    schedule: every second
```
I see it running without issues

If I update it to `1.1.1` it fails with the mentioned error:
```console
Invalid recurring tasks:
- production: Schedule is not a supported recurring schedule, either command or class_name must be present
```
regardless I run it as plug in or in its own terminal

**EDIT: it only fails if the only environment declared is production and trying to run the app in development**
In my case it's working fine in development, but the workers are failing in production once updating to 1.1.1. 

I reverted and then upgraded again in prod and still getting the same issue. 
Currently digging into why the workers are failing to boot on prod.
Right ok, I've dug into the failure trying to manually kick off bin/jobs in a container on prod; in my case the error was:
```
> Solid Queue is configured to use 3 threads but the database connection pool is 2. Increase it in `config/database.yml
```
Increasing the `RAILS_MAX_THREADS` has brought prod back up to life.

I can see this check was added to 1.1.1, so was the issue in my case:

https://github.com/rails/solid_queue/blob/e0921d28c1a21e3595d624b06a900e678059c7c4/lib/solid_queue/configuration.rb#L78-L83
thanks!
Ok, just released version 1.1.2 with a fix for the recurring configuration when not all environments are defined. Sorry about that! 
Hello, after updating I noticed the following raises an error:

```yaml
development: 
# nothing
```

```ruby
/Users/david/.local/share/mise/installs/ruby/3.4.0/lib/ruby/gems/3.4.0+1/gems/solid_queue-1.1.2/lib/solid_queue/configuration.rb:144:in 'block in SolidQueue::Configuration#recurring_tasks': undefined method 'has_key?' for nil (NoMethodError)

          RecurringTask.from_configuration(id, **options) if options.has_key?(:schedule)
                                                                    ^^^^^^^^^
        from /Users/david/.local/share/mise/installs/ruby/3.4.0/lib/ruby/gems/3.4.0+1/gems/solid_queue-1.1.2/lib/solid_queue/configuration.rb:143:in 'Hash#each'
        from /Users/david/.local/share/mise/installs/ruby/3.4.0/lib/ruby/gems/3.4.0+1/gems/solid_queue-1.1.2/lib/solid_queue/configuration.rb:143:in 'Enumerable#map'
        from /Users/david/.local/share/mise/installs/ruby/3.4.0/lib/ruby/gems/3.4.0+1/gems/solid_queue-1.1.2/lib/solid_queue/configuration.rb:143:in 'SolidQueue::Configuration#recurring_tasks'
```

Removing `development:` works around this, but if the yaml is valid then it probably should not fail
Oops, yes! I'll fix that. Agh. So sorry @dgmora! 
Fixed in https://github.com/rails/solid_queue/pull/475



Patch:
diff --git a/lib/solid_queue/configuration.rb b/lib/solid_queue/configuration.rb
index bd238dcc..c9e44901 100644
--- a/lib/solid_queue/configuration.rb
+++ b/lib/solid_queue/configuration.rb
@@ -141,8 +141,8 @@ def dispatchers_options
 
       def recurring_tasks
         @recurring_tasks ||= recurring_tasks_config.map do |id, options|
-          RecurringTask.from_configuration(id, **options)
-        end
+          RecurringTask.from_configuration(id, **options) if options.has_key?(:schedule)
+        end.compact
       end
 
       def processes_config


Test patch:
diff --git a/test/dummy/config/recurring_with_production_only.yml b/test/dummy/config/recurring_with_production_only.yml
new file mode 100644
index 00000000..6d71dc1e
--- /dev/null
+++ b/test/dummy/config/recurring_with_production_only.yml
@@ -0,0 +1,6 @@
+production:
+  periodic_store_result:
+    class: StoreResultJob
+    queue: default
+    args: [ 42, { status: "custom_status" } ]
+    schedule: every second
diff --git a/test/unit/configuration_test.rb b/test/unit/configuration_test.rb
index 87b8726e..11653c25 100644
--- a/test/unit/configuration_test.rb
+++ b/test/unit/configuration_test.rb
@@ -99,6 +99,10 @@ class ConfigurationTest < ActiveSupport::TestCase
     assert SolidQueue::Configuration.new(recurring_schedule_file: config_file_path(:empty_recurring)).valid?
     assert SolidQueue::Configuration.new(skip_recurring: true).valid?
 
+    configuration = SolidQueue::Configuration.new(recurring_schedule_file: config_file_path(:recurring_with_production_only))
+    assert configuration.valid?
+    assert_processes configuration, :scheduler, 0
+
     # No processes
     configuration = SolidQueue::Configuration.new(skip_recurring: true, dispatchers: [], workers: [])
     assert_not configuration.valid?