Rails: Quarterly automation fails with no error

35 views Asked by At

I'm the maintenance developer for an inventory management site. There's a quarterly process that fails for about 10-20% of our customers but yields no error message or failure output of any sort. I've traced the code from trigger to model and found nothing that stands out as well as run code/tests by hand and can't find any loose ends to pull on.

I can share chunks of code as requested, but here is the class that handles the part that's failing. The process is one that looks at a company's history and generates min/max inventory recommended changes.

class ProductInventoryAdjustment < ActiveRecord::Base
  belongs_to :product
  has_many   :notifications, as: :target, dependent: :destroy

  validates :product_id,    presence: true
  validates :max_inventory, presence: true
  validates :min_inventory, presence: true
  validates :state,         presence: true

  def self.create_scheduled_adjustments
    if is_annual?
      schedules_to_adjust = ["quarterly", "semiannual", "annual"]
    elsif is_semiannual?
      schedules_to_adjust = ["quarterly", "semiannual"]
    elsif is_quarter?
      schedules_to_adjust = ["quarterly"]
    else
      # This method runs monthly, so on off months we
      # catch here and return.
      return
    end

    companies = Company.where(inventory_adjustment_schedule: schedules_to_adjust)
    companies.each { |c| create_adjustments_for_company(c) }
  end

  def self.create_adjustments_for_company(company)
    company.products.each { |p| create_adjustments_for_product(p) }
    company.users.each do |user|
      Notification.create!({
        user: user,
        notification_type: Notification::INVENTORY_ADJUSTMENT,
        target: company
      })
    end
  end

  def self.create_adjustments_for_product(product)
    return false if !product.is_old_enough_to_calculate_used_inventory?

    average_inventory_used_per_week = product.average_inventory_used_per_week
    max_inventory = (average_inventory_used_per_week * 4).ceil
    min_inventory = (average_inventory_used_per_week * 2).round

    max_inventory = 1 if max_inventory < 1

    product.inventory_adjustments.create(
      max_inventory: max_inventory,
      min_inventory: min_inventory
    )
  end

  private

    def self.is_quarter?
      [1,4,7,10].include? Date.today.month
    end

    def self.is_semiannual?
      [1,7].include? Date.today.month
    end

    def self.is_annual?
      [1].include? Date.today.month
    end

end

100% of our clients do this quarterly and I've checked the database directly and all the relevant clients are scooped up when the code is run manually. As far as I can tell, there's really no rhyme or reason as to which clients pass/fail. The only exception is the fact that older clients tend to fail less, but there's no "hard cutoff" that passes/fails.

1

There are 1 answers

0
BHollan On

I teamed up with another engineer and we figured out that the machine was running out of memory during the calculation due to having to instantiate so many things.

Once the code was refactored to take this into account, it was fine.