Class: Philiprehberger::HttpClient::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/http_client/cache.rb

Overview

Simple in-memory cache for GET responses. Respects Cache-Control headers (max-age, no-cache, no-store) and supports conditional requests via ETag and Last-Modified headers.

Examples:

cache = Cache.new
cache.store(uri, response)
cached = cache.lookup(uri)

Defined Under Namespace

Classes: CacheEntry

Instance Method Summary collapse

Constructor Details

#initializeCache

Returns a new instance of Cache.



19
20
21
22
# File 'lib/philiprehberger/http_client/cache.rb', line 19

def initialize
  @monitor = Monitor.new
  @store = {}
end

Instance Method Details

#clear!void

This method returns an undefined value.

Remove all entries from the cache.



81
82
83
# File 'lib/philiprehberger/http_client/cache.rb', line 81

def clear!
  @monitor.synchronize { @store.clear }
end

#entry_for(uri) ⇒ CacheEntry?

Return the cache entry for conditional request headers. Returns nil if no entry exists (even if expired).

Parameters:

  • uri (URI)

    the request URI

Returns:



50
51
52
53
# File 'lib/philiprehberger/http_client/cache.rb', line 50

def entry_for(uri)
  key = cache_key(uri)
  @monitor.synchronize { @store[key] }
end

#lookup(uri) ⇒ Response?

Look up a cached response for the given URI. Returns nil if not cached or expired.

Parameters:

  • uri (URI)

    the request URI

Returns:

  • (Response, nil)

    the cached response or nil



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/philiprehberger/http_client/cache.rb', line 29

def lookup(uri)
  key = cache_key(uri)
  @monitor.synchronize do
    entry = @store[key]
    return nil unless entry

    if expired?(entry)
      # Keep entries with etag/last_modified for conditional requests
      @store.delete(key) unless entry.etag || entry.last_modified
      nil
    else
      entry.response
    end
  end
end

#sizeInteger

Return the number of cached entries.

Returns:

  • (Integer)


88
89
90
# File 'lib/philiprehberger/http_client/cache.rb', line 88

def size
  @monitor.synchronize { @store.size }
end

#store(uri, response) ⇒ void

This method returns an undefined value.

Store a response in the cache. Respects Cache-Control: no-store (does not cache).

Parameters:

  • uri (URI)

    the request URI

  • response (Response)

    the response to cache



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/philiprehberger/http_client/cache.rb', line 61

def store(uri, response)
  return if no_store?(response)

  key = cache_key(uri)
  cc = parse_cache_control(response)

  entry = CacheEntry.new(
    response: response,
    stored_at: now,
    max_age: cc[:max_age],
    etag: response.headers['etag'],
    last_modified: response.headers['last-modified']
  )

  @monitor.synchronize { @store[key] = entry }
end