Class: Condenser::Cache::FileStore

Inherits:
Condenser::CacheStore show all
Defined in:
lib/condenser/cache/file_store.rb

Constant Summary collapse

GITKEEP_FILES =
['.gitkeep', '.keep'].freeze

Instance Method Summary collapse

Methods inherited from Condenser::CacheStore

#delete, #fetch, #fetch_if

Constructor Details

#initialize(root, size: 26_214_400, logger: nil) ⇒ FileStore

Public: Initialize the cache store.

root - A String path to a directory to persist cached values to. size - A Integer of the maximum size the store will hold (in bytes).

(default: 25MB).

logger - The logger to which some info will be printed.

(default logger level is FATAL and won't output anything).


13
14
15
16
17
18
# File 'lib/condenser/cache/file_store.rb', line 13

def initialize(root, size: 26_214_400, logger: nil)
  @root     = root
  @max_size = size
  @gc_size  = size * 0.75
  @logger   = logger
end

Instance Method Details

#clear(options = nil) ⇒ Object

Public: Clear the cache

adapted from ActiveSupport::Cache::FileStore#clear

Deletes all items from the cache. In this case it deletes all the entries in the specified file store directory except for .keep or .gitkeep. Be careful which directory is specified as @root because everything in that directory will be deleted.

Returns true



93
94
95
96
97
98
99
# File 'lib/condenser/cache/file_store.rb', line 93

def clear(options=nil)
  Dir.children(@root).each do |f|
    next if GITKEEP_FILES.include?(f)
    FileUtils.rm_r(File.join(@root, f))
  end
  true
end

#get(key) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/condenser/cache/file_store.rb', line 20

def get(key)
  path = File.join(@root, "#{key}.cache")
  
  value = safe_open(path) do |f|
    begin
      unmarshaled_deflated(f.read, Zlib::MAX_WBITS)
    rescue Exception => e
      # @logger.error do
        puts "#{self.class}[#{path}] could not be unmarshaled: #{e.class}: #{e.message}"
      # end
      nil
    end
  end

  FileUtils.touch(path) if value
  
  value
end

#inspectObject

Public: Pretty inspect

Returns String.



80
81
82
# File 'lib/condenser/cache/file_store.rb', line 80

def inspect
  "#<#{self.class}>"
end

#set(key, value) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/condenser/cache/file_store.rb', line 39

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_096
    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
  Condenser::Utils.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

#sizeObject



101
102
103
# File 'lib/condenser/cache/file_store.rb', line 101

def size
  @size ||= find_caches.inject(0) { |sum, (_, stat)| sum + stat.size }
end