cachext 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3072a5999fa8a90d21259de13caec3f355eebdc4
4
- data.tar.gz: 7ef116659a1bfa08174f3c27157752a3bdd13c8d
3
+ metadata.gz: 1141e77be7834868ab37636024f4eeea8c719581
4
+ data.tar.gz: aed591612989be4abf58211a409542c9f51c189e
5
5
  SHA512:
6
- metadata.gz: 1c7308ee711bb3c43522f1801fe51f6de0653057a2e6cccd7e9ae0e27be8d42e7ce5285b3287a371f1fe5b26b6ffee1e789db1a1a793ec26fdc991a7ded85489
7
- data.tar.gz: 3cb8a48dcd02fac5070bb695e35064fe5562f8303265c334e8846c44bf0a358e6b011e5a63ce60dfe1ea5d61e096f5f070652668ec2dea0fe929fd29d9cf84fe
6
+ metadata.gz: 4f0bcdf511a0c61b65ee32a4b7a82c1f14864c08bd9a7c5c609970f6bc8f13cbe3c4c2e183966fb75d16cbeb2ce5a7f5f490c1ab9f02f268df8c1f324248370a
7
+ data.tar.gz: 7bffc2e75ce62b71a0a3db99c917653304291bb7ad854582a04caf7103bbfc18deb2a9c2e9026959ca51bccf143b9d4d532aa886d5afa312531cdd8ae65a771d
data/lib/cachext.rb CHANGED
@@ -4,8 +4,10 @@ require "faraday/error"
4
4
  module Cachext
5
5
  autoload :Client, "cachext/client"
6
6
  autoload :Configuration, "cachext/configuration"
7
- autoload :Key, "cachext/key"
8
7
  autoload :Features, "cachext/features"
8
+ autoload :Key, "cachext/key"
9
+ autoload :MissingRecord, "cachext/missing_record"
10
+ autoload :Multi, "cachext/multi"
9
11
  autoload :Options, "cachext/options"
10
12
 
11
13
  def self.Key raw_key
@@ -36,4 +38,8 @@ module Cachext
36
38
  config.cache.clear
37
39
  config.redis.del "cachext:*"
38
40
  end
41
+
42
+ def self.multi klass, ids, options = {}, &block
43
+ Multi.new(config, klass, options).fetch ids, &block
44
+ end
39
45
  end
@@ -0,0 +1,12 @@
1
+ module Cachext
2
+ MissingRecord = Struct.new(:id)
3
+ class MissingRecord
4
+ def missing?
5
+ true
6
+ end
7
+
8
+ def present?
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,114 @@
1
+ require "active_support/core_ext/module/delegation"
2
+ require "active_support/core_ext/hash/keys"
3
+ require "active_support/core_ext/hash/reverse_merge"
4
+
5
+ module Cachext
6
+ class Multi
7
+ delegate :cache, :default_errors, :error_logger, to: :@config
8
+
9
+ def initialize config, key_base, options = {}
10
+ @config = config
11
+ @key_base = key_base
12
+ @options = options
13
+ end
14
+
15
+ def fetch ids, &block
16
+ records = FindByIds.new(self, ids, block).records
17
+
18
+ if @options.fetch(:return_array, false)
19
+ records.values + missing_records(ids - records.keys)
20
+ else
21
+ records
22
+ end
23
+ end
24
+
25
+ def key id
26
+ @key_base + [id]
27
+ end
28
+
29
+ def expires_in
30
+ @options.fetch :expires_in, @config.default_expires_in
31
+ end
32
+
33
+ private
34
+
35
+ def missing_records ids
36
+ ids.map { |id| MissingRecord.new id }
37
+ end
38
+
39
+ class FindByIds
40
+ attr_reader :multi, :ids
41
+
42
+ delegate :cache, to: :multi
43
+
44
+ def initialize(multi, ids, lookup)
45
+ @multi = multi
46
+ @ids = ids
47
+ @lookup = lookup
48
+ end
49
+
50
+ def records
51
+ fresh_cached.merge(direct).reverse_merge(stale)
52
+ end
53
+
54
+ private
55
+
56
+ def fresh_cached
57
+ @fresh_cached ||= cache.read_multi(*ids.map { |id| multi.key(id) }).
58
+ transform_keys { |key| key.last }
59
+ end
60
+
61
+ def uncached_or_stale_ids
62
+ ids - fresh_cached.keys
63
+ end
64
+
65
+ def direct
66
+ @direct ||= if uncached_or_stale_ids.length > 0
67
+ records = uncached_where uncached_or_stale_ids
68
+ write_cache records
69
+ records
70
+ else
71
+ {}
72
+ end
73
+ end
74
+
75
+ def write_cache records
76
+ records.each do |id, record|
77
+ key = Key.new(multi.key(id))
78
+ key.write record, expires_in: multi.expires_in
79
+ key.write_backup record
80
+ end
81
+ end
82
+
83
+ def delete_backups ids
84
+ return if ids.blank?
85
+
86
+ ids.each do |id|
87
+ key = Key.new(multi.key(id))
88
+ key.delete_backup
89
+ end
90
+ end
91
+
92
+ def stale
93
+ cache.read_multi(*(uncached_or_stale_ids - direct.keys).map { |id| [:backup_cache] + multi.key(id) }).
94
+ transform_keys { |key| key.last }
95
+ end
96
+
97
+ def uncached_where ids
98
+ records = @lookup.call ids
99
+
100
+ if records.is_a?(Array)
101
+ records = records.each_with_object({}) do |record, acc|
102
+ acc[record.id] = record
103
+ end
104
+ end
105
+
106
+ delete_backups ids - records.keys
107
+ records
108
+ rescue *multi.default_errors => e
109
+ multi.error_logger.error e
110
+ {}
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,3 +1,3 @@
1
1
  module Cachext
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cachext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donald Plummer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-01 00:00:00.000000000 Z
11
+ date: 2015-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -191,6 +191,8 @@ files:
191
191
  - lib/cachext/features/default.rb
192
192
  - lib/cachext/features/lock.rb
193
193
  - lib/cachext/key.rb
194
+ - lib/cachext/missing_record.rb
195
+ - lib/cachext/multi.rb
194
196
  - lib/cachext/options.rb
195
197
  - lib/cachext/version.rb
196
198
  homepage: https://github.com/dplummer/cachext