bucketer 0.0.1 → 0.0.2
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/README.md +21 -11
- data/bucketer.gemspec +2 -0
- data/lib/bucketer/in_memory.rb +23 -9
- data/lib/bucketer/version.rb +1 -1
- data/spec/bucketer_spec.rb +51 -64
- data/spec/in_memory_spec.rb +8 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_methods.rb +10 -0
- metadata +19 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 977bcdc41c9616bd1eb50f0c6ef7b38d477d2acb
|
4
|
+
data.tar.gz: 7fc0498334f0eb657dfba2a3d6bd8129d6cea23e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f10938119224521bfdc699037e64cda70193bf7f323d0a196524f62b28f46831cdbb335b81d180a709be5ea204eaf11bb71e2e23781deb8cfcf5eb18e4aa257
|
7
|
+
data.tar.gz: d326b7ff4de0a29d66d0a2821780c3a8da3ebcce3764f158b374cdbc8b07fa48112b7f806b3feb6114a93c3ef10e00bedc40b7f8a8ea1642c1e6bc8a65c1d696
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Bucketer
|
2
2
|
|
3
|
-
This is a generic
|
3
|
+
This is a generic EventMachine library for putting arbitrary objects into buckets and setting callbacks to be called when any bucket exceeds a specific threshold size. Although the `Bucketer::InMemory` is synchronous (it's just using a ruby hash) the interface is still what would be expected for an asynchronous API for consistency with other Bucketers to be implemented in future.
|
4
4
|
|
5
5
|
Currently an in memory bucketer is supported, however it is intended that a redis backed bucketer will be added later and it will be using em-hiredis gem for redis interaction and it will actually be asynchronous.
|
6
6
|
|
@@ -21,17 +21,27 @@ Or install it yourself as:
|
|
21
21
|
## Usage
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
bucketer
|
25
|
-
|
26
|
-
bucketer.
|
27
|
-
|
24
|
+
require 'bucketer'
|
25
|
+
EM.run do
|
26
|
+
bucketer = Bucketer::InMemory.new(:bucket_threshold_size => 5)
|
27
|
+
|
28
|
+
bucketer.on_bucket_full do |bucket_id|
|
29
|
+
p "yay bucket #{bucket_id} filled up!"
|
30
|
+
|
31
|
+
bucketer.get_and_empty_bucket(bucket_id) do |items|
|
32
|
+
EM.stop
|
33
|
+
items.each do |item|
|
34
|
+
p "got back #{item}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
bucketer.add_item("1", "1", {:foo => :bar}) {EM.stop}
|
40
|
+
bucketer.add_item("1", "2", {:foo => :bar}) {}
|
41
|
+
bucketer.add_item("1", "3", {:foo => :bar}) {}
|
42
|
+
bucketer.add_item("1", "4", {:bar => :foo}) {}
|
43
|
+
bucketer.add_item("1", "5", {:bar => :foo}) {}
|
28
44
|
end
|
29
|
-
|
30
|
-
bucketer.add_item("1", "1", {:foo => :bar})
|
31
|
-
bucketer.add_item("1", "2", {:foo => :bar})
|
32
|
-
bucketer.add_item("1", "3", {:foo => :bar})
|
33
|
-
bucketer.add_item("1", "4", {:bar => :foo})
|
34
|
-
bucketer.add_item("1", "5", {:bar => :foo})
|
35
45
|
```
|
36
46
|
|
37
47
|
## Contributing
|
data/bucketer.gemspec
CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
+
spec.add_runtime_dependency "eventmachine"
|
21
|
+
|
20
22
|
spec.add_development_dependency "bundler", "~> 1.6"
|
21
23
|
spec.add_development_dependency "rake"
|
22
24
|
spec.add_development_dependency "rspec"
|
data/lib/bucketer/in_memory.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
1
3
|
module Bucketer
|
2
4
|
# This is a purpose built class for storing arbitrary
|
3
5
|
# objects in buckets then calling callbacks when any
|
@@ -37,8 +39,11 @@ module Bucketer
|
|
37
39
|
# @param item [Object] the item to be
|
38
40
|
# placed in the bucket
|
39
41
|
def add_item(bucket_id, item_id, item, &blk)
|
40
|
-
|
41
|
-
|
42
|
+
EM::Completion.new.tap do |c|
|
43
|
+
c.callback(&blk) if block_given?
|
44
|
+
add_bucket_to_db(bucket_id, item_id, item) { c.succeed }
|
45
|
+
check_bucket_full(bucket_id)
|
46
|
+
end
|
42
47
|
end
|
43
48
|
|
44
49
|
# Used to set a callback hook for when a bucket
|
@@ -61,8 +66,11 @@ module Bucketer
|
|
61
66
|
# @yield [Array] the items you put
|
62
67
|
# into the bucket
|
63
68
|
def get_bucket(bucket_id, &blk)
|
64
|
-
|
65
|
-
blk
|
69
|
+
EM::Completion.new.tap do |c|
|
70
|
+
c.callback(&blk) if block_given?
|
71
|
+
get_bucket_from_db(bucket_id) do |bucket|
|
72
|
+
c.succeed bucket.values
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
68
76
|
|
@@ -73,9 +81,12 @@ module Bucketer
|
|
73
81
|
# @yield [Array] the items you put
|
74
82
|
# into the bucket
|
75
83
|
def get_and_empty_bucket(bucket_id, &blk)
|
76
|
-
|
77
|
-
|
78
|
-
|
84
|
+
EM::Completion.new.tap do |c|
|
85
|
+
c.callback(&blk) if block_given?
|
86
|
+
get_bucket(bucket_id) do |contents|
|
87
|
+
empty_bucket(bucket_id) do
|
88
|
+
c.succeed contents
|
89
|
+
end
|
79
90
|
end
|
80
91
|
end
|
81
92
|
end
|
@@ -85,8 +96,11 @@ module Bucketer
|
|
85
96
|
# @param bucket_id [String] the bucket id
|
86
97
|
# of the bucket you want to empty
|
87
98
|
def empty_bucket(bucket_id, &blk)
|
88
|
-
|
89
|
-
blk
|
99
|
+
EM::Completion.new.tap do |c|
|
100
|
+
c.callback(&blk) if block_given?
|
101
|
+
empty_bucket_in_db(bucket_id) do
|
102
|
+
c.succeed
|
103
|
+
end
|
90
104
|
end
|
91
105
|
end
|
92
106
|
|
data/lib/bucketer/version.rb
CHANGED
data/spec/bucketer_spec.rb
CHANGED
@@ -1,93 +1,80 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'bucketer'
|
3
3
|
|
4
|
-
|
5
|
-
let(:bucketer) { Bucketer::InMemory.new(:bucket_threshold_size => 5) }
|
6
|
-
|
4
|
+
shared_examples "a bucketer" do
|
7
5
|
describe '#add_item' do
|
8
6
|
it 'adds a item to the bucket' do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
ran_get = true
|
7
|
+
EM.run do
|
8
|
+
EM.add_timer(1) { fail "didn't reach EM.stop" }
|
9
|
+
bucketer.add_item("1", "2", {:foo => :bar}) do
|
10
|
+
bucketer.get_bucket("1") do |bucket|
|
11
|
+
expect(bucket).to eq([{:foo => :bar}])
|
12
|
+
EM.stop
|
13
|
+
end
|
14
|
+
end
|
18
15
|
end
|
19
|
-
|
20
|
-
expect(ran_add).to eq(true)
|
21
|
-
expect(ran_get).to eq(true)
|
22
16
|
end
|
23
17
|
|
24
18
|
it 'overwrites an existing item with the same id' do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
EM.run do
|
20
|
+
EM.add_timer(1) { fail "didn't reach EM.stop" }
|
21
|
+
bucketer.add_item("1", "2", {:foo => :bar}) do
|
22
|
+
bucketer.add_item("1", "2", {:bar => :foo}) do
|
23
|
+
|
24
|
+
bucketer.get_bucket("1") do |bucket|
|
25
|
+
expect(bucket).to eq([{:bar => :foo}])
|
26
|
+
EM.stop
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
32
30
|
end
|
33
|
-
|
34
|
-
expect(ran_get).to eq(true)
|
35
31
|
end
|
36
32
|
|
37
33
|
it 'calls on_bucket_full when a bucket fills up' do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
34
|
+
EM.run do
|
35
|
+
EM.add_timer(1) { fail "didn't reach EM.stop" }
|
36
|
+
bucketer.on_bucket_full do |bucket_id|
|
37
|
+
expect(bucket_id).to eq("1")
|
38
|
+
EM.stop
|
39
|
+
end
|
40
|
+
|
41
|
+
add_n_items(bucketer, "1", 5) {}
|
42
42
|
end
|
43
|
-
|
44
|
-
bucketer.add_item("1", "1", {:foo => :bar})
|
45
|
-
bucketer.add_item("1", "2", {:foo => :bar})
|
46
|
-
bucketer.add_item("1", "3", {:foo => :bar})
|
47
|
-
bucketer.add_item("1", "4", {:bar => :foo})
|
48
|
-
bucketer.add_item("1", "5", {:bar => :foo})
|
49
|
-
|
50
|
-
expect(ran).to eq(true)
|
51
43
|
end
|
52
44
|
end
|
53
45
|
|
54
46
|
describe '#empty_bucket' do
|
55
47
|
it 'emptys a bucket' do
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
48
|
+
EM.run do
|
49
|
+
EM.add_timer(1) { fail "didn't reach EM.stop" }
|
50
|
+
add_n_items(bucketer, "1", 3) do
|
51
|
+
bucketer.empty_bucket("1") do
|
52
|
+
bucketer.get_bucket("1") do |bucket|
|
53
|
+
expect(bucket).to eq([])
|
54
|
+
EM.stop
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
66
58
|
end
|
67
|
-
expect(ran).to eq(true)
|
68
59
|
end
|
69
60
|
end
|
70
61
|
|
71
62
|
describe '#get_and_empty_bucket' do
|
72
63
|
it 'gets the bucket then emptys the bucket' do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
64
|
+
EM.run do
|
65
|
+
EM.add_timer(1) { fail "didn't reach EM.stop" }
|
66
|
+
add_n_items(bucketer, "1", 3) do
|
67
|
+
|
68
|
+
bucketer.get_and_empty_bucket("1") do |bucket|
|
69
|
+
expect(bucket).to eq([{:id => 0}, {:id => 1}, {:id => 2}])
|
70
|
+
|
71
|
+
bucketer.get_bucket("1") do |empty_bucket|
|
72
|
+
expect(empty_bucket).to eq([])
|
73
|
+
EM.stop
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
82
77
|
end
|
83
|
-
|
84
|
-
bucketer.get_bucket("1") do |bucket|
|
85
|
-
expect(bucket).to eq([])
|
86
|
-
ran_get = true
|
87
|
-
end
|
88
|
-
|
89
|
-
expect(ran_get_and_empty).to eq(true)
|
90
|
-
expect(ran_get).to eq(true)
|
91
78
|
end
|
92
79
|
end
|
93
80
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bucketer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Heycock
|
@@ -11,6 +11,20 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2014-10-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: bundler
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,7 +98,9 @@ files:
|
|
84
98
|
- lib/bucketer/in_memory.rb
|
85
99
|
- lib/bucketer/version.rb
|
86
100
|
- spec/bucketer_spec.rb
|
101
|
+
- spec/in_memory_spec.rb
|
87
102
|
- spec/spec_helper.rb
|
103
|
+
- spec/spec_methods.rb
|
88
104
|
homepage: https://github.com/dgvz/bucketer
|
89
105
|
licenses:
|
90
106
|
- GPL
|
@@ -112,4 +128,6 @@ summary: A generic class for storing arbitrary objects in buckets with callbacks
|
|
112
128
|
threshold reached
|
113
129
|
test_files:
|
114
130
|
- spec/bucketer_spec.rb
|
131
|
+
- spec/in_memory_spec.rb
|
115
132
|
- spec/spec_helper.rb
|
133
|
+
- spec/spec_methods.rb
|