whi-cassie 1.0.6 → 1.0.7

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: f85b689086bd176a805cd0fcdd9ba9cab4980d75
4
- data.tar.gz: e596bacb6ddd3393c5d1fd93d49da61d1898333b
3
+ metadata.gz: d3ebdf5f386202ccb62aa4e9f4c10599111f18f6
4
+ data.tar.gz: 15e6f8b61b24160a946f5fd521b0f20bfc258366
5
5
  SHA512:
6
- metadata.gz: de080c2f8d0a523d754dbfa0aee4215cc64923e1f122c6ddce85a58c7becb97b02616540cdc880b1dd2c993aed89396f91123393cd374f4b90189da5fc571871
7
- data.tar.gz: 2bc5d0e2ea0aa0e8ee43cbe86789b497ad8e421bda9365bcf4d5493e1ddeec647b22383e89ca35c8f254d9e5d5056389cd4fafd346de8ede7a9493792c546fae
6
+ metadata.gz: 8d8e4275b346070a0549d52a782d3a0c403cf13c3b3d7e332469d6fa93b2335ce368e3243b2dce4b9dc49ac339bff3c7d3172095ad39298752b3eaf8808fa462
7
+ data.tar.gz: f6a73b42ef8301d095b9fa2a6910169cbfb7b42fd9b0fc1d1584c5a959b5350a1829893843179b0b8ab09116591157493778e485d544d5d39ae41c4846c9228b
data/HISTORY.txt CHANGED
@@ -1,3 +1,7 @@
1
+ 1.0.7
2
+
3
+ Add find_subscribers to Cassie::Model for instrumenting model find calls.
4
+
1
5
  1.0.6
2
6
 
3
7
  Wrap raw CQL in a Simple statement for code consistency in subscribers.
data/README.md CHANGED
@@ -212,6 +212,11 @@ You can add instrumentation via subscribers to the `Cassie.instance`. Subscriber
212
212
  Cassie.instance.subscribers << lambda{|message| logger.warn("CQL: #{message.statement.cql} with #{message.options} took #{message.elapsed_time}s") if message.elapsed_time > 0.5 && message.statement.cql}
