From 1fa36b5b9f0fb0aa1435c526fc9e947b7eaf3785 Mon Sep 17 00:00:00 2001 From: Jonathan Rochkind Date: Thu, 22 Jun 2023 11:53:35 -0400 Subject: [PATCH] Tweak config of mem_cache_store used for rack-attack With context from the memcachier heroku docs. We are attempting to reduce/eliminate all the errors we get for memcached being unavailable. We add a 'pool', recommended there for use with multi-thread puma, which we are using. We also, while looking at the config, go back on our decision to eliminate retry after error, instead enabling a pretty small 80ms retry delay. Ref #2143, trying harder with memcache before giving up --- config/environments/production.rb | 35 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index b8783b0fa..3f29abeaf 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -77,7 +77,7 @@ # has some standard Rails code that lets you turn it on in dev with in-memory store, # with `./bin/rails dev:cache` toggle. # - # On heroku we try to set up either memcachdcloud or memcachier, in that order, + # On heroku we try to set up either memcachier or memcachedcloud, in that order, # depending on what env variables are defined. # # We tune the timeouts to give up really quickly -- we don't want the server @@ -85,25 +85,36 @@ # it on every request. It's just a cache; give up if it's slow! # # https://github.com/petergoldstein/dalli/blob/5588d98f79eb04a9abcaeeff3263e08f93468b30/lib/dalli/protocol/connection_manager.rb + # + # We use configuration including 'pool' suggested by memcachier docs, which requires + # connection_pool gem to be available to work. + # + require 'connection_pool' # needed for dalli pool_size to work + + mem_cache_store_config = { + :socket_timeout => (ENV["MEMCACHE_TIMEOUT"] || 0.15).to_f, # default is maybe 1 second? + :socket_failure_delay => 0.08, # retry failures with fairly quick 80ms delay + :failover => true, # don't think it matters unless provider gives us more than one hostname + :pool_size => ENV.fetch("RAILS_MAX_THREADS") { 5 }, # should match puma, suggested by memcachier docs + :pool_timeout => (ENV["MEMCACHE_TIMEOUT"] || 0.15).to_f # don't wait too long for a connection from pool either + } + if ENV["MEMCACHIER_SERVERS"] - # https://devcenter.heroku.com/articles/memcachier#rails - config.cache_store = :mem_cache_store, ENV["MEMCACHIER_SERVERS"].split(","), { + # https://devcenter.heroku.com/articles/memcachier#ruby-puma-webserver + config.cache_store = :mem_cache_store, ENV["MEMCACHIER_SERVERS"].split(","), mem_cache_store_config.merge({ :username => ENV["MEMCACHIER_USERNAME"], - :password => ENV["MEMCACHIER_PASSWORD"], - :socket_timeout => (ENV["MEMCACHE_TIMEOUT"] || 0.15).to_f, # default was 0.5 - :socket_failure_delay => false # don't retry failures - } + :password => ENV["MEMCACHIER_PASSWORD"] + }) elsif ENV["MEMCACHEDCLOUD_SERVERS"] # https://devcenter.heroku.com/articles/memcachedcloud#using-memcached-from-ruby - config.cache_store = :mem_cache_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(','), { + config.cache_store = :mem_cache_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(','), mem_cache_store_config.merge({ :username => ENV["MEMCACHEDCLOUD_USERNAME"], - :password => ENV["MEMCACHEDCLOUD_PASSWORD"], - :socket_timeout => (ENV["MEMCACHE_TIMEOUT"] || 0.15).to_f, # default was 1 - :socket_failure_delay => false # don't retry failures - } + :password => ENV["MEMCACHEDCLOUD_PASSWORD"] + }) end + # Use a real queuing backend for Active Job (and separate queues per environment) config.active_job.queue_adapter = :resque