class Sprockets::Cache::FileStore
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/sprockets/cache/file_store.rbs class Sprockets::Cache::FileStore def get: (String key) -> (Array[Set] | nil | String) def safe_open: (String path, ) -> String? def safe_stat: (String fn) -> File::Stat def set: (String key, (Hash | String) value) -> (Hash | String) def size: () -> Integer end
ActiveSupport::Cache::FileStore
See Also
environment.cache = Sprockets::Cache::FileStore.new(“/tmp”)
Assign the instance to the Environment#cache.
Public: A file system cache store that automatically cleans up old keys.
def self.default_logger
Internal: Default standard error fatal logger.
def self.default_logger logger = Logger.new($stderr) logger.level = Logger::FATAL logger end
def clear(options=nil)
as @root because everything in that directory will be deleted.
file store directory except for .keep or .gitkeep. Be careful which directory is specified
Deletes all items from the cache. In this case it deletes all the entries in the specified
adapted from ActiveSupport::Cache::FileStore#clear
Public: Clear the cache
def clear(options=nil) if File.exist?(@root) root_dirs = Dir.entries(@root).reject { |f| (EXCLUDED_DIRS + GITKEEP_FILES).include?(f) } FileUtils.rm_r(root_dirs.collect{ |f| File.join(@root, f) }) end true end
def compute_size(caches)
def compute_size(caches) caches.inject(0) { |sum, (_, stat)| sum + stat.size } end
def find_caches
Returns an Array of [String filename, File::Stat] pairs sorted by
Internal: Get all cache files along with stats.
def find_caches Dir.glob(File.join(@root, '**/*.cache')).reduce([]) { |stats, filename| stat = safe_stat(filename) # stat maybe nil if file was removed between the time we called # dir.glob and the next stat stats << [filename, stat] if stat stats }.sort_by { |_, stat| stat.mtime.to_i } end
def gc!
def gc! start_time = Time.now caches = find_caches size = compute_size(caches) delete_caches, keep_caches = caches.partition { |filename, stat| deleted = size > @gc_size size -= stat.size deleted } return if delete_caches.empty? FileUtils.remove(delete_caches.map(&:first), force: true) @size = compute_size(keep_caches) @logger.warn do secs = Time.now.to_f - start_time.to_f "#{self.class}[#{@root}] garbage collected " + "#{delete_caches.size} files (#{(secs * 1000).to_i}ms)" end end
def get(key)
Experimental RBS support (using type sampling data from the type_fusion
project).
type Sprockets__Cache__FileStore_get_return_value = | nil | String | Set | Set def get: (String key) -> Sprockets__Cache__FileStore_get_return_value
This signature was generated using 47 samples from 3 applications.
key - String cache key.
This API should not be used directly, but via the Cache wrapper API.
Public: Retrieve value from cache.
def get(key) path = File.join(@root, "#{key}.cache") value = safe_open(path) do |f| begin EncodingUtils.unmarshaled_deflated(f.read, Zlib::MAX_WBITS) rescue Exception => e @logger.error do "#{self.class}[#{path}] could not be unmarshaled: " + "#{e.class}: #{e.message}" end nil end end if value FileUtils.touch(path) value end end
def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger)
logger - The logger to which some info will be printed.
(default: 25MB).
max_size - A Integer of the maximum size the store will hold (in bytes).
root - A String path to a directory to persist cached values to.
Public: Initialize the cache store.
def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger) @root = root @max_size = max_size @gc_size = max_size * 0.75 @logger = logger end
def inspect
Public: Pretty inspect
def inspect "#<#{self.class} size=#{size}/#{@max_size}>" end
def safe_open(path, &block)
Experimental RBS support (using type sampling data from the type_fusion
project).
def safe_open: (String path, ) -> String?
This signature was generated using 36 samples from 4 applications.
def safe_open(path, &block) if File.exist?(path) File.open(path, 'rb', &block) end rescue Errno::ENOENT end
def safe_stat(fn)
Experimental RBS support (using type sampling data from the type_fusion
project).
def safe_stat: (String fn) -> File::Stat
This signature was generated using 21 samples from 5 applications.
def safe_stat(fn) File.stat(fn) rescue Errno::ENOENT nil end
def set(key, value)
Experimental RBS support (using type sampling data from the type_fusion
project).
def set: (String key, (uri | String | load_path | String | filename | String | name | String | logical_path | String | content_type | String | source | String | metadata | dependencies | Set | required | Set | stubbed | Set | links | Set | to_load | Set | to_link | Set | map | version | Integer | file | String | mappings | String | sources | | names | | x_sprockets_linecount | Integer | charset | String | digest | String | length | Integer | environment_version | String | dependencies_digest | String | id | String | String) value) -> (uri | String | load_path | String | filename | String | name | String | logical_path | String | content_type | String | source | String | metadata | dependencies | Set | required | Set | stubbed | Set | links | Set | to_load | Set | to_link | Set | map | version | Integer | file | String | mappings | String | sources | | names | | x_sprockets_linecount | Integer | charset | String | digest | String | length | Integer | environment_version | String | dependencies_digest | String | id | String | String)
This signature was generated using 2 samples from 1 application.
value - Object value.
key - String cache key.
This API should not be used directly, but via the Cache wrapper API.
Public: Set a key and value in the cache.
def set(key, value) path = File.join(@root, "#{key}.cache") # Ensure directory exists FileUtils.mkdir_p File.dirname(path) # Check if cache exists before writing exists = File.exist?(path) # Serialize value marshaled = Marshal.dump(value) # Compress if larger than 4KB if marshaled.bytesize > 4 * 1024 deflater = Zlib::Deflate.new( Zlib::BEST_COMPRESSION, Zlib::MAX_WBITS, Zlib::MAX_MEM_LEVEL, Zlib::DEFAULT_STRATEGY ) deflater << marshaled raw = deflater.finish else raw = marshaled end # Write data PathUtils.atomic_write(path) do |f| f.write(raw) @size = size + f.size unless exists end # GC if necessary gc! if size > @max_size value end
def size
Experimental RBS support (using type sampling data from the type_fusion
project).
def size: () -> Integer
This signature was generated using 2 samples from 1 application.
def size @size ||= compute_size(find_caches) end