looksist 0.2.3 → 0.2.4

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: 3505080addc197736b40fd6384223c3f116d94bc
4
- data.tar.gz: 9a3303eb8dd99a337dfb74e669ce9cfd970294ce
3
+ metadata.gz: 3fb62a2a0b2778134b40201016d38980393ee389
4
+ data.tar.gz: 6621c86b40473717e6e077c004506d0f79482d88
5
5
  SHA512:
6
- metadata.gz: e1606ba5e94a4a323a6ce83b4c7804519bb169ba670bba6d7fc29da7488ac972d459815277b904c631b0932d62a54bab8f4bf34d8a5fbc6257daf3d822437446
7
- data.tar.gz: f72d42711b96d872d972f397b94c6104724e32cb93d2b4cb7bfdf159522f1d11d8bcbbfa6aff5a65b9bc7dc73f26f53ef96c20d9e59f2d5bf17ac72760ffe7c8
6
+ metadata.gz: 2bca80bd21a7a699b332930bdc5396f52e60a23b8e61acee6df1b0f42e92685a64b0a7c1658710a4f9aa610b83db50ed7ebc9fb8b50fa1d4ace9a2a257d4414f
7
+ data.tar.gz: 35937a98b7ff7e8e2edf52aa49424b04c8ec95eb0186b7c4e0b0bf3b8b2adce85374f69365ac3b5c261b907964eaa8ca84a24f9d937c728ff438c8fafc2ae080
@@ -29,5 +29,6 @@ I18n.enforce_available_locales = false
29
29
 
30
30
  Looksist.configure do |looksist|
31
31
  looksist.lookup_store = Redis.new(url: 'redis://localhost:6379', driver: :hiredis)
32
+ looksist.l2_cache = :no_cache
32
33
  looksist.driver = Looksist::Serializers::Her
33
- end
34
+ end
data/lib/looksist.rb CHANGED
@@ -15,13 +15,13 @@ module Looksist
15
15
  include Hashed
16
16
 
17
17
  class << self
18
- attr_accessor :lookup_store, :driver, :cache_buffer_size, :redis_service
18
+ attr_accessor :lookup_store, :driver, :cache_buffer_size, :redis_service, :l2_cache
19
19
 
20
20
  def configure
21
21
  yield self
22
22
  self.redis_service = Looksist::RedisService.instance do |lookup|
23
23
  lookup.client = self.lookup_store
24
- lookup.buffer_size = self.cache_buffer_size || 50000
24
+ lookup.buffer_size = (self.l2_cache == :no_cache) ? 0 : (self.cache_buffer_size || 50000)
25
25
  end
26
26
  end
27
27
 
@@ -32,14 +32,22 @@ module Looksist
32
32
  private
33
33
 
34
34
  def find_all(entity, ids)
35
- raise 'Buffer overflow! Increase buffer size' if ids.length > @buffer_size
35
+ raise 'Buffer overflow! Increase buffer size' if ids.length > @buffer_size && @buffer_size != 0
36
36
  keys = ids.collect { |id| redis_key(entity, id) }
37
- missed_keys = (keys - @cache.keys).uniq
37
+ missed_keys = cache_op(proc_from { keys.uniq }) { (keys - @cache.keys).uniq }
38
38
  unless missed_keys.empty?
39
39
  values = @client.mget *missed_keys
40
- @cache.merge!(Hash[*missed_keys.zip(values).flatten])
40
+ cache_op { @cache.merge!(Hash[*missed_keys.zip(values).flatten]) }
41
+ end
42
+ (cache_op(proc_from { values }) { @cache.mslice(keys) })
43
+ end
44
+
45
+ def cache_op(computed = nil)
46
+ if @buffer_size == 0
47
+ return computed.call if computed
48
+ else
49
+ yield
41
50
  end
42
- @cache.mslice(keys)
43
51
  end
44
52
 
45
53
  def find(entity, id)
@@ -50,11 +58,15 @@ module Looksist
50
58
  end
51
59
 
52
60
  def fetch(key, &block)
53
- @cache[key] ||= block.call
61
+ (cache_op(proc_from { block.call }) { @cache[key] ||= block.call })
54
62
  end
55
63
 
56
64
  def redis_key(entity, id)
57
65
  "#{entity.pluralize}/#{id}"
58
66
  end
67
+
68
+ def proc_from
69
+ Proc.new
70
+ end
59
71
  end
60
72
  end
