Class: SSLTest::MemoryStore

Inherits:
Object
  • Object
show all
Defined in:
lib/ssl-test/memory_store.rb

Overview

A tiny in-process cache store used as the default backend. It mirrors the small subset of the ActiveSupport::Cache / Rails.cache API that SSLTest relies on (read/write/delete) so they’re interchangeable (assign Rails.cache via SSLTest.cache= to share/compress across processes). Access is guarded by a Mutex because SSLTest is typically used from threaded servers (e.g. Puma).

Unlike a shared/compressed backend (memcache via Dalli), this store is per-process, uncompressed and unbounded, so be careful about memory usage if you validate millions of certificates in a row (the OCSP cache is keyed by certificate serial). For those workloads, configure SSLTest.cache to a shared store instead.

Instance Method Summary collapse

Constructor Details

#initializeMemoryStore

Returns a new instance of MemoryStore.



14
15
16
17
# File 'lib/ssl-test/memory_store.rb', line 14

def initialize
  @data = {}
  @mutex = Mutex.new
end

Instance Method Details

#clearObject



42
43
44
# File 'lib/ssl-test/memory_store.rb', line 42

def clear
  @mutex.synchronize { @data.clear }
end

#delete(key) ⇒ Object



38
39
40
# File 'lib/ssl-test/memory_store.rb', line 38

def delete(key)
  @mutex.synchronize { @data.delete(key) }
end

#eachObject

Yields [key, value] for every entry that hasn’t expired.



47
48
49
50
51
52
53
54
# File 'lib/ssl-test/memory_store.rb', line 47

def each
  return enum_for(:each) unless block_given?
  now = Time.now
  @mutex.synchronize { @data.dup }.each do |key, entry|
    next if entry[:expires_at] && entry[:expires_at] <= now
    yield key, entry[:value]
  end
end

#read(key) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ssl-test/memory_store.rb', line 19

def read(key)
  @mutex.synchronize do
    entry = @data[key]
    next nil unless entry
    if entry[:expires_at] && entry[:expires_at] <= Time.now
      @data.delete(key)
      next nil
    end
    entry[:value]
  end
end

#sizeObject

Returns a breakdown of the cached SSLTest entries (CRL lists and OCSP responses/errors) with approximate byte sizes, mainly useful for monitoring memory usage. Specific to ssl-test’s key namespace.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ssl-test/memory_store.rb', line 59

def size
  crl_lists = ocsp_responses = ocsp_errors = 0
  crl_bytes = ocsp_bytes = 0
  each do |key, value|
    case key
    when %r{\A#{CACHE_NAMESPACE}/crl/}
      crl_lists += 1
      crl_bytes += ObjectSize.size(value)
    when %r{\A#{CACHE_NAMESPACE}/ocsp-error/}
      ocsp_errors += 1
      ocsp_bytes += ObjectSize.size(value)
    when %r{\A#{CACHE_NAMESPACE}/ocsp/}
      ocsp_responses += 1
      ocsp_bytes += ObjectSize.size(value)
    end
  end
  {
    crl: { lists: crl_lists, bytes: crl_bytes },
    ocsp: { responses: ocsp_responses, errors: ocsp_errors, bytes: ocsp_bytes }
  }
end

#write(key, value, expires_in: nil) ⇒ Object



31
32
33
34
35
36
# File 'lib/ssl-test/memory_store.rb', line 31

def write(key, value, expires_in: nil)
  @mutex.synchronize do
    @data[key] = { value: value, expires_at: expires_in && Time.now + expires_in }
  end
  value
end