Resque问题:在Job内部调用#perform_later无法触发子Job执行
Hey there, let's break down why your child jobs aren't running. Looking at the code snippet you shared, the first thing that stands out is that your start_events method is iterating over events and their connectors—but there’s no actual code triggering a child job in that loop. That’s probably the biggest missing piece right now.
Let’s walk through the most likely fixes and checks step by step:
Add code to enqueue your child jobs
Right now, you’re looping through connectors but not telling Rails to run a job for each one. You need to explicitly call your child job’sperform_later(for async execution) orperform_now(for synchronous execution) method inside the loop. For example:private def start_events events = Events.all events.each do |event| event.connectors.each do |con| # Replace with your actual child job class name ChildConnectorJob.perform_later(con.id) end end endWithout this line, your parent job just loops through records and does nothing to trigger the work you want.
Verify your child job is properly defined
Make sure your child job follows the Active Job structure:class ChildConnectorJob < ApplicationJob queue_as :default # Or a specific queue name def perform(connector_id) connector = Connector.find(connector_id) # Add your actual processing logic here end endIf the child job doesn’t inherit from
ApplicationJob, lacks aperformmethod, or has syntax errors, it won’t execute even if enqueued.Check your queue processor and configuration
- If you’re using a tool like Sidekiq or Delayed Job, ensure the processor is running (e.g.,
bundle exec sidekiqfor Sidekiq). If it’s stopped, jobs will sit in the queue indefinitely. - If your child job uses a custom queue (via
queue_as :custom_queue), make sure your processor is listening to that queue. For Sidekiq, that means starting it withbundle exec sidekiq -q default -q custom_queue. - In development, if you’re using the default
asyncadapter, note that it runs jobs in the same process as your server—restarting the server will clear pending jobs, and long-running parent jobs might block child job execution. Switching to a dedicated processor like Sidekiq for testing is better.
- If you’re using a tool like Sidekiq or Delayed Job, ensure the processor is running (e.g.,
Catch silent failures in the parent job
If an exception occurs while iterating (e.g., a missing event/connector, database error), the parent job might stop early without triggering all child jobs. Add logging and error handling to debug this:private def start_events events = Events.all events.each do |event| event.connectors.each do |con| begin ChildConnectorJob.perform_later(con.id) Rails.logger.info "Enqueued child job for connector #{con.id}" rescue => e Rails.logger.error "Failed to enqueue job for connector #{con.id}: #{e.message}" end end end endAlso, check your logs to confirm the parent job is running fully—you should see both
TriggerJob before_performandTriggerJob after_performprinted.Rule out hook interference
Youraround_performblock looks correct, but double-check if there are global job hooks (e.g., inApplicationJob) or callbacks that might be blocking child job enqueuing or execution.
Start with the first check—adding the child job enqueue line is almost certainly the fix you need right now. If that’s already in place, work through the other steps while checking logs to narrow down where things are getting stuck.
内容的提问来源于stack exchange,提问作者Peter Evjan

