Sha256: 53a9c78f39453a63a1958489589445c44e9851059f1cd056730242db6ea52a76

Contents?: true

Size: 1.89 KB

Versions: 8

Compression:

Stored size: 1.89 KB

Contents

require_relative '../explicit_require'

Bootsnap::ExplicitRequire.with_gems('msgpack') { require 'msgpack' }
Bootsnap::ExplicitRequire.from_rubylibdir('fileutils')

module Bootsnap
  module LoadPathCache
    class Store
      NestedTransactionError = Class.new(StandardError)
      SetOutsideTransactionNotAllowed = Class.new(StandardError)

      def initialize(store_path)
        @store_path = store_path
        @in_txn = false
        @dirty = false
        load_data
      end

      def get(key)
        @data[key]
      end

      def fetch(key)
        raise SetOutsideTransactionNotAllowed unless @in_txn
        v = get(key)
        unless v
          @dirty = true
          v = yield
          @data[key] = v
        end
        v
      end

      def set(key, value)
        raise SetOutsideTransactionNotAllowed unless @in_txn
        if value != @data[key]
          @dirty = true
          @data[key] = value
        end
      end

      def transaction
        raise NestedTransactionError if @in_txn
        @in_txn = true
        yield
      ensure
        commit_transaction
        @in_txn = false
      end

      private

      def commit_transaction
        if @dirty
          dump_data
          @dirty = false
        end
      end

      def load_data
        @data = begin
          MessagePack.load(File.binread(@store_path))
        # handle malformed data due to upgrade incompatability
        rescue Errno::ENOENT, MessagePack::MalformedFormatError, MessagePack::UnknownExtTypeError, EOFError
          {}
        end
      end

      def dump_data
        # Change contents atomically so other processes can't get invalid
        # caches if they read at an inopportune time.
        tmp = "#{@store_path}.#{(rand * 100000).to_i}.tmp"
        FileUtils.mkpath(File.dirname(tmp))
        File.binwrite(tmp, MessagePack.dump(@data))
        FileUtils.mv(tmp, @store_path)
      end
    end
  end
end

Version data entries

8 entries across 8 versions & 1 rubygems

Version Path
bootsnap-1.1.6.beta3 lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.6.beta2 lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.6.beta lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.5-java lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.5 lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.4-java lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.3-java lib/bootsnap/load_path_cache/store.rb
bootsnap-1.1.3 lib/bootsnap/load_path_cache/store.rb