@@ -1,3 +1,3 @@
1
1
  module Lookist
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
@@ -10,7 +10,6 @@ describe Looksist::Hashed do
10
10
  end
11
11
 
12
12
  context 'inject ' do
13
-
14
13
  it 'should be capable to deep lookup and inject' do
15
14
  class Menu
16
15
  include Looksist
@@ -2,232 +2,294 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe Looksist do
5
- before(:each) do
6
- @mock = {}
7
- Looksist.configure do |looksist|
8
- looksist.lookup_store = @mock
9
- looksist.driver = Looksist::Serializers::Her
5
+ context 'no l2 cache' do
6
+ before(:each) do
7
+ @mock = {}
8
+ Looksist.configure do |looksist|
9
+ looksist.lookup_store = @mock
10
+ looksist.l2_cache = :no_cache
11
+ looksist.driver = Looksist::Serializers::Her
12
+ end
10
13
  end
11
- end
12
-
13
- context 'Serialization Support' do
14
- it 'should decorate for her models' do
15
- module Her
16
- class Employee
17
- include Her::Model
18
- use_api TEST_API
19
- include Looksist
20
-
21
- lookup :name, using: :employee_id
22
-
23
- def as_json(opts)
24
- super(opts).merge(another_attr: 'Hello World')
14
+ context 'Serialization Support' do
15
+ it 'should decorate for her models' do
16
+ module Her
17
+ class NoCacheEmployee
18
+ include Her::Model
19
+ use_api TEST_API
20
+ include Looksist
21
+
22
+ lookup :name, using: :employee_id
23
+
24
+ def as_json(opts)
25
+ super(opts).merge(another_attr: 'Hello World')
26
+ end
25
27
  end
26
28
  end
29
+
30
+ expect(@mock).to receive(:get).twice.with('employees/1').and_return('Employee Name')
31
+ e = Her::NoCacheEmployee.new({employee_id: 1})
32
+ expect(e.name).to eq('Employee Name')
33
+ expect(e.to_json).to eq({:employee_id => 1, :name => 'Employee Name', :another_attr => 'Hello World'}.to_json)
27
34
  end
28
- expect(@mock).to receive(:get).once.with('employees/1').and_return('Employee Name')
29
- e = Her::Employee.new({employee_id: 1})
30
- expect(e.name).to eq('Employee Name')
31
- expect(e.to_json).to eq({:employee_id => 1, :name => 'Employee Name', :another_attr => 'Hello World'}.to_json)
32
35
  end
33
- end
34
-
35
- context 'Store Lookup' do
36
- it 'should consider bucket key when provided' do
37
- module ExplicitBucket
38
- class Employee
39
- include Looksist
40
- attr_accessor :id
41
- lookup :name, using: :id, bucket_name: 'employees'
42
36
 
43
- def initialize(id)
44
- @id = id
37
+ context 'Alias Lookup' do
38
+ it 'should fetch attributes and use the alias for specific attributes in the api' do
39
+ module AliasSpecificLookup
40
+ class NoCacheEmployee
41
+ include Her::Model
42
+ use_api TEST_API
43
+ include Looksist
44
+ attr_accessor :id
45
+ lookup [:name, :age], using: :id, as: {name: 'nome'}
46
+
47
+ def initialize(id)
48
+ @id = id
49
+ end
50
+
51
+ def as_json(opts)
52
+ super(opts).merge(id: @id)
53
+ end
45
54
  end
46
55
  end
56
+ expect(@mock).to receive(:get).exactly(4).times.with('ids/1').and_return({name: 'Rajini', age: 16}.to_json)
57
+ e = AliasSpecificLookup::NoCacheEmployee.new(1)
58
+ expect(e.nome).to eq('Rajini')
59
+ expect(e.age).to eq(16)
60
+ expect(e.to_json).to eq("{\"nome\":\"Rajini\",\"age\":16,\"id\":1}")
47
61
  end
48
- expect(@mock).to receive(:get).once.with('employees/1').and_return('Employee Name')
49
- e = ExplicitBucket::Employee.new(1)
50
- expect(e.name).to eq('Employee Name')
51
62
  end
52
63
  end
64
+ context 'with l2 cache' do
65
+ before(:each) do
66
+ @mock = {}
67
+ Looksist.configure do |looksist|
68
+ looksist.lookup_store = @mock
69
+ looksist.l2_cache = :cached
70
+ looksist.driver = Looksist::Serializers::Her
71
+ end
72
+ end
53
73
 
