Search code examples
ruby-on-railsrubyrakeactionmailerrake-task

Run mailer only after rake task is finished


I only want to run my mailer if my rake task is NOT running. If I run both the api gets throttled.

So I'm trying to define a variable in a method on my OrderMailer and just watch for a true value on that variable, but I can't seem to get it to work.

This is my code so far:

class OrderMailer < ActionMailer::Base
  default from: '[email protected]'
  attr_reader :sheet
  attr_accessor :amazon_api_is_free

def order_report
    Rails.logger.info"Is the api free? #{amazon_api_is_free}"
    sleep(30) until amazon_api_is_free
    shops = Shop.where(subscribed: true, setup: true)
    shops.each do |shop|
      @sheet = OrderReport.new(shop)
      @sheet.create_order_workbook
      # get_data_for_inside_email
      time = Time.now
      if File.exist?("problem_orders_#{shop.id}.xlsx")
        mail(to: "[email protected]", 
        subject: "FBA Shipping Report for #{time.strftime("%B %d")}").attachments["problem_orders_#{shop.id}.xlsx"] = File.read("problem_orders_#{shop.id}.xlsx")
        # mail(to: "[email protected]", subject: "FBA Shipping Report for #{time.strftime("%B %d")}")
      end
    end
  end

  def self.is_amazon_api_available
    @amazon_api_is_free
  end

And then my example rake task:

desc 'Passing the buck'
task :just_a_test => :environment do
  puts "testing"
  start
end

  def start
    not_available
    pp "From the rake is the api free? #{OrderMailer.is_amazon_api_available}"
    pp "making sure its running"
    sleep(20)
    available
  end

  def not_available
    is_amazon_api_available = false
  end

  def available
    is_amazon_api_available = true
  end

Solution

  • Unless you execute rake from inside the same Ruby machine as your mailer (which I doubt,) they do not share the environment, even if you were trying to use the global variable (setting local variables has zero effect at all in any case, even inside your last two methods in rake those are different variables.)

    What you need is to write .pid file and check it’s existence on the file system, or use any other external source of truth, like redis, or even DB.