Comparing Ruby Objects based on their instance variables

Compare 2 objects without having to repeat all their variables and potentially miss something, only thing dangerous is adding something like a inline method cache, which would then break equality.

def ==(other)
  self.class == other.class && instance_variables.all? do |i|
    instance_variable_get(i) == other.instance_variable_get(i)

Rails 5.1 do not compile asset in test vs asset is not present in the asset pipeline

We don’t want to compile assets during test runs, since that is slow, but we also don’t want the asset pipeline to fail because assets are missing.

This will not work if you plan on doing javascript integration tests, but everything else should work fine.

Rails 5.1 added a flag for this which prints deprecations and will be removed in rails 5.2 so that is not a elegant solution either.

config.assets.unknown_asset_fallback = true

So we are now using this fix to fake assets being available!:

# config/environments/test.rb
# make our tests fast by avoiding asset compilation
# but do not raise when assets are not compiled either
Rails.application.config.assets.compile = false
Sprockets::Rails::Helper.prepend( do
  def resolve_asset_path(path, *)
    super || path

Ruby on Kubernetes: Newrelic

– Report each environment as separate app
– Report namespace so we can track down where misbehaving pods live

    # config/application.rb (not in initializers)
    if ENV['POD_NAMESPACE'] # on kubernetes
      # report each env into a separate project
      NewRelic::Agent::Configuration::Manager.class_eval do
        undef app_names
        def app_names
          name = ENV.fetch('NEW_RELIC_APP_NAME')
          name += " #{Rails.env}" unless Rails.env.production?

      # report namespace so we can track down where a troublesome pod lives
      # newrelic_rpm 3.18.0+ has a NEW_RELIC_PROCESS_HOST_DISPLAY_NAME setting which is supposed to do that, but did not work.
      class << NewRelic::Agent::Hostname
        def get

Ruby on Kubernetes: Airbrake Exception Reporting

For simple apps reporting exceptions is simple, but not obvious … have a snippet 🙂

– report context so it’s easy to find out where a bug happened
– do not report when user opened a session manually (tty)
– do not report regular system exit

# report any errors to airbrake, kubernetes takes care of restarting
require 'airbrake-ruby'
Airbrake.configure do |config|
  config.project_id = 1234567
  config.project_key = ENV.fetch('AIRBRAKE_API_KEY')
  config.environment = ENV.fetch('RAILS_ENV')
  config.ignore_environments = [:test, :development]
  config.logger =
at_exit do
  context = ['POD_NAME', 'POD_NAMESPACE', 'TAG'].
    map { |k| [k.downcase, ENV[k]] }.to_h
  Airbrake.notify_sync($!, context) if $! && !$stdout.tty?

Ruby on Kubernetes: Memory GC OOMKilled

Ruby seems to always grow and then hit the memory limit … which triggers a SIGKILL … which means shutdown without cleanup.
This snippet helps to keep memory low and softly kills the process when memory gets to close to the limit.

# run GC periodically to reduce memory and report to airbrake if we run out (instead of kubernetes silently failing) do
  loop do
    sleep 60
    used = Integer('/sys/fs/cgroup/memory/memory.usage_in_bytes')) / 1024 / 1024
    max = Integer(`cat /sys/fs/cgroup/memory/memory.stat | grep hierarchical_memory_limit`.split.last) / 1024 / 1024
    puts "Ram: #{used}M / #{max}M"
    raise "Out of memory #{used}/#{max}" if used + 5 >= max

A fun little tool that might help too: preoomkiller