54
- context 'Tolerant lookup' do
55
- it 'should not do a lookup when the key attribute is not defined' do
56
- module TolerantLookUp
57
- class Employee
58
- include Her::Model
59
- use_api TEST_API
60
- include Looksist
74
+ context 'Serialization Support' do
75
+ it 'should decorate for her models' do
76
+ module Her
77
+ class Employee
78
+ include Her::Model
79
+ use_api TEST_API
80
+ include Looksist
61
81
 
62
- lookup :name, using: :employee_id
82
+ lookup :name, using: :employee_id
63
83
 
64
- def as_json(opts)
65
- super(opts)
84
+ def as_json(opts)
85
+ super(opts).merge(another_attr: 'Hello World')
86
+ end
66
87
  end
67
88
  end
89
+ expect(@mock).to receive(:get).once.with('employees/1').and_return('Employee Name')
90
+ e = Her::Employee.new({employee_id: 1})
91
+ expect(e.name).to eq('Employee Name')
92
+ expect(e.to_json).to eq({:employee_id => 1, :name => 'Employee Name', :another_attr => 'Hello World'}.to_json)
68
93
  end
69
- expect(@mock).to receive(:get).never.with('employees_/1')
70
- e = TolerantLookUp::Employee.new
71
- expect(e.to_json).to eq('{}')
72
94
  end
73
- end
74
-
75
- context 'Alias support for lookup' do
76
- it 'should fetch attributes and use the alias specified in the api' do
77
- module AliasLookup
78
- class Employee
79
- include Her::Model
80
- use_api TEST_API
81
- include Looksist
82
- attr_accessor :id
83
- lookup :name, using: :id, bucket_name: 'employees', as: {name: 'nome'}
84
-
85
- def initialize(id)
86
- @id = id
87
- end
88
95
 
89
- def as_json(opts)
90
- super(opts).merge(id: @id)
96
+ context 'Store Lookup' do
97
+ it 'should consider bucket key when provided' do
98
+ module ExplicitBucket
99
+ class Employee
100
+ include Looksist
101
+ attr_accessor :id
102
+ lookup :name, using: :id, bucket_name: 'employees'
103
+
104
+ def initialize(id)
105
+ @id = id
106
+ end
91
107
  end
92
108
  end
109
+ expect(@mock).to receive(:get).once.with('employees/1').and_return('Employee Name')
110
+ e = ExplicitBucket::Employee.new(1)
111
+ expect(e.name).to eq('Employee Name')
93
112
  end
94
- expect(@mock).to receive(:get).once.with('employees/1').and_return('Rajini')
95
- e = AliasLookup::Employee.new(1)
96
- expect(e.nome).to eq('Rajini')
97
- expect(e.to_json).to eq("{\"nome\":\"Rajini\",\"id\":1}")
98
113
  end
99
114
 
100
- it 'should fetch attributes and use the alias for specific attributes in the api' do
101
- module AliasSpecificLookup
102
- class Employee
103
- include Her::Model
104
- use_api TEST_API
105
- include Looksist
106
- attr_accessor :id
107
- lookup [:name, :age], using: :id, as: {name: 'nome'}
115
+ context 'Tolerant lookup' do
116
+ it 'should not do a lookup when the key attribute is not defined' do
117
+ module TolerantLookUp
118
+ class Employee
119
+ include Her::Model
120
+ use_api TEST_API
121
+ include Looksist
108
122
 
109
- def initialize(id)
110
- @id = id
111
- end
123
+ lookup :name, using: :employee_id
112
124
 
113
- def as_json(opts)
114
- super(opts).merge(id: @id)
125
+ def as_json(opts)
126
+ super(opts)
127
+ end
115
128
  end
116
129
  end
130
+ expect(@mock).to receive(:get).never.with('employees_/1')
131
+ e = TolerantLookUp::Employee.new
132
+ expect(e.to_json).to eq('{}')
117
133
  end
118
- expect(@mock).to receive(:get).once.with('ids/1').and_return({name: 'Rajini', age: 16}.to_json)
119
- e = AliasSpecificLookup::Employee.new(1)
120
- expect(e.nome).to eq('Rajini')
121
- expect(e.age).to eq(16)
122
- expect(e.to_json).to eq("{\"nome\":\"Rajini\",\"age\":16,\"id\":1}")
123
134
  end
124
- end
125
-
126
- context 'Lazy Evaluation' do
127
- module LazyEval
128
- class HerEmployee
129
- include Her::Model
130
- use_api TEST_API
131
- include Looksist
132
-
133
- lookup :name, using: :employee_id
134
135
 
