atomic_cache 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'store'
4
+
5
+ module AtomicCache
6
+ module Storage
7
+
8
+ # An abstract storage adapter which keeps all values in memory
9
+ class Memory < Store
10
+
11
+ # @abstract implement returning a Hash of the in-memory representation
12
+ def store; raise NotImplementedError end
13
+
14
+ # @abstract implement performing an operation on the store
15
+ def store_op(key, user_options=nil); raise NotImplementedError end
16
+
17
+ def add(raw_key, new_value, ttl, user_options=nil)
18
+ store_op(raw_key, user_options) do |key, options|
19
+ return false if store.has_key?(key)
20
+ write(key, new_value, ttl)
21
+ end
22
+ end
23
+
24
+ def read(raw_key, user_options=nil)
25
+ store_op(raw_key, user_options) do |key, options|
26
+ entry = store[key]
27
+ return nil unless entry.present?
28
+
29
+ return entry[:value] if entry[:ttl].nil? or entry[:ttl] == false
30
+
31
+ life = Time.now - entry[:written_at]
32
+ if (life >= entry[:ttl])
33
+ store.delete(key)
34
+ nil
35
+ else
36
+ entry[:value]
37
+ end
38
+ end
39
+ end
40
+
41
+ def set(raw_key, new_value, user_options=nil)
42
+ store_op(raw_key, user_options) do |key, options|
43
+ write(key, new_value, options[:expires_in])
44
+ end
45
+ end
46
+
47
+ def delete(raw_key)
48
+ store_op(raw_key) do |key, options|
49
+ store.delete(key)
50
+ true
51
+ end
52
+ end
53
+
54
+ def write(key, value, ttl=nil)
55
+ stored_value = value.to_s
56
+ stored_value = nil if value.nil?
57
+
58
+ store[key] = {
59
+ value: stored_value,
60
+ ttl: ttl || false,
61
+ written_at: Time.now
62
+ }
63
+ true
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'memory'
4
+
5
+ module AtomicCache
6
+ module Storage
7
+
8
+ # A storage adapter which keeps all values in memory, global to all threads
9
+ class SharedMemory < Memory
10
+ STORE = {}
11
+ SEMAPHORE = Mutex.new
12
+
13
+ def self.reset
14
+ STORE.clear
15
+ end
16
+
17
+ def self.store
18
+ STORE
19
+ end
20
+
21
+ def reset
22
+ self.class.reset
23
+ end
24
+
25
+ def store
26
+ STORE
27
+ end
28
+
29
+ def store_op(key, user_options=nil)
30
+ normalized_key = key.to_sym
31
+ user_options ||= {}
32
+
33
+ SEMAPHORE.synchronize do
34
+ yield(normalized_key, user_options)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'memory'
4
+
5
+ module AtomicCache
6
+ module Storage
7
+
8
+ class Store
9
+
10
+ # @abstract (String, Object, Integer, Hash) -> Boolean
11
+ # ttl is in millis
12
+ # operation must be atomic
13
+ # returns true when the key doesn't exist and was written successfully
14
+ # returns false in all other cases
15
+ def add(key, new_value, ttl, user_options); raise NotImplementedError end
16
+
17
+ # @abstract (String, Hash) -> String
18
+ # return the `value` at `key`
19
+ def read(key, user_options); raise NotImplementedError end
20
+
21
+ # @abstract (String, Object) -> Boolean
22
+ # returns true if it succeeds; false otherwise
23
+ def set(key, new_value, user_options); raise NotImplementedError end
24
+
25
+ # @abstract (String) -> Boolean
26
+ # returns true if it succeeds; false otherwise
27
+ def delete(key, user_options); raise NotImplementedError end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AtomicCache
4
+ VERSION = "0.1.0.rc1"
5
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atomic_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Ibotta Developers
8
+ - Titus Stone
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2018-02-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.14'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.14'
28
+ - !ruby/object:Gem::Dependency
29
+ name: gems
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 1.0.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: simplecov
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.15'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.15'
84
+ - !ruby/object:Gem::Dependency
85
+ name: timecop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.8.1
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.8.1
98
+ - !ruby/object:Gem::Dependency
99
+ name: activesupport
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '4.2'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '4.2'
112
+ - !ruby/object:Gem::Dependency
113
+ name: murmurhash3
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '0.1'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '0.1'
126
+ description: desc
127
+ email: osscompliance@ibotta.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".ruby_version"
134
+ - ".travis.yml"
135
+ - CODE_OF_CONDUCT.md
136
+ - Gemfile
137
+ - LICENSE
138
+ - README.md
139
+ - Rakefile
140
+ - atomic_cache.gemspec
141
+ - bin/console
142
+ - bin/setup
143
+ - docs/ARCH.md
144
+ - docs/INTERFACES.md
145
+ - docs/MODEL_SETUP.md
146
+ - docs/PROJECT_SETUP.md
147
+ - docs/USAGE.md
148
+ - docs/img/quick_retry_graph.png
149
+ - lib/atomic_cache.rb
150
+ - lib/atomic_cache/atomic_cache_client.rb
151
+ - lib/atomic_cache/concerns/global_lmt_cache_concern.rb
152
+ - lib/atomic_cache/default_config.rb
153
+ - lib/atomic_cache/key/keyspace.rb
154
+ - lib/atomic_cache/key/last_mod_time_key_manager.rb
155
+ - lib/atomic_cache/storage/dalli.rb
156
+ - lib/atomic_cache/storage/instance_memory.rb
157
+ - lib/atomic_cache/storage/memory.rb
158
+ - lib/atomic_cache/storage/shared_memory.rb
159
+ - lib/atomic_cache/storage/store.rb
160
+ - lib/atomic_cache/version.rb
161
+ homepage: https://github.com/ibotta/atomic_cache
162
+ licenses:
163
+ - apache 2.0
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">"
177
+ - !ruby/object:Gem::Version
178
+ version: 1.3.1
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.6.11
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: summary
185
+ test_files: []