looksist 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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