135
- def as_json(opts)
136
- super(opts).merge(another_attr: 'Hello World')
136
+ context 'Alias support for lookup' do
137
+ it 'should fetch attributes and use the alias specified in the api' do
138
+ module AliasLookup
139
+ class Employee
140
+ include Her::Model
141
+ use_api TEST_API
142
+ include Looksist
143
+ attr_accessor :id
144
+ lookup :name, using: :id, bucket_name: 'employees', as: {name: 'nome'}
145
+
146
+ def initialize(id)
147
+ @id = id
148
+ end
149
+
150
+ def as_json(opts)
151
+ super(opts).merge(id: @id)
152
+ end
153
+ end
137
154
  end
155
+ expect(@mock).to receive(:get).once.with('employees/1').and_return('Rajini')
156
+ e = AliasLookup::Employee.new(1)
157
+ expect(e.nome).to eq('Rajini')
158
+ expect(e.to_json).to eq("{\"nome\":\"Rajini\",\"id\":1}")
138
159
  end
139
- class Employee
140
- include Looksist
141
- attr_accessor :id
142
- lookup :name, using: :id, bucket_name: 'employees'
143
160
 
144
- def initialize(id)
145
- @id = id
161
+ it 'should fetch attributes and use the alias for specific attributes in the api' do
162
+ module AliasSpecificLookup
163
+ class Employee
164
+ include Her::Model
165
+ use_api TEST_API
166
+ include Looksist
167
+ attr_accessor :id
168
+ lookup [:name, :age], using: :id, as: {name: 'nome'}
169
+
170
+ def initialize(id)
171
+ @id = id
172
+ end
173
+
174
+ def as_json(opts)
175
+ super(opts).merge(id: @id)
176
+ end
177
+ end
146
178
  end
179
+ expect(@mock).to receive(:get).once.with('ids/1').and_return({name: 'Rajini', age: 16}.to_json)
180
+ e = AliasSpecificLookup::Employee.new(1)
181
+ expect(e.nome).to eq('Rajini')
182
+ expect(e.age).to eq(16)
183
+ expect(e.to_json).to eq("{\"nome\":\"Rajini\",\"age\":16,\"id\":1}")
147
184
  end
148
185
  end
149
- it 'should not eager evaluate' do
150
- expect(@mock).to_not receive(:get)
151
- LazyEval::Employee.new(1)
152
- LazyEval::HerEmployee.new(employee_id: 1)
153
- end
154
- end
155
186
 
156
- context 'lookup attributes' do
157
- it 'should generate declarative attributes on the model with simple lookup value' do
158
- module SimpleLookup
187
+ context 'Lazy Evaluation' do
188
+ module LazyEval
189
+ class HerEmployee
190
+ include Her::Model
191
+ use_api TEST_API
192
+ include Looksist
193
+
194
+ lookup :name, using: :employee_id
195
+
196
+ def as_json(opts)
197
+ super(opts).merge(another_attr: 'Hello World')
198
+ end
199
+ end
159
200
  class Employee
160
201
  include Looksist
161
- attr_accessor :id, :employee_id
162
- lookup :name, using: :id
163
- lookup :unavailable, using: :employee_id
202
+ attr_accessor :id
203
+ lookup :name, using: :id, bucket_name: 'employees'
164
204
 
165
205
  def initialize(id)
166
- @id = @employee_id = id
206
+ @id = id
167
207
  end
168
208
  end
169
209
  end
170
-
171
- expect(@mock).to receive(:get).once.with('ids/1').and_return('Employee Name')
172
- expect(@mock).to receive(:get).once.with('employees/1').and_return(nil)
173
- e = SimpleLookup::Employee.new(1)
174
- expect(e.name).to eq('Employee Name')
175
- expect(e.unavailable).to be(nil)
210
+ it 'should not eager evaluate' do
211
+ expect(@mock).to_not receive(:get)
212
+ LazyEval::Employee.new(1)
213
+ LazyEval::HerEmployee.new(employee_id: 1)
214
+ end
176
215
  end
177
216
 
178
- it 'should generate declarative attributes on the model with object based lookup value' do
179
- module CompositeLookup
180
- class Employee
181
- include Looksist
182
- attr_accessor :id, :employee_id, :contact_id
217
+ context 'lookup attributes' do
218
+ it 'should generate declarative attributes on the model with simple lookup value' do
219
+ module SimpleLookup
220
+ class Employee
221
+ include Looksist
222
+ attr_accessor :id, :employee_id
223
+ lookup :name, using: :id
224
+ lookup :unavailable, using: :employee_id
225
+
226
+ def initialize(id)
227
+ @id = @employee_id = id
228
+ end
229
+ end
230
+ end
183
231
 
