perf improvements for traffic intensity
TrafficHelper's hot-path intensity does a single select for a single row and loads the value rather than instantiate an ActiveRecord object. Updating the intensity has moved entirely to the cron job to prevent dogpiling, and does three upserts instead of select + upsert. No more hassling around with different keys for intensity when we only use the latest value.
This commit is contained in:
parent
c98648933b
commit
e334ae41b4
|
@ -29,19 +29,15 @@ module TrafficHelper
|
|||
result.to_a.first
|
||||
end
|
||||
|
||||
def self.cached_traffic_range
|
||||
low, high = nil, nil
|
||||
low = Keystore.readthrough_cache('traffic:low') do
|
||||
low, high = traffic_range
|
||||
Keystore.put('traffic:high', high)
|
||||
low
|
||||
end
|
||||
high ||= Keystore.value_for('traffic:high')
|
||||
[low, high]
|
||||
def self.cache_traffic!
|
||||
low, high = self.traffic_range
|
||||
Keystore.put('traffic:low', low)
|
||||
Keystore.put('traffic:high', high)
|
||||
Keystore.put('traffic:intensity', current_intensity(low, high))
|
||||
end
|
||||
|
||||
def self.current_activity
|
||||
start_at = Time.now.utc - 15.minutes
|
||||
start_at = PERIOD_LENGTH.minutes.ago
|
||||
result = ActiveRecord::Base.connection.execute <<-SQL
|
||||
select
|
||||
(SELECT count(1) AS n_votes FROM votes WHERE updated_at >= '#{start_at}') +
|
||||
|
@ -51,20 +47,13 @@ module TrafficHelper
|
|||
result.to_a.first.first
|
||||
end
|
||||
|
||||
def self.current_intensity
|
||||
low, high = cached_traffic_range
|
||||
def self.current_intensity(low, high)
|
||||
return 0.5 if low.nil? || high.nil? || high == low
|
||||
activity = [low, current_activity, high].sort[1]
|
||||
[0, ((activity - low)*1.0/(high - low) * 100).round, 100].sort[1]
|
||||
end
|
||||
|
||||
def self.current_period_key
|
||||
"traffic:at:#{(Time.now.utc.to_i/CACHE_FOR.minutes).floor}"
|
||||
end
|
||||
|
||||
def self.cached_current_intensity
|
||||
Keystore.readthrough_cache(current_period_key) do
|
||||
current_intensity
|
||||
end
|
||||
Keystore.value_for('traffic:intensity') || 0.5
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,11 +6,11 @@ class Keystore < ApplicationRecord
|
|||
validates :key, presence: true, length: { maximum: MAX_KEY_LENGTH }
|
||||
|
||||
def self.get(key)
|
||||
self.find_by(:key => key)
|
||||
self.find_by(key: key)
|
||||
end
|
||||
|
||||
def self.value_for(key)
|
||||
self.find_by(:key => key).try(:value)
|
||||
self.where(key: 'traffic:intensity').limit(1).pluck(:value).first
|
||||
end
|
||||
|
||||
def self.put(key, value)
|
||||
|
@ -76,6 +76,14 @@ class Keystore < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def self.decrement_value_for(key, amount = -1)
|
||||
self.increment_value_for(key, amount)
|
||||
end
|
||||
|
||||
def self.decremented_value_for(key, amount = -1)
|
||||
self.incremented_value_for(key, amount)
|
||||
end
|
||||
|
||||
# deliberately no lock/transaction as TrafficHelper is on the hot path of every request
|
||||
def self.readthrough_cache(key, &blk)
|
||||
if (found = value_for(key))
|
||||
|
@ -87,14 +95,6 @@ class Keystore < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def self.decrement_value_for(key, amount = -1)
|
||||
self.increment_value_for(key, amount)
|
||||
end
|
||||
|
||||
def self.decremented_value_for(key, amount = -1)
|
||||
self.incremented_value_for(key, amount)
|
||||
end
|
||||
|
||||
def self.validate_input_key(key)
|
||||
exception = ActiveRecord::ValueTooLong.new("#{MAX_KEY_LENGTH}" \
|
||||
" characters is the maximum allowed for key")
|
||||
|
|
|
@ -9,11 +9,5 @@ require File.expand_path('../../config/boot', __FILE__)
|
|||
require APP_PATH
|
||||
Rails.application.require_environment!
|
||||
|
||||
# Delete old period keys
|
||||
Keystore
|
||||
.where('`key` like "traffic:at:%"')
|
||||
.where.not('`key` = ?', TrafficHelper.current_period_key)
|
||||
.delete_all
|
||||
|
||||
# calculate and cache new low and high activity range for traffic
|
||||
TrafficHelper.cached_traffic_range
|
||||
# calculate and cache activity range for traffic
|
||||
TrafficHelper.cache_traffic!
|
||||
|
|
Loading…
Reference in New Issue