Class: Dalli::Protocol::ValueSerializer

Inherits:
Object
  • Object
show all
Defined in:
lib/dalli/protocol/value_serializer.rb

Overview

Dalli::Protocol::ValueSerializer compartmentalizes the logic for managing serialization and deserialization of stored values. It manages interpreting relevant options from both client and request, determining whether to serialize/deserialize on store/retrieve, and processes bitflags as necessary.

Constant Summary collapse

DEFAULTS =
{
  serializer: Marshal
}.freeze
OPTIONS =
DEFAULTS.keys.freeze
FLAG_SERIALIZED =

www.hjp.at/zettel/m/memcached_flags.rxml Looks like most clients use bit 0 to indicate native language serialization

0x1
FLAG_UTF8 =
0x2
@@marshal_warning_logged =

Class variable to track whether the Marshal warning has been logged

false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocol_options) ⇒ ValueSerializer

Returns a new instance of ValueSerializer.



28
29
30
31
32
# File 'lib/dalli/protocol/value_serializer.rb', line 28

def initialize(protocol_options)
  @serialization_options =
    DEFAULTS.merge(protocol_options.slice(*OPTIONS))
  warn_if_marshal_default(protocol_options) unless protocol_options[:silence_marshal_warning]
end

Instance Attribute Details

#serialization_optionsObject

rubocop:disable Style/ClassVars



26
27
28
# File 'lib/dalli/protocol/value_serializer.rb', line 26

def serialization_options
  @serialization_options
end

Instance Method Details

#retrieve(value, bitflags) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/dalli/protocol/value_serializer.rb', line 55

def retrieve(value, bitflags)
  serialized = bitflags.anybits?(FLAG_SERIALIZED)
  if serialized
    begin
      serializer.load(value)
    rescue StandardError
      raise UnmarshalError, 'Unable to unmarshal value'
    end
  elsif bitflags.anybits?(FLAG_UTF8)
    value.force_encoding(Encoding::UTF_8)
  else
    value
  end
end

#serialize_value(value) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/dalli/protocol/value_serializer.rb', line 74

def serialize_value(value)
  serializer.dump(value)
rescue Timeout::Error => e
  raise e
rescue StandardError => e
  # Serializing can throw several different types of generic Ruby exceptions.
  # Convert to a specific exception so we can special case it higher up the stack.
  exc = Dalli::MarshalError.new(e.message)
  exc.set_backtrace e.backtrace
  raise exc
end

#serializerObject



70
71
72
# File 'lib/dalli/protocol/value_serializer.rb', line 70

def serializer
  @serialization_options[:serializer]
end

#store(value, req_options, bitflags) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/dalli/protocol/value_serializer.rb', line 34

def store(value, req_options, bitflags)
  if req_options
    return [value.to_s, bitflags] if req_options[:raw]

    # If the value is a simple string, going through serialization is costly
    # for no benefit other than preserving encoding.
    # Assuming most strings are either UTF-8 or BINARY we can just store
    # that information in the bitflags.
    if req_options[:string_fastpath] && value.instance_of?(String)
      case value.encoding
      when Encoding::BINARY
        return [value, bitflags]
      when Encoding::UTF_8
        return [value, bitflags | FLAG_UTF8]
      end
    end
  end

  [serialize_value(value), bitflags | FLAG_SERIALIZED]
end