Module: Familia::Horreum::Serialization

Included in:
Familia::Horreum
Defined in:
lib/familia/horreum/serialization.rb

Overview

Methods that call load and dump (InstanceMethods)

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#redisObject



18
19
20
# File 'lib/familia/horreum/serialization.rb', line 18

def redis
  @redis || self.class.redis
end

Instance Method Details

#commit_fieldsObject

+return: [Array<String>] The return value of the Redis multi command



54
55
56
57
58
59
60
# File 'lib/familia/horreum/serialization.rb', line 54

def commit_fields
  Familia.ld "[commit_fields] #{self.class} #{rediskey} #{to_h}"
  transaction do |conn|
    hmset
    update_expiration
  end
end

#destroy!Object



62
63
64
65
# File 'lib/familia/horreum/serialization.rb', line 62

def destroy!
  Familia.trace :DESTROY, redis, redisuri, caller(1..1) if Familia.debug?
  delete!
end

#saveObject

A thin wrapper around ‘commit_fields` that updates the timestamps and returns a boolean.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/familia/horreum/serialization.rb', line 37

def save
  Familia.trace :SAVE, redis, redisuri, caller(1..1) if Familia.debug?

  # Update timestamp fields
  self.updated = Familia.now.to_i
  self.created = Familia.now.to_i unless self.created

  # Thr return value of commit_fields is an array of strings: ["OK"].
  ret = commit_fields # e.g. ["OK"]

  Familia.ld "[save] #{self.class} #{rediskey} #{ret}"

  # Convert the return value to a boolean
  ret.all? { |value| value == "OK" }
end

#to_aObject



79
80
81
82
83
84
85
# File 'lib/familia/horreum/serialization.rb', line 79

def to_a
  self.class.fields.map do |field|
    val = send(field)
    Familia.ld " [to_a] field: #{field} val: #{val}"
    to_redis(val)
  end
end

#to_hObject



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/familia/horreum/serialization.rb', line 67

def to_h
  # Use self.class.fields to efficiently generate a hash
  # of all the fields for this object
  self.class.fields.inject({}) do |hsh, field|
    val = send(field)
    prepared = val.to_s
    Familia.ld " [to_h] field: #{field} val: #{val.class} prepared: #{prepared.class}"
    hsh[field] = prepared
    hsh
  end
end

#to_redis(val) ⇒ Object

The to_redis method in Familia::Redistype and Familia::Horreum serve similar purposes but have some key differences in their implementation:

Similarities:

  • Both methods aim to serialize various data types for Redis storage

  • Both handle basic data types like String, Symbol, and Numeric

  • Both have provisions for custom serialization methods

Differences:

  • Familia::Redistype uses the opts for type hints

  • Familia::Horreum had more explicit type checking and conversion

  • Familia::Redistype includes more extensive debug tracing

The centralized Familia.distinguisher method accommodates both approaches by:

  1. Handling a wide range of data types, including those from both implementations

  2. Providing a ‘strict_values’ option for flexible type handling

  3. Supporting custom serialization through a dump_method

  4. Including debug tracing similar to Familia::Redistype

By using Familia.distinguisher, we achieve more consistent behavior across different parts of the library while maintaining the flexibility to handle various data types and custom serialization needs. This centralization also makes it easier to extend or modify serialization behavior in the future.



111
112
113
114
115
116
117
118
119
120
# File 'lib/familia/horreum/serialization.rb', line 111

def to_redis(val)
  prepared = Familia.distinguisher(val, false)

  if prepared.nil? && val.respond_to?(dump_method)
    prepared = val.send(dump_method)
  end

  Familia.ld "[#{self.class}#to_redis] nil returned for #{self.class}##{name}" if prepared.nil?
  prepared
end

#transactionObject



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/familia/horreum/serialization.rb', line 22

def transaction
  original_redis = self.redis

  begin
    redis.multi do |conn|
      self.instance_variable_set(:@redis, conn)
      yield(conn)
    end
  ensure
    self.redis = original_redis
  end
end

#update_expiration(ttl = nil) ⇒ Object



122
123
124
125
126
127
128
# File 'lib/familia/horreum/serialization.rb', line 122

def update_expiration(ttl = nil)
  ttl ||= opts[:ttl]
  return if ttl.to_i.zero? # nil will be zero

  Familia.ld "#{rediskey} to #{ttl}"
  expire ttl.to_i
end