184
- lookup [:name, :location], using: :id
185
- lookup [:age, :sex], using: :employee_id
186
- lookup [:pager, :cell], using: :contact_id
232
+ expect(@mock).to receive(:get).once.with('ids/1').and_return('Employee Name')
233
+ expect(@mock).to receive(:get).once.with('employees/1').and_return(nil)
234
+ e = SimpleLookup::Employee.new(1)
235
+ expect(e.name).to eq('Employee Name')
236
+ expect(e.unavailable).to be(nil)
237
+ end
187
238
 
188
- def initialize(id)
189
- @contact_id = @id = @employee_id = id
239
+ it 'should generate declarative attributes on the model with object based lookup value' do
240
+ module CompositeLookup
241
+ class Employee
242
+ include Looksist
243
+ attr_accessor :id, :employee_id, :contact_id
244
+
245
+ lookup [:name, :location], using: :id
246
+ lookup [:age, :sex], using: :employee_id
247
+ lookup [:pager, :cell], using: :contact_id
248
+
249
+ def initialize(id)
250
+ @contact_id = @id = @employee_id = id
251
+ end
190
252
  end
191
253
  end
192
- end
193
254
 
194
- expect(@mock).to receive(:get).once.with('ids/1').and_return({name: 'Employee Name', location: 'Chennai'}.to_json)
195
- expect(@mock).to receive(:get).once.with('contacts/1').and_return({pager: 'pager', cell: 'cell'}.to_json)
196
- expect(@mock).to receive(:get).twice.with('employees/1').and_return(nil)
197
- e = CompositeLookup::Employee.new(1)
255
+ expect(@mock).to receive(:get).once.with('ids/1').and_return({name: 'Employee Name', location: 'Chennai'}.to_json)
256
+ expect(@mock).to receive(:get).once.with('contacts/1').and_return({pager: 'pager', cell: 'cell'}.to_json)
257
+ expect(@mock).to receive(:get).twice.with('employees/1').and_return(nil)
258
+ e = CompositeLookup::Employee.new(1)
198
259
 
199
- expect(e.name).to eq('Employee Name')
200
- expect(e.location).to eq('Chennai')
260
+ expect(e.name).to eq('Employee Name')
261
+ expect(e.location).to eq('Chennai')
201
262
 
202
- expect(e.age).to eq(nil)
203
- expect(e.sex).to eq(nil)
263
+ expect(e.age).to eq(nil)
264
+ expect(e.sex).to eq(nil)
204
265
 
205
- expect(e.pager).to eq('pager')
206
- expect(e.cell).to eq('cell')
266
+ expect(e.pager).to eq('pager')
267
+ expect(e.cell).to eq('cell')
268
+ end
207
269
  end
208
- end
209
270
 
210
- context 'share storage between instances' do
211
- class Employee
212
- include Looksist
213
- attr_accessor :id
271
+ context 'share storage between instances' do
272
+ class Employee
273
+ include Looksist
274
+ attr_accessor :id
214
275
 
215
- lookup [:name, :location], using: :id
276
+ lookup [:name, :location], using: :id
216
277
 
217
- def initialize(id)
218
- @id = id
278
+ def initialize(id)
279
+ @id = id
280
+ end
219
281
  end
220
- end
221
- it 'should share storage between instances to improve performance' do
222
- employee_first_instance = Employee.new(1)
223
- expect(@mock).to receive(:get).once.with('ids/1')
224
- .and_return({name: 'Employee Name', location: 'Chennai'}.to_json)
225
- employee_first_instance.name
282
+ it 'should share storage between instances to improve performance' do
283
+ employee_first_instance = Employee.new(1)
284
+ expect(@mock).to receive(:get).once.with('ids/1')
285
+ .and_return({name: 'Employee Name', location: 'Chennai'}.to_json)
286
+ employee_first_instance.name
226
287
 
227
- employee_second_instance = Employee.new(1)
228
- expect(@mock).not_to receive(:get).with('ids/1')
288
+ employee_second_instance = Employee.new(1)
289
+ expect(@mock).not_to receive(:get).with('ids/1')
229
290
 
230
- employee_second_instance.name
291
+ employee_second_instance.name
292
+ end
231
293
  end
232
294
  end
233
295
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: looksist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - RC