Class: Async::HTTP::Cache::Store::Memory

Inherits:
Object
  • Object
show all
Defined in:
lib/async/http/cache/store/memory.rb

Overview

Represents an in-memory cache store with automatic pruning of expired entries.

Constant Summary collapse

IF_NONE_MATCH =
"if-none-match"
NOT_MODIFIED =
::Protocol::HTTP::Response[304]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(limit: 1024, maximum_size: 1024*64, prune_interval: 60) ⇒ Memory

Initialize a new in-memory cache store.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/async/http/cache/store/memory.rb', line 16

def initialize(limit: 1024, maximum_size: 1024*64, prune_interval: 60)
	@index = {}
	@limit = limit
	@maximum_size = maximum_size
	
	@hit = 0
	@miss = 0
	@pruned = 0
	
	@gardener = Async(transient: true, annotation: self.class) do |task|
		while true
			task.sleep(prune_interval)
			
			pruned = self.prune
			@pruned += pruned
			
			Console.logger.debug(self) do |buffer|
				if pruned > 0
					buffer.puts "Pruned #{pruned} entries."
				end
				
				buffer.puts "Hits: #{@hit} Misses: #{@miss} Pruned: #{@pruned} Ratio: #{(100.0*@hit/@miss).round(2)}%"
				
				body_usage = @index.sum{|key, value| value.body.length}
				buffer.puts "Index size: #{@index.size} Memory usage: #{(body_usage / 1024.0**2).round(2)}MiB"
				
				# @index.each do |key, value|
				# 	buffer.puts "#{key.join('-')}: #{value.body.length}B"
				# end
			end
		end
	end
end

Instance Attribute Details

#indexObject (readonly)

Returns the value of attribute index.



55
56
57
# File 'lib/async/http/cache/store/memory.rb', line 55

def index
  @index
end

Instance Method Details

#closeObject

Close the cache store and stop background pruning.



51
52
53
# File 'lib/async/http/cache/store/memory.rb', line 51

def close
	@gardener.stop
end

#insert(key, request, response) ⇒ Object

Insert a response into the cache if it meets size and limit constraints.



94
95
96
97
98
99
100
101
# File 'lib/async/http/cache/store/memory.rb', line 94

def insert(key, request, response)
	if @index.size < @limit
		length = response.body&.length
		if length.nil? or length < @maximum_size
			@index[key] = response
		end
	end
end

#lookup(key, request) ⇒ Object

Look up a cached response for the given key and request.



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
# File 'lib/async/http/cache/store/memory.rb', line 64

def lookup(key, request)
	if response = @index[key]
		if response.expired?
			@index.delete(key)
			
			@pruned += 1
			
			return nil
		end
		
		if etags = request.headers[IF_NONE_MATCH]
			if etags.include?(response.etag)
				return NOT_MODIFIED
			end
		end
		
		@hit += 1
		
		return response.dup
	else
		@miss += 1
		
		return nil
	end
end

#pruneInteger

Returns the number of pruned entries.

Returns:

  • (Integer)

    the number of pruned entries.



104
105
106
107
108
109
110
111
112
# File 'lib/async/http/cache/store/memory.rb', line 104

def prune
	initial_count = @index.size
	
	@index.delete_if do |key, value|
		value.expired?
	end
	
	return initial_count - @index.size
end