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 +4 -4
- data/HISTORY.txt +4 -0
- data/README.md +5 -0
- data/VERSION +1 -1
- data/lib/cassie/model.rb +32 -0
- data/lib/cassie/subscribers.rb +53 -0
- data/lib/cassie.rb +2 -1
- data/spec/cassie/model_spec.rb +10 -0
- data/spec/cassie/subscribers_spec.rb +63 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3ebdf5f386202ccb62aa4e9f4c10599111f18f6
|
4
|
+
data.tar.gz: 15e6f8b61b24160a946f5fd521b0f20bfc258366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d8e4275b346070a0549d52a782d3a0c403cf13c3b3d7e332469d6fa93b2335ce368e3243b2dce4b9dc49ac339bff3c7d3172095ad39298752b3eaf8808fa462
|
7
|
+
data.tar.gz: f6a73b42ef8301d095b9fa2a6910169cbfb7b42fd9b0fc1d1584c5a959b5350a1829893843179b0b8ab09116591157493778e485d544d5d39ae41c4846c9228b
|
data/HISTORY.txt
CHANGED
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.
|
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.
|
data/spec/cassie/model_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|