213
213
  ```
214
214
 
215
+ You can instrument the finding code on your model by adding a find subscriber either to the model or to Cassie::Model. These subscribers take a block which is yielded to with the CQL, arguments, options, elapsed time, and rows returned.
216
+ ```
217
+ Cassie::Model.find_subscribers << lambda{|message| logger.warn("CQL: #{message.cql}; Rows: #{message.rows}; Time: #{message.elapsed_time}")
218
+ ```
219
+
215
220
  ### Limitations
216
221
 
217
222
  Ruby 2.0 (or compatible) required.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 1.0.7
data/lib/cassie/model.rb CHANGED
@@ -47,10 +47,33 @@ module Cassie::Model
47
47
  class_attribute :_column_aliases, :instance_reader => false, :instance_writer => false
48
48
  class_attribute :_ordering_keys, :instance_reader => false, :instance_writer => false
49
49
  class_attribute :_counter_table, :instance_reader => false, :instance_writer => false
50
+ class_attribute :find_subscribers, :instance_reader => false, :instance_writer => false
50
51
  define_model_callbacks :create, :update, :save, :destroy
51
52
  self._columns = {}
52
53
  self._column_aliases = HashWithIndifferentAccess.new
53
54
  self._ordering_keys = {}
55
+ self.find_subscribers = Cassie::Subscribers.new(Cassie::Model.find_subscribers)
56
+ end
57
+
58
+ class << self
59
+ @@find_subscribers = Cassie::Subscribers.new
60
+
61
+ def find_subscribers
62
+ @@find_subscribers
63
+ end
64
+ end
65
+
66
+ # Message sent to find subscribers for instrumenting find operations.
67
+ class FindMessage
68
+ attr_reader :cql, :args, :options, :elapsed_time, :rows
69
+
70
+ def initialize(cql, args, options, elapsed_time, rows)
71
+ @cql = cql
72
+ @args = args
73
+ @options = options
74
+ @elapsed_time = elapsed_time
75
+ @rows = rows
76
+ end
54
77
  end
55
78
 
56
79
  module ClassMethods
@@ -186,6 +209,7 @@ module Cassie::Model
186
209
  # You can provide a block to this method in which case it will yield each
187
210
  # record as it is foundto the block instead of returning them.
188
211
  def find_all(where:, select: nil, order: nil, limit: nil, options: nil)
212
+ start_time = Time.now
189
213
  columns = (select ? Array(select).collect{|c| column_name(c)} : column_names)
190
214
  cql = "SELECT #{columns.join(', ')} FROM #{full_table_name}"
191
215
  values = nil
@@ -209,7 +233,9 @@ module Cassie::Model
209
233
 
210
234
  results = connection.find(cql, values, options)
211
235
  records = [] unless block_given?
236
+ row_count = 0
212
237
  loop do
238
+ row_count += results.size
213
239
  results.each do |row|
214
240
  record = new(row)
215
241
  record.instance_variable_set(:@persisted, true)
@@ -222,6 +248,12 @@ module Cassie::Model
222
248
  break if results.last_page?
223
249
  results = results.next_page
224
250
  end
251
+
252
+ if find_subscribers && !find_subscribers.empty?
253
+ payload = FindMessage.new(cql, values, options, Time.now - start_time, row_count)
254
+ find_subscribers.each{|subscriber| subscriber.call(payload)}
255
+ end
256
+
225
257
  records
226
258
  end
227
259
 
@@ -0,0 +1,53 @@
1
+ # Thread safe list of subscribers. Each subscriber must respond to the :call method.
2
+ class Cassie::Subscribers
3
+
4
+ def initialize(parent_subscribers = nil)
5
+ @array = [].freeze
6
+ @lock = Mutex.new
7
+ @parent_subscribers = parent_subscribers
8
+ end
9
+
10
+ def add(subscriber)
11
+ @lock.synchronize do
12
+ new_array = @array.dup
13
+ new_array << subscriber
14
+ @array = new_array
15
+ end
16
+ end
17
+ alias_method :<<, :add
18
+
19
+ def remove(subscriber)
20
+ removed = nil
21
+ @lock.synchronize do
22
+ new_array = @array.dup
23
+ removed = new_array.delete(subscriber)
24
+ @array = new_array
25
+ end
26
+ removed
27
+ end
28
+ alias_method :delete, :remove
29
+
30
+ def clear
31
+ @array = []
32
+ end
33
+
34
+ def size
35
+ @array.size + (@parent_subscribers ? @parent_subscribers.size : 0)
36
+ end
37
+
38
+ def empty?
39
+ size == 0
40
+ end
41
+
42
+ def each(&block)
43
+ @array.each(&block)
44
+ if @parent_subscribers
45
+ @parent_subscribers.each(&block)
46
+ end
47
+ end
48
+
49
+ def include?(subscriber)
50
+ @array.include?(subscriber)
51
+ end
52
+
53
+ end
data/lib/cassie.rb CHANGED
@@ -4,6 +4,7 @@ require 'cassandra'
4
4
  # a foundation for maintaining a connection and constructing CQL statements.
5
5
  class Cassie
6
6
  require File.expand_path("../cassie/config.rb", __FILE__)
7
+ require File.expand_path("../cassie/subscribers.rb", __FILE__)
7
8
  require File.expand_path("../cassie/model.rb", __FILE__)
8
9
  require File.expand_path("../cassie/schema.rb", __FILE__)
9
10
  require File.expand_path("../cassie/testing.rb", __FILE__)
@@ -88,7 +89,7 @@ class Cassie
88
89
  @session = nil
89
90
  @prepared_statements = {}
90
91
  @last_prepare_warning = Time.now
91
- @subscribers = []
92
+ @subscribers = Subscribers.new
92
93
  end
93
94
 
94
95
  # Open a connection to the Cassandra cluster.
@@ -100,6 +100,16 @@ describe Cassie::Model do
100
100
  expect{ Cassie::Thing.find_all(where: {}) }.to raise_error(ArgumentError)
101
101
  Cassie::Thing.find_all(where: :all).size.should == 3
102
102
  end
103
+
104
+ it "should be able to add subscribers" do
105
+ global = nil
106
+ local = nil
107
+ Cassie::Model.find_subscribers << lambda{|info| global = info.rows}
108
+ Cassie::Thing.find_subscribers << lambda{|info| local = info.rows}
109
+ Cassie::Thing.find_all(where: {:owner => 1}).size.should == 2
110
+ global.should == 2
111
+ local.should == 2
112
+ end
103
113
  end
104
114
 
105
115
  describe "offset_to_id" do
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cassie::Subscribers do
4
+
5
+ it "should be able to add and remove a subscriber" do
6
+ subscribers = Cassie::Subscribers.new
7
+ expect(subscribers.empty?).to eq true
8
+ data_1 = []
9
+ data_2 = []
10
+ subscriber_1 = lambda{|info| data_1 << info}
11
+ subscriber_2 = lambda{|info| data_2 << info}
12
+ subscribers.add(subscriber_1)
13
+ subscribers << subscriber_2
14
+ expect(subscribers.empty?).to eq false
15
+ expect(subscribers.size).to eq 2
16
+ expect(subscribers.include?(subscriber_1)).to eq true
17
+ expect(subscribers.include?(subscriber_2)).to eq true
18
+
19
+ subscribers.each{|s| s.call(:payload)}
20
+ expect(data_1).to eq [:payload]
21
+ expect(data_2).to eq [:payload]
22
+
23
+ subscribers.remove(subscriber_2)
24
+ expect(subscribers.size).to eq 1
25
+ expect(subscribers.include?(subscriber_1)).to eq true
26
+ expect(subscribers.include?(subscriber_2)).to eq false
27
+
28
+ subscribers.each{|s| s.call(:more)}
29
+ expect(data_1).to eq [:payload, :more]
30
+ expect(data_2).to eq [:payload]
31
+
32
+ subscribers.delete(subscriber_1)
33
+ expect(subscribers.size).to eq 0
34
+ end
35
+
36
+ it "should have a hierarchy of subscribers" do
37
+ subscribers_1 = Cassie::Subscribers.new
38
+ subscribers_2 = Cassie::Subscribers.new(subscribers_1)
39
+ subscribers_3 = Cassie::Subscribers.new(subscribers_1)
40
+ data_1 = []
41
+ data_2 = []
42
+ data_3 = []
43
+ subscribers_1 << lambda{|info| data_1 << info}
44
+ subscribers_2 << lambda{|info| data_2 << info}
45
+
46
+ expect(subscribers_1.size).to eq 1
47
+ expect(subscribers_2.size).to eq 2
48
+ expect(subscribers_3.size).to eq 1
49
+
50
+ subscribers_1.each{|subscriber| subscriber.call(:payload_1)}
51
+ subscribers_2.each{|subscriber| subscriber.call(:payload_2)}
52
+ subscribers_3.each{|subscriber| subscriber.call(:payload_3)}
53
+
54
+ expect(data_1).to eq [:payload_1, :payload_2, :payload_3]
55
+ expect(data_2).to eq [:payload_2]
56
+
57
+ subscribers_2.clear
58
+ expect(subscribers_2.size).to eq 1
59
+ subscribers_1.clear
60
+ expect(subscribers_2.size).to eq 0
61
+ end
62
+
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whi-cassie
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - We Heart It
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-31 00:00:00.000000000 Z
12
+ date: 2016-06-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cassandra-driver
@@ -99,10 +99,12 @@ files:
99
99
  - lib/cassie/model.rb
100
100
  - lib/cassie/railtie.rb
101
101
  - lib/cassie/schema.rb
102
+ - lib/cassie/subscribers.rb
102
103
  - lib/cassie/testing.rb
103
104
  - lib/whi-cassie.rb
104
105
  - spec/cassie/config_spec.rb
105
106
  - spec/cassie/model_spec.rb
107
+ - spec/cassie/subscribers_spec.rb
106
108
  - spec/cassie_spec.rb
107
109
  - spec/models/thing.rb
108
110
  - spec/models/type_tester.rb
@@ -137,6 +139,7 @@ summary: Simple object mapper for Cassandra data tables specifically designed to
137
139
  test_files:
138
140
  - spec/cassie/config_spec.rb
139
141
  - spec/cassie/model_spec.rb
142
+ - spec/cassie/subscribers_spec.rb
140
143
  - spec/cassie_spec.rb
141
144
  - spec/models/thing.rb
142
145
  - spec/models/type_tester.rb