Daniel Viglione
Daniel Viglione

Reputation: 9407

When block finishes executing, ruby interpreter does not continue to next instruction

I have the following execution sequence. When import gets called, it in turn invokes perform_tasks and then goes into a redis subscribe loop on on_complete:

class Record < ActiveRecord::Base
  def self.import(params)
    peform_tasks params[:record]
    on_complete
  end

  def self.peform_tasks(record_params)
    record_params.each do |param|
      AddressWorker.perform_async param
    end
  end

  def self.on_complete
    redis.subscribe('address_notifier') do |payload|
      on_post_execute payload
    end
    puts 'BUT WE NEVER GET HERE'
  end

  def self.on_post_execute(payload)
   puts 'Yes we get here'
  end
end

The problem is when the block finishes executing, and on_post_execute runs, execution does not leave the block. And we never get to the line:

puts 'BUT WE NEVER GET HERE'

Why don't we get to the line after the block?

Note that the use of redis.subscribe from the ruby redis gem should be irrelevant here, since I get to the block and it is a regular ruby block.

Upvotes: 0

Views: 80

Answers (1)

ActiveModel_Dirty
ActiveModel_Dirty

Reputation: 528

The use of redis.subscribe isn't exactly irrelevant here as you've noted.

This method is a loop that won't break until you unsubscribe. So, in this case I don't think you're actually exiting that block, hence your puts line wouldn't be executed.

  def self.on_complete
    redis.subscribe_with_timeout(5, 'address_notifier') do |payload|
      on_post_execute payload

      redis.unsubscribe
    end
    puts 'Should get here now'
  end

  def self.on_post_execute(payload)
    puts 'Yes we get here'
  end

Alternatively use subscribe_with_timeout:

  def self.on_complete
    redis.subscribe_with_timeout(5, 'address_notifier') do |payload|
      on_post_execute payload
    end
    puts 'Should get here now'
  end

  def self.on_post_execute(payload)
    puts 'Yes we get here'
  end

Upvotes: 2

Related Questions