Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions app/models/etsource/merit_order.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
module Etsource
class MeritOrder
class << self
attr_accessor :cache
end

CACHE_ATTRIBUTES = %i[
merit_order
hydrogen
heat_network_lt
heat_network_mt
heat_network_ht
agriculture_heat
].freeze

def initialize(etsource = Etsource::Base.instance)
@etsource = etsource
end
Expand Down Expand Up @@ -84,21 +97,39 @@ def import_agriculture_heat
#
# Returns a hash.
def import(attribute)
Rails.cache.fetch("#{attribute}_hash") do
mo_nodes = Atlas::EnergyNode.all.select(&attribute).sort_by(&:key)
mo_data = {}
merit_order_cache[attribute]
end

mo_nodes.each do |node|
config = node.public_send(attribute)
type = config.type.to_s
group = config.group&.to_s
def self.reset_cache!
self.cache = nil
end

mo_data[type] ||= {}
mo_data[type][node.key.to_s] = group
end
# Batches all MeritOrder cache reads into one SQL query per request, so
# subsequent fetch calls are served from memory instead of the database.
def merit_order_cache
self.class.cache ||= begin
cache_attr_by_key = CACHE_ATTRIBUTES.index_by { |a| "#{a}_hash" }

mo_data
Rails.cache.fetch_multi(*cache_attr_by_key.keys) do |cache_key|
compute(cache_attr_by_key[cache_key])
end.transform_keys { |k| cache_attr_by_key[k] }
end
end

def compute(attribute)
mo_nodes = Atlas::EnergyNode.all.select(&attribute).sort_by(&:key)
mo_data = {}

mo_nodes.each do |node|
config = node.public_send(attribute)
type = config.type.to_s
group = config.group&.to_s

mo_data[type] ||= {}
mo_data[type][node.key.to_s] = group
end

mo_data
end
end
end
26 changes: 21 additions & 5 deletions app/models/etsource/molecules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
module Etsource
# Loads data relating to the calculation of molecule flows based on the energy graph.
module Molecules
CACHE_KEYS = %w[
molecules.from_energy_keys
molecules.from_molecules_keys
].freeze

module_function

# Internal: Computes the list of molecule graph nodes which have a molecule_conversion
Expand All @@ -12,9 +17,7 @@ module Molecules
#
# Returns an Array of Symbols.
def from_energy_keys
Rails.cache.fetch('molecules.from_energy_keys') do
Atlas::MoleculeNode.all.select(&:from_energy).map(&:key).sort
end
molecule_cache['molecules.from_energy_keys']
end

# Internal: Computes the list of molecule graph nodes which have a molecule_conversion
Expand All @@ -24,8 +27,21 @@ def from_energy_keys
#
# Returns an Array of Symbols.
def from_molecules_keys
Rails.cache.fetch('molecules.from_molecules_keys') do
Atlas::EnergyNode.all.select(&:from_molecules).map(&:key).sort
molecule_cache['molecules.from_molecules_keys']
end

def reset_cache!
@molecule_cache = nil
end

# Batches all Molecules cache reads into one SQL query per request, so
# subsequent fetch calls are served from memory instead of the database.
def molecule_cache
@molecule_cache ||= Rails.cache.fetch_multi(*CACHE_KEYS) do |key|
case key
when 'molecules.from_energy_keys' then Atlas::MoleculeNode.all.select(&:from_energy).map(&:key).sort
when 'molecules.from_molecules_keys' then Atlas::EnergyNode.all.select(&:from_molecules).map(&:key).sort
end
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions app/models/nasty_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ def expire_local!
Merit::Curve.reader = Merit::Curve.reader.class.new

@cache_store = {}

# Reset process-level memoization so the next request re-fetches from
# Rails.cache, which has just been cleared by expire_cache!
Etsource::MeritOrder.reset_cache!
Etsource::Molecules.reset_cache!
end

def expire_atlas!(options)
Expand Down