1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
# frozen_string_literal: true
require 'forwardable'
module Dalli
module Protocol
##
# Dalli::Protocol::ValueMarshaller compartmentalizes the logic for marshalling
# and unmarshalling unstructured data (values) to Memcached. It also enforces
# limits on the maximum size of marshalled data.
##
class ValueMarshaller
extend Forwardable
DEFAULTS = {
# max size of value in bytes (default is 1 MB, can be overriden with "memcached -I <size>")
value_max_bytes: 1024 * 1024
}.freeze
OPTIONS = DEFAULTS.keys.freeze
def_delegators :@value_serializer, :serializer
def_delegators :@value_compressor, :compressor, :compression_min_size, :compress_by_default?
def initialize(client_options)
@value_serializer = ValueSerializer.new(client_options)
@value_compressor = ValueCompressor.new(client_options)
@marshal_options =
DEFAULTS.merge(client_options.slice(*OPTIONS))
end
def store(key, value, options = nil)
bitflags = 0
value, bitflags = @value_serializer.store(value, options, bitflags)
value, bitflags = @value_compressor.store(value, options, bitflags)
error_if_over_max_value_bytes(key, value)
[value, bitflags]
end
def retrieve(value, flags)
value = @value_compressor.retrieve(value, flags)
@value_serializer.retrieve(value, flags)
end
def value_max_bytes
@marshal_options[:value_max_bytes]
end
def error_if_over_max_value_bytes(key, value)
return if value.bytesize <= value_max_bytes
message = "Value for #{key} over max size: #{value_max_bytes} <= #{value.bytesize}"
raise Dalli::ValueOverMaxSize, message
end
end
end
end
|