class FactoryBotCaching::FactoryRecordCache
Constants
- CacheEntry
Attributes
build_class[R]
cache[R]
enumerator_cache[R]
Public Class Methods
new(build_class:)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 32 def initialize(build_class:) @build_class = build_class @cache = Hash.new do |factory_hash, key| factory_hash[key] = [] end reset_counters end
Public Instance Methods
fetch(overrides:, traits:, &block)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 40 def fetch(overrides:, traits:, &block) key = {overrides: overrides, traits: traits} now = Time.now enumerator = enumerator_for(key, at: now) enumerator.until_end do |entry| # Entries are sorted by created at, so we can break as soon as we see an entry created_at after now break if entry.created_at > now record = build_class.find_by(build_class.primary_key => entry.identifier) return record unless record.nil? end cache_new_record(key, &block) end
reset_counters()
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 55 def reset_counters @enumerator_cache = Hash.new do |enumerator_hash, key| enumerator_hash[key] = ImmutableIterator.new(cache[key]) end end
Private Instance Methods
cache_new_record(cache_key, &block)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 76 def cache_new_record(cache_key, &block) new_record = process_block(&block) primary_key = new_record.class.primary_key entry = CacheEntry.new(Time.now, new_record[primary_key]) cached_records = cache[cache_key] insert_at_index = cached_records.find_index { |record| record.created_at > entry.created_at } if insert_at_index.nil? cached_records << entry else cached_records.insert(insert_at_index, entry) end new_record end
enumerator_for(key, at:)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 65 def enumerator_for(key, at:) enumerator = enumerator_cache[key] boundary_time = lookback_start_time(time: at) enumerator.fast_forward { |entry| entry.created_at > boundary_time } enumerator end
lookback_start_time(time: Time.now)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 72 def lookback_start_time(time: Time.now) time - FactoryBotCaching.configuration.cache_timeout end
process_block(&block)
click to toggle source
# File lib/factory_bot_caching/factory_record_cache.rb, line 93 def process_block(&block) record = nil Thread.new do ActiveRecord::Base.connection_pool.with_connection do |conn| conn.execute("SET statement_timeout = '20s'") record = FactoryBotCaching.without_caching(&block) end end.join record rescue => e # Append the backtrace of the current thread to the backtrace of the joined thread e.set_backtrace(e.backtrace + caller) raise e end