Class: Telegem::Session::MemoryStore

Inherits:
Object
  • Object
show all
Defined in:
lib/session/memory_store.rb

Instance Method Summary collapse

Constructor Details

#initialize(default_ttl: 300, cleanup_interval: 300, backup_path: nil, backup_interval: 60) ⇒ MemoryStore

Returns a new instance of MemoryStore.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/session/memory_store.rb', line 9

def initialize(
  default_ttl: 300,
  cleanup_interval: 300,
  backup_path: nil,
  backup_interval: 60
)
  @store = {}
  @ttls = {}
  @default_ttl = default_ttl
  @cleanup_interval = cleanup_interval
  @backup_path = backup_path
  @backup_interval = backup_interval

  @last_cleanup = Time.now
  @last_backup = Time.now

  restore! if @backup_path && File.exist?(@backup_path)
end

Instance Method Details

#backup!Object

— Persistence Logic (The “Telecr” Way) —



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/session/memory_store.rb', line 69

def backup!
  return unless @backup_path
  
  # 1. Prepare data
  data = {
    "store" => @store,
    "ttls"  => @ttls.transform_values(&:to_i), # Save as Unix timestamp
    "timestamp" => Time.now.to_i
  }

  # 2. Ensure directory exists
  FileUtils.mkdir_p(File.dirname(@backup_path))

  # 3. ATOMIC WRITE: Write to temp, then rename
  temp_path = "#{@backup_path}.tmp"
  File.write(temp_path, JSON.generate(data))
  File.rename(temp_path, @backup_path)
  
  @last_backup = Time.now
end

#delete(key) ⇒ Object



51
52
53
54
55
56
# File 'lib/session/memory_store.rb', line 51

def delete(key)
  key_s = key.to_s
  @store.delete(key_s)
  @ttls.delete(key_s)
  true
end

#get(key) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/session/memory_store.rb', line 39

def get(key)
  key_s = key.to_s
  return nil unless @store.key?(key_s)

  if expired?(key_s)
    delete(key_s)
    return nil
  end

  @store[key_s]
end

#increment(key, amount = 1, ttl: nil) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/session/memory_store.rb', line 58

def increment(key, amount = 1, ttl: nil)
  current = get(key) || 0
  # Ensure we are working with numbers 
  val = current.to_i rescue 0
  new_val = val + amount
  set(key, new_val, ttl: ttl)
  new_val
end

#restore!Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/session/memory_store.rb', line 90

def restore!
  return unless @backup_path && File.exist?(@backup_path)

  begin
    raw = JSON.parse(File.read(@backup_path))
    
    @store.clear
    @ttls.clear

    raw["store"].each { |k, v| @store[k] = v }
    raw["ttls"].each do |k, v|
      @ttls[k] = Time.at(v)
    end
  rescue => e
    warn "Telegem: Failed to restore backup: #{e.message}"
  end
end

#set(key, value, ttl: nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/session/memory_store.rb', line 28

def set(key, value, ttl: nil)
  auto_cleanup
  key_s = key.to_s

  @store[key_s] = value
  @ttls[key_s] = Time.now + (ttl || @default_ttl)

  auto_backup
  value
end