Module: SecurityBox::ModuleCache
- Defined in:
- lib/security_box/module_cache.rb
Overview
Content-addressed disk cache for compiled wasm modules.
Compiling the ruby.wasm image costs ~15s per process. This cache stores the
compiled artifact (Module#serialize) so later processes pay only a fast
deserialize. Files live at <cache_dir>/modules/
Everything here is best effort: on any I/O or deserialization failure the caller falls back to a regular compile and the cache self-heals on the next successful store. Set SECURITY_BOX_CACHE_DIR to relocate the cache; the default is ~/.cache/security_box.
Constant Summary collapse
- CACHE_DIR_ENV_VAR =
"SECURITY_BOX_CACHE_DIR"
Class Method Summary collapse
-
.cache_path(engine, image_path) ⇒ Object
Nil when no usable cache directory exists (cache disabled).
-
.compile_and_store(engine, image_path) ⇒ Object
Compiles the image and stores the serialized artifact in the cache (best effort).
-
.load_module(engine, image_path) ⇒ Object
Returns the cached module for this engine+image, or nil on cache miss, corrupted cache file or any cache error.
- .modules_dir ⇒ Object
- .store(engine, image_path, module_) ⇒ Object
Class Method Details
.cache_path(engine, image_path) ⇒ Object
Nil when no usable cache directory exists (cache disabled).
58 59 60 61 62 63 |
# File 'lib/security_box/module_cache.rb', line 58 def cache_path(engine, image_path) dir = modules_dir return nil unless dir File.join(dir, "#{cache_key(engine, image_path)}.cwasm") end |
.compile_and_store(engine, image_path) ⇒ Object
Compiles the image and stores the serialized artifact in the cache (best effort). Returns the compiled module in all cases.
37 38 39 40 41 |
# File 'lib/security_box/module_cache.rb', line 37 def compile_and_store(engine, image_path) module_ = Wasmtime::Module.from_file(engine, image_path) store(engine, image_path, module_) module_ end |
.load_module(engine, image_path) ⇒ Object
Returns the cached module for this engine+image, or nil on cache miss, corrupted cache file or any cache error.
26 27 28 29 30 31 32 33 |
# File 'lib/security_box/module_cache.rb', line 26 def load_module(engine, image_path) path = cache_path(engine, image_path) return nil unless path && File.file?(path) Wasmtime::Module.deserialize_file(engine, path) rescue Wasmtime::Error, TypeError, SystemCallError nil end |
.modules_dir ⇒ Object
65 66 67 68 69 70 |
# File 'lib/security_box/module_cache.rb', line 65 def modules_dir base = ENV[CACHE_DIR_ENV_VAR] || default_base_dir return nil unless base File.("modules", base) end |
.store(engine, image_path, module_) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/security_box/module_cache.rb', line 43 def store(engine, image_path, module_) path = cache_path(engine, image_path) return if path.nil? dir = File.dirname(path) FileUtils.mkdir_p(dir) tmp = File.join(dir, ".#{File.basename(path)}.#{Process.pid}.tmp") File.binwrite(tmp, module_.serialize) File.rename(tmp, path) rescue Wasmtime::Error, SystemCallError File.delete(tmp) if defined?(tmp) && tmp && File.exist?(tmp) nil end |