Class: Readthis::Serializers

Inherits:
Object
  • Object
show all
Defined in:
lib/readthis/serializers.rb

Overview

Instances of the ‘Serializers` class are used to configure the use of multiple “serializers” for a single cache.

Readthis uses Ruby’s ‘Marshal` module for serializing all values by default. This isn’t always the fastest option, and depending on your use case it may be desirable to use a faster but less flexible serializer.

By default Readthis knows about 3 different serializers:

  • Marshal

  • JSON

  • Passthrough

If all cached data can safely be represented as a string then use the pass-through serializer:

Readthis::Cache.new(marshal: Readthis::Passthrough)

You can introduce up to four additional serializers by configuring ‘serializers` on the Readthis module. For example, if you wanted to use the extremely fast Oj library for JSON serialization:

Readthis.serializers << Oj
# Freeze the serializers to ensure they aren't changed at runtime.
Readthis.serializers.freeze!
Readthis::Cache.new(marshal: Oj)

Be aware that the *order in which you add serializers matters*. Serializers are sticky and a flag is stored with each cached value. If you subsequently go to deserialize values and haven’t configured the same serializers in the same order your application will raise errors.

Constant Summary collapse

BASE_SERIALIZERS =

Defines the default set of three serializers: Marshal, Passthrough, and JSON. With a hard limit of 7 that leaves 4 additional slots.

{
  Marshal => 0x1,
  Passthrough => 0x2,
  JSON => 0x3
}.freeze
SERIALIZER_LIMIT =

The hard serializer limit, based on the number of possible values within a single 3bit integer.

7

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSerializers

Creates a new Readthis::Serializers entity. No configuration is expected during initialization.



57
58
59
# File 'lib/readthis/serializers.rb', line 57

def initialize
  reset!
end

Instance Attribute Details

#invertedObject (readonly)

Returns the value of attribute inverted.



52
53
54
# File 'lib/readthis/serializers.rb', line 52

def inverted
  @inverted
end

#serializersObject (readonly)

Returns the value of attribute serializers.



52
53
54
# File 'lib/readthis/serializers.rb', line 52

def serializers
  @serializers
end

Instance Method Details

#<<(serializer) ⇒ self

Append a new serializer. Up to 7 total serializers may be configured for any single application be configured for any single application. This limit is based on the number of bytes available in the option flag.

Examples:

Adding Oj as an accepted serializer


serializers = Readthis::Serializers.new
serializers << Oj

Parameters:

  • serializer (Module)

    Any object that responds to ‘dump` and `load`

Returns:

  • (self)

    Returns itself for possible chaining



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/readthis/serializers.rb', line 73

def <<(serializer)
  case
  when serializers.frozen?
    raise SerializersFrozenError
  when serializers.length >= SERIALIZER_LIMIT
    raise SerializersLimitError
  else
    @serializers[serializer] = flags.max.succ
    @inverted = @serializers.invert
  end

  self
end

#assoc(serializer) ⇒ Number

Find a flag for a serializer object.

Examples:

Find the JSON serializer’s flag


serializers.assoc(JSON) #=> 1

Parameters:

  • serializer (Object)

    Look up a flag by object

Returns:

  • (Number)

    Corresponding flag for the serializer object

Raises:

  • (UnknownSerializerError)

    Indicates that a serializer was specified, but hasn’t been configured for usage.



120
121
122
123
124
125
126
127
128
# File 'lib/readthis/serializers.rb', line 120

def assoc(serializer)
  flag = serializers[serializer]

  unless flag
    raise UnknownSerializerError, "'#{serializer}' hasn't been configured"
  end

  flag
end

#flagsObject



149
150
151
# File 'lib/readthis/serializers.rb', line 149

def flags
  serializers.values
end

#freeze!self

Freeze the serializers hash, preventing modification.

Returns:

  • (self)

    The serializer instance.



91
92
93
94
95
# File 'lib/readthis/serializers.rb', line 91

def freeze!
  serializers.freeze

  self
end

#marshalsObject



144
145
146
# File 'lib/readthis/serializers.rb', line 144

def marshals
  serializers.keys
end

#rassoc(flag) ⇒ Module

Find a serializer object by flag value.

Examples:

Find the serializer associated with flag 1


serializers.rassoc(1) #=> Marshal

Parameters:

  • flag (Number)

    Integer to look up the serializer object by

Returns:

  • (Module)

    The serializer object



139
140
141
# File 'lib/readthis/serializers.rb', line 139

def rassoc(flag)
  inverted[flag & SERIALIZER_LIMIT]
end

#reset!self

Reset the instance back to the default state. Useful for cleanup during testing.

Returns:

  • (self)

    The serializer instance.



102
103
104
105
106
107
# File 'lib/readthis/serializers.rb', line 102

def reset!
  @serializers = BASE_SERIALIZERS.dup
  @inverted = @serializers.invert

  self
end