[フレーム]

Class: Opal::Cache::FileCache

Inherits:
Object
  • Object
  • Opal::Cache::FileCache
show all
Defined in:
opal/lib/opal/cache/file_cache.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir: nil, max_size: nil) ⇒ FileCache

Returns a new instance of FileCache.

9
10
11
12
13
14
15
16
17
18
# File 'opal/lib/opal/cache/file_cache.rb', line 9
def initialize(dir: nil, max_size: nil)
 @dir = dir || self.class.find_dir
 # Store at most 32MB of cache - de facto this 32MB is larger,
 # as we don't account for inode size for instance. In fact, it's
 # about 50M. Also we run this check before anything runs, so things
 # may go up to 64M or even larger.
 @max_size = max_size || 32 * 1024 * 1024
 tidy_up_cache
end

Class Method Details

.dir_writable?(*paths) ⇒ Boolean

This complex piece of code tries to check if we can robustly mkdir_p a directory.

Returns:

  • (Boolean)
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'opal/lib/opal/cache/file_cache.rb', line 82
def self.dir_writable?(*paths)
 dir = nil
 paths = paths.reduce([]) do |a, b|
 [*a, dir = a.last ? File.expand_path(b, a.last) : b]
 end
 File.exist?(paths.first) &&
 paths.reverse.all? do |i|
 !File.exist?(i) || (File.directory?(i) && File.writable?(i))
 end
 dir
end

.find_dirObject

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'opal/lib/opal/cache/file_cache.rb', line 96
def self.find_dir
 @find_dir ||= case
 # Try to write cache into a directory pointed by an environment variable if present
 when dir = ENV['OPAL_CACHE_DIR']
 FileUtils.mkdir_p(dir)
 dir
 # Otherwise, we write to the place where Opal is installed...
 # I don't think it's a good location to store cache, so many things can go wrong.
 # when dir = dir_writable?(Opal.gem_dir, '..', 'tmp', 'cache')
 # FileUtils.mkdir_p(dir)
 # FileUtils.chmod(0o700, dir)
 # dir
 # Otherwise, ~/.cache/opal...
 when dir = dir_writable?(Dir.home, '.cache', 'opal')
 FileUtils.mkdir_p(dir)
 FileUtils.chmod(0o700, dir)
 dir
 # Only /tmp is writable... or isn't it?
 when (dir = dir_writable?('/tmp', "opal-cache-#{ENV['USER']}")) && File.sticky?('/tmp')
 FileUtils.mkdir_p(dir)
 FileUtils.chmod(0o700, dir)
 dir
 # No way... we can't write anywhere...
 else
 warn "Couldn't find a writable path to store Opal cache. " \
 'Try setting OPAL_CACHE_DIR environment variable'
 nil
 end
end

Instance Method Details

#get(key) ⇒ Object

39
40
41
42
43
44
45
46
47
48
49
50
# File 'opal/lib/opal/cache/file_cache.rb', line 39
def get(key)
 file = cache_filename_for(key)
 if File.exist?(file)
 FileUtils.touch(file)
 out = File.binread(file)
 out = Zlib.gunzip(out)
 Marshal.load(out) # rubocop:disable Security/MarshalLoad
 end
rescue Zlib::GzipFile::Error
 nil
end

#set(key, data) ⇒ Object

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'opal/lib/opal/cache/file_cache.rb', line 20
def set(key, data)
 file = cache_filename_for(key)
 out = Marshal.dump(data)
 # Sometimes `Zlib::BufError` gets raised, unsure why, makes no sense, possibly
 # some race condition (see https://github.com/ruby/zlib/issues/49).
 # Limit the number of retries to avoid infinite loops.
 retries = 5
 begin
 out = Zlib.gzip(out, level: 9)
 rescue Zlib::BufError
 warn "\n[Opal]: Zlib::BufError; retrying (#{retries} retries left)"
 retries -= 1
 retry if retries > 0
 end
 File.binwrite(file, out)
end

AltStyle によって変換されたページ (->オリジナル) /