Module: Familia::Features::Expiration

Extended by:
ClassMethods
Defined in:
lib/familia/features/expiration.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



21
22
23
24
25
26
27
28
29
30
# File 'lib/familia/features/expiration.rb', line 21

def self.included base
  Familia.ld "[#{base}] Loaded #{self}"
  base.extend ClassMethods

  # Optionally define ttl in the class to make
  # sure we always have an array to work with.
  unless base.instance_variable_defined?(:@ttl)
    base.instance_variable_set(:@ttl, @ttl) # set above
  end
end

Instance Method Details

#ttlObject



36
37
38
# File 'lib/familia/features/expiration.rb', line 36

def ttl
  @ttl || self.class.ttl
end

#ttl=(v) ⇒ Object



32
33
34
# File 'lib/familia/features/expiration.rb', line 32

def ttl=(v)
  @ttl = v.to_f
end

#update_expiration(ttl: nil) ⇒ Boolean

Note:

If TTL is set to zero, the expiration will be removed, making the data persist indefinitely.

Sets an expiration time for the Redis data associated with this object.

This method allows setting a Time To Live (TTL) for the data in Redis, after which it will be automatically removed.

Examples:

Setting an expiration of one day

object.update_expiration(ttl: 86400)

Parameters:

  • ttl (Integer, nil) (defaults to: nil)

    The Time To Live in seconds. If nil, the default TTL will be used.

Returns:

  • (Boolean)

    Returns true if the expiration was set successfully, false otherwise.

Raises:

  • (Familia::Problem)

    Raises an error if the TTL is not a non-negative integer.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/familia/features/expiration.rb', line 60

def update_expiration(ttl: nil)
  ttl ||= self.ttl

  if self.class.has_relations?
    Familia.ld "[update_expiration] #{self.class} has relations: #{self.class.redis_types.keys}"
    self.class.redis_types.each do |name, definition|
      next if definition.opts[:ttl].nil?
      obj = send(name)
      Familia.ld "[update_expiration] Updating expiration for #{name} (#{obj.rediskey}) to #{ttl}"
      obj.update_expiration(ttl: ttl)
    end
  end

  # It's important to raise exceptions here and not just log warnings. We
  # don't want to silently fail at setting expirations and cause data
  # retention issues (e.g. not removed in a timely fashion).
  #
  # For the same reason, we don't want to default to 0 bc there's not a
  # good reason for the ttl to not be set in the first place. If the
  # class doesn't have a ttl, the default comes from Familia.ttl (which
  # is 0).
  unless ttl.is_a?(Numeric)
    raise Familia::Problem, "TTL must be a number (#{ttl.class} in #{self.class})"
  end

  if ttl.zero?
    return Familia.ld "[update_expiration] No expiration for #{self.class} (#{rediskey})"
  end

  Familia.ld "[update_expiration] Expires #{rediskey} in #{ttl} seconds"

  # Redis' EXPIRE command returns 1 if the timeout was set, 0 if key does
  # not exist or the timeout could not be set. Via redis-rb here, it's
  # a bool.
  expire(ttl)
end