redstream 0.0.1 → 0.1.0
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/.rubocop.yml +116 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +0 -2
- data/Rakefile +0 -1
- data/lib/redstream/consumer.rb +1 -3
- data/lib/redstream/delayer.rb +1 -3
- data/lib/redstream/lock.rb +2 -4
- data/lib/redstream/message.rb +0 -2
- data/lib/redstream/model.rb +7 -9
- data/lib/redstream/producer.rb +0 -2
- data/lib/redstream/trimmer.rb +1 -3
- data/lib/redstream/version.rb +1 -3
- data/lib/redstream.rb +12 -3
- data/redstream.gemspec +14 -15
- data/spec/redstream/consumer_spec.rb +4 -6
- data/spec/redstream/delayer_spec.rb +0 -2
- data/spec/redstream/lock_spec.rb +1 -3
- data/spec/redstream/model_spec.rb +50 -32
- data/spec/redstream/producer_spec.rb +1 -3
- data/spec/redstream/trimmer_spec.rb +0 -2
- data/spec/redstream_spec.rb +12 -4
- data/spec/spec_helper.rb +0 -3
- metadata +38 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48ab0cf09dec323cf89c4bebe065054535f24402182208ee62ab0524e0d45fa3
|
4
|
+
data.tar.gz: 4264929febdbe55dfd240893d8f1327244937a835e2535cdf943342529e926a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2507c6ebdeb7e4e1c0088af3f7711dce068b614c490222cb69a3634696c8be695e9485750f3c032f1b87d17653135bd59397a09bacc3d3d121f9fbce94251b9a
|
7
|
+
data.tar.gz: 66cf9439eebf813c7bca3426bb466189babec062da87eeb6f0a1a893d497fdf80cafe0bb63764aee7c1a56a07bdfbae9aebce91a2ff1eb2f8b4da4074a6f69af
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
Lint/AmbiguousBlockAssociation:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Style/FrozenStringLiteralComment:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Lint/RedundantRequireStatement:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Layout/ArgumentAlignment:
|
11
|
+
EnforcedStyle: with_fixed_indentation
|
12
|
+
|
13
|
+
Layout/FirstArrayElementIndentation:
|
14
|
+
EnforcedStyle: consistent
|
15
|
+
|
16
|
+
Style/BracesAroundHashParameters:
|
17
|
+
EnforcedStyle: no_braces
|
18
|
+
|
19
|
+
Style/PercentLiteralDelimiters:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/SpecialGlobalVars:
|
23
|
+
EnforcedStyle: use_english_names
|
24
|
+
|
25
|
+
Security/Eval:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/WordArray:
|
29
|
+
EnforcedStyle: brackets
|
30
|
+
|
31
|
+
Style/ClassAndModuleChildren:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/TrivialAccessors:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/Alias:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/StringLiteralsInInterpolation:
|
41
|
+
EnforcedStyle: double_quotes
|
42
|
+
|
43
|
+
Metrics/ClassLength:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Naming/MethodParameterName:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/SymbolArray:
|
50
|
+
EnforcedStyle: brackets
|
51
|
+
|
52
|
+
Layout/RescueEnsureAlignment:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Metrics/LineLength:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Metrics/MethodLength:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Metrics/ModuleLength:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/ZeroLengthPredicate:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Metrics/PerceivedComplexity:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
Metrics/AbcSize:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Metrics/CyclomaticComplexity:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
Metrics/BlockLength:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Metrics/BlockNesting:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
Style/NumericPredicate:
|
83
|
+
Enabled: false
|
84
|
+
|
85
|
+
Naming/AccessorMethodName:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
Naming/MemoizedInstanceVariableName:
|
89
|
+
Enabled: false
|
90
|
+
|
91
|
+
Style/StringLiterals:
|
92
|
+
EnforcedStyle: double_quotes
|
93
|
+
|
94
|
+
Style/Documentation:
|
95
|
+
Enabled: false
|
96
|
+
|
97
|
+
Naming/ConstantName:
|
98
|
+
Enabled: false
|
99
|
+
|
100
|
+
Style/MutableConstant:
|
101
|
+
Enabled: false
|
102
|
+
|
103
|
+
Layout/MultilineMethodCallIndentation:
|
104
|
+
EnforcedStyle: indented
|
105
|
+
|
106
|
+
Layout/ParameterAlignment:
|
107
|
+
EnforcedStyle: with_fixed_indentation
|
108
|
+
|
109
|
+
Lint/UnusedMethodArgument:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
Style/IfUnlessModifier:
|
113
|
+
Enabled: false
|
114
|
+
|
115
|
+
Style/RedundantBegin:
|
116
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
data/Rakefile
CHANGED
data/lib/redstream/consumer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "thread"
|
3
2
|
|
4
3
|
module Redstream
|
@@ -92,7 +91,7 @@ module Redstream
|
|
92
91
|
end
|
93
92
|
|
94
93
|
sleep(5) unless got_lock
|
95
|
-
rescue => e
|
94
|
+
rescue StandardError => e
|
96
95
|
@logger.error e
|
97
96
|
|
98
97
|
sleep 5
|
@@ -112,4 +111,3 @@ module Redstream
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
end
|
115
|
-
|
data/lib/redstream/delayer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Redstream
|
3
2
|
# The Redstream::Delayer class is responsible for reading messages from
|
4
3
|
# special delay streams which are used to fix inconsistencies resulting from
|
@@ -68,7 +67,7 @@ module Redstream
|
|
68
67
|
|
69
68
|
deliver
|
70
69
|
end
|
71
|
-
rescue => e
|
70
|
+
rescue StandardError => e
|
72
71
|
@logger.error e
|
73
72
|
|
74
73
|
sleep 5
|
@@ -97,4 +96,3 @@ module Redstream
|
|
97
96
|
end
|
98
97
|
end
|
99
98
|
end
|
100
|
-
|
data/lib/redstream/lock.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "securerandom"
|
3
2
|
|
4
3
|
module Redstream
|
@@ -55,7 +54,7 @@ module Redstream
|
|
55
54
|
end
|
56
55
|
|
57
56
|
def get_lock
|
58
|
-
@get_lock_script
|
57
|
+
@get_lock_script = <<~GET_LOCK_SCRIPT
|
59
58
|
local lock_key_name, id = ARGV[1], ARGV[2]
|
60
59
|
|
61
60
|
local cur = redis.call('get', lock_key_name)
|
@@ -71,10 +70,9 @@ module Redstream
|
|
71
70
|
end
|
72
71
|
|
73
72
|
return false
|
74
|
-
|
73
|
+
GET_LOCK_SCRIPT
|
75
74
|
|
76
75
|
Redstream.connection_pool.with { |redis| redis.eval(@get_lock_script, argv: [Redstream.lock_key_name(@name), @id]) }
|
77
76
|
end
|
78
77
|
end
|
79
78
|
end
|
80
|
-
|
data/lib/redstream/message.rb
CHANGED
data/lib/redstream/model.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Redstream
|
3
2
|
# Include Redstream::Model in your model to stream the model's updates via
|
4
3
|
# redis streams.
|
@@ -15,7 +14,7 @@ module Redstream
|
|
15
14
|
module Model
|
16
15
|
def self.included(base)
|
17
16
|
base.extend(ClassMethods)
|
18
|
-
end
|
17
|
+
end
|
19
18
|
|
20
19
|
module ClassMethods
|
21
20
|
# Adds after_save, after_touch, after_destroy and, most importantly,
|
@@ -30,11 +29,11 @@ module Redstream
|
|
30
29
|
# responsible for writing to a redis stream
|
31
30
|
|
32
31
|
def redstream_callbacks(producer: Producer.new)
|
33
|
-
after_save { |object| producer.delay object }
|
34
|
-
after_touch { |object| producer.delay
|
35
|
-
after_destroy { |object| producer.delay
|
36
|
-
after_commit { |object| producer.queue object }
|
37
|
-
end
|
32
|
+
after_save { |object| producer.delay(object) if object.saved_changes.present? }
|
33
|
+
after_touch { |object| producer.delay(object) }
|
34
|
+
after_destroy { |object| producer.delay(object) }
|
35
|
+
after_commit { |object| producer.queue(object) if object.saved_changes.present? }
|
36
|
+
end
|
38
37
|
|
39
38
|
def redstream_name
|
40
39
|
name.pluralize.underscore
|
@@ -52,6 +51,5 @@ module Redstream
|
|
52
51
|
def redstream_payload
|
53
52
|
{ id: id }
|
54
53
|
end
|
55
|
-
end
|
54
|
+
end
|
56
55
|
end
|
57
|
-
|
data/lib/redstream/producer.rb
CHANGED
data/lib/redstream/trimmer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Redstream
|
3
2
|
# The Redstream::Trimmer class is neccessary to clean up messsages after all
|
4
3
|
# consumers have successfully processed and committed them. Otherwise they
|
@@ -79,7 +78,7 @@ module Redstream
|
|
79
78
|
end
|
80
79
|
|
81
80
|
sleep(5) unless got_lock
|
82
|
-
rescue => e
|
81
|
+
rescue StandardError => e
|
83
82
|
@logger.error e
|
84
83
|
|
85
84
|
sleep 5
|
@@ -88,4 +87,3 @@ module Redstream
|
|
88
87
|
end
|
89
88
|
end
|
90
89
|
end
|
91
|
-
|
data/lib/redstream/version.rb
CHANGED
data/lib/redstream.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require "active_support/inflector"
|
3
2
|
require "connection_pool"
|
4
3
|
require "redis"
|
@@ -59,6 +58,17 @@ module Redstream
|
|
59
58
|
@namespace
|
60
59
|
end
|
61
60
|
|
61
|
+
# Returns the length of the specified stream.
|
62
|
+
#
|
63
|
+
# @param stream_name [String] The stream name
|
64
|
+
# @return [Integer] The length of the stream
|
65
|
+
|
66
|
+
def self.stream_size(stream_name)
|
67
|
+
connection_pool.with do |redis|
|
68
|
+
redis.xlen(stream_key_name(stream_name))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
62
72
|
# Returns the max id of the specified stream, i.e. the id of the
|
63
73
|
# last/newest message added. Returns nil for empty streams.
|
64
74
|
#
|
@@ -69,7 +79,7 @@ module Redstream
|
|
69
79
|
connection_pool.with do |redis|
|
70
80
|
message = redis.xrevrange(stream_key_name(stream_name), "+", "-", count: 1).first
|
71
81
|
|
72
|
-
return unless message
|
82
|
+
return nil unless message
|
73
83
|
|
74
84
|
message[0]
|
75
85
|
end
|
@@ -131,4 +141,3 @@ module Redstream
|
|
131
141
|
[namespace, "redstream"].compact.join(":")
|
132
142
|
end
|
133
143
|
end
|
134
|
-
|
data/redstream.gemspec
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "redstream/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "redstream"
|
8
7
|
spec.version = Redstream::VERSION
|
9
8
|
spec.authors = ["Benjamin Vetter"]
|
10
9
|
spec.email = ["vetter@plainpicture.de"]
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
10
|
+
spec.summary = "Using redis streams to keep your primary database in sync with secondary datastores"
|
11
|
+
spec.description = "Using redis streams to keep your primary database in sync with secondary datastores"
|
13
12
|
spec.homepage = "https://github.com/mrkamel/redstream"
|
14
13
|
spec.license = "MIT"
|
15
14
|
|
@@ -18,21 +17,21 @@ Gem::Specification.new do |spec|
|
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
|
-
spec.add_development_dependency "bundler"
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "rspec"
|
24
20
|
spec.add_development_dependency "activerecord"
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "concurrent-ruby"
|
25
23
|
spec.add_development_dependency "database_cleaner"
|
26
|
-
spec.add_development_dependency "sqlite3", "1.3.13"
|
27
24
|
spec.add_development_dependency "factory_bot"
|
28
|
-
spec.add_development_dependency "timecop"
|
29
|
-
spec.add_development_dependency "concurrent-ruby"
|
30
|
-
spec.add_development_dependency "rspec-instafail"
|
31
25
|
spec.add_development_dependency "mocha"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "rspec-instafail"
|
29
|
+
spec.add_development_dependency "rubocop"
|
30
|
+
spec.add_development_dependency "sqlite3"
|
31
|
+
spec.add_development_dependency "timecop"
|
32
32
|
|
33
|
-
spec.add_dependency "connection_pool"
|
34
33
|
spec.add_dependency "activesupport"
|
35
|
-
spec.add_dependency "
|
34
|
+
spec.add_dependency "connection_pool"
|
36
35
|
spec.add_dependency "json"
|
36
|
+
spec.add_dependency "redis", ">= 4.1.0"
|
37
37
|
end
|
38
|
-
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe Redstream::Consumer do
|
@@ -6,7 +5,7 @@ RSpec.describe Redstream::Consumer do
|
|
6
5
|
it "doesn't call the block without messages" do
|
7
6
|
called = false
|
8
7
|
|
9
|
-
Redstream::Consumer.new(name: "consumer", stream_name: "products", batch_size: 5).run_once do |
|
8
|
+
Redstream::Consumer.new(name: "consumer", stream_name: "products", batch_size: 5).run_once do |_batch|
|
10
9
|
called = true
|
11
10
|
end
|
12
11
|
|
@@ -18,9 +17,9 @@ RSpec.describe Redstream::Consumer do
|
|
18
17
|
|
19
18
|
calls = Concurrent::AtomicFixnum.new(0)
|
20
19
|
|
21
|
-
threads = Array.new(2) do |
|
20
|
+
threads = Array.new(2) do |_i|
|
22
21
|
Thread.new do
|
23
|
-
Redstream::Consumer.new(name: "consumer", stream_name: "products", batch_size: 5).run_once do |
|
22
|
+
Redstream::Consumer.new(name: "consumer", stream_name: "products", batch_size: 5).run_once do |_batch|
|
24
23
|
calls.increment
|
25
24
|
|
26
25
|
sleep 1
|
@@ -55,7 +54,7 @@ RSpec.describe Redstream::Consumer do
|
|
55
54
|
end
|
56
55
|
|
57
56
|
it "yields messages in batches" do
|
58
|
-
|
57
|
+
create_list(:product, 15)
|
59
58
|
|
60
59
|
consumer = Redstream::Consumer.new(name: "consumer", stream_name: "products", batch_size: 10)
|
61
60
|
|
@@ -87,4 +86,3 @@ RSpec.describe Redstream::Consumer do
|
|
87
86
|
end
|
88
87
|
end
|
89
88
|
end
|
90
|
-
|
data/spec/redstream/lock_spec.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe Redstream::Lock do
|
@@ -7,7 +6,7 @@ RSpec.describe Redstream::Lock do
|
|
7
6
|
lock_results = Concurrent::Array.new
|
8
7
|
calls = Concurrent::AtomicFixnum.new(0)
|
9
8
|
|
10
|
-
threads = Array.new(2) do |
|
9
|
+
threads = Array.new(2) do |_i|
|
11
10
|
Thread.new do
|
12
11
|
lock_results << Redstream::Lock.new(name: "lock").acquire do
|
13
12
|
calls.increment
|
@@ -65,4 +64,3 @@ RSpec.describe Redstream::Lock do
|
|
65
64
|
end
|
66
65
|
end
|
67
66
|
end
|
68
|
-
|
@@ -1,57 +1,75 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe Redstream::Model do
|
5
|
-
|
6
|
-
|
4
|
+
describe "after_save" do
|
5
|
+
it "adds a delay message after save" do
|
6
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(0)
|
7
|
+
|
8
|
+
time = Time.now
|
7
9
|
|
8
|
-
|
10
|
+
product = Timecop.freeze(time) do
|
11
|
+
create(:product)
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(1)
|
15
|
+
expect(redis.xrange(Redstream.stream_key_name("products.delay"), "-", "+").first[1]).to eq("payload" => JSON.dump(product.redstream_payload))
|
12
16
|
end
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
it "does not a delay message after save if there are no changes" do
|
19
|
+
product = create(:product)
|
20
|
+
|
21
|
+
expect { product.save }.not_to change { redis.xlen(Redstream.stream_key_name("products.delay")) }
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
|
-
|
19
|
-
|
25
|
+
describe "after_touch" do
|
26
|
+
it "adds a delay message after touch" do
|
27
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(0)
|
20
28
|
|
21
|
-
|
29
|
+
product = create(:product)
|
22
30
|
|
23
|
-
|
31
|
+
time = Time.now
|
24
32
|
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
Timecop.freeze(time) do
|
34
|
+
product.touch
|
35
|
+
end
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(2)
|
38
|
+
expect(redis.xrange(Redstream.stream_key_name("products.delay"), "-", "+").last[1]).to eq("payload" => JSON.dump(product.redstream_payload))
|
39
|
+
end
|
31
40
|
end
|
32
41
|
|
33
|
-
|
34
|
-
|
42
|
+
describe "after_destroy" do
|
43
|
+
it "adds a delay message after destroy" do
|
44
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(0)
|
35
45
|
|
36
|
-
|
46
|
+
product = create(:product)
|
37
47
|
|
38
|
-
|
48
|
+
time = Time.now
|
39
49
|
|
40
|
-
|
41
|
-
|
42
|
-
|
50
|
+
Timecop.freeze(time) do
|
51
|
+
product.touch
|
52
|
+
end
|
43
53
|
|
44
|
-
|
45
|
-
|
54
|
+
expect(redis.xlen(Redstream.stream_key_name("products.delay"))).to eq(2)
|
55
|
+
expect(redis.xrange(Redstream.stream_key_name("products.delay"), "-", "+").last[1]).to eq("payload" => JSON.dump(product.redstream_payload))
|
56
|
+
end
|
46
57
|
end
|
47
58
|
|
48
|
-
|
49
|
-
|
59
|
+
describe "after_commit" do
|
60
|
+
it "adds a queue message after commit" do
|
61
|
+
expect(redis.xlen(Redstream.stream_key_name("products"))).to eq(0)
|
62
|
+
|
63
|
+
product = create(:product)
|
64
|
+
|
65
|
+
expect(redis.xlen(Redstream.stream_key_name("products"))).to eq(1)
|
66
|
+
expect(redis.xrange(Redstream.stream_key_name("products"), "-", "+").first[1]).to eq("payload" => JSON.dump(product.redstream_payload))
|
67
|
+
end
|
50
68
|
|
51
|
-
|
69
|
+
it "does not add a queue message after commit if there are no changes" do
|
70
|
+
product = create(:product)
|
52
71
|
|
53
|
-
|
54
|
-
|
72
|
+
expect { product.save }.not_to change { redis.xlen(Redstream.stream_key_name("products")) }
|
73
|
+
end
|
55
74
|
end
|
56
75
|
end
|
57
|
-
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe Redstream::Producer do
|
@@ -66,7 +65,7 @@ RSpec.describe Redstream::Producer do
|
|
66
65
|
end
|
67
66
|
|
68
67
|
it "should resepect wait for delay" do
|
69
|
-
|
68
|
+
create(:product)
|
70
69
|
|
71
70
|
stream_key_name = Redstream.stream_key_name("products.delay")
|
72
71
|
|
@@ -76,4 +75,3 @@ RSpec.describe Redstream::Producer do
|
|
76
75
|
end
|
77
76
|
end
|
78
77
|
end
|
79
|
-
|
data/spec/redstream_spec.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe Redstream do
|
@@ -31,11 +30,21 @@ RSpec.describe Redstream do
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
33
|
+
describe ".stream_size" do
|
34
|
+
it "returns the stream's size" do
|
35
|
+
expect(Redstream.stream_size("products")).to eq(0)
|
36
|
+
|
37
|
+
redis.xadd("redstream:stream:products", key: "value")
|
38
|
+
|
39
|
+
expect(Redstream.stream_size("products")).to eq(1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
34
43
|
describe ".max_stream_id" do
|
35
44
|
it "returns the stream's max id" do
|
36
45
|
expect(Redstream.max_stream_id("products")).to be_nil
|
37
46
|
|
38
|
-
|
47
|
+
_id1 = redis.xadd("redstream:stream:products", key: "value")
|
39
48
|
id2 = redis.xadd("redstream:stream:products", key: "value")
|
40
49
|
|
41
50
|
expect(Redstream.max_stream_id("products")).to eq(id2)
|
@@ -46,7 +55,7 @@ RSpec.describe Redstream do
|
|
46
55
|
it "returns the consumer's max id" do
|
47
56
|
expect(Redstream.max_consumer_id(stream_name: "products", consumer_name: "consumer")).to be_nil
|
48
57
|
|
49
|
-
|
58
|
+
_id1 = redis.xadd("redstream:stream:products", key: "value")
|
50
59
|
id2 = redis.xadd("redstream:stream:products", key: "value")
|
51
60
|
|
52
61
|
Redstream::Consumer.new(name: "consumer", stream_name: "products").run_once do |messages|
|
@@ -114,4 +123,3 @@ RSpec.describe Redstream do
|
|
114
123
|
end
|
115
124
|
end
|
116
125
|
end
|
117
|
-
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redstream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: concurrent-ruby
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: database_cleaner
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: factory_bot
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,21 +81,21 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: mocha
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: rspec-instafail
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
@@ -137,7 +137,7 @@ dependencies:
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: rubocop
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
@@ -151,7 +151,7 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: sqlite3
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
@@ -165,13 +165,13 @@ dependencies:
|
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
168
|
+
name: timecop
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
171
|
- - ">="
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
|
-
type: :
|
174
|
+
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
@@ -193,19 +193,19 @@ dependencies:
|
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
196
|
+
name: connection_pool
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
198
198
|
requirements:
|
199
199
|
- - ">="
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
201
|
+
version: '0'
|
202
202
|
type: :runtime
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - ">="
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
208
|
+
version: '0'
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: json
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,6 +220,20 @@ dependencies:
|
|
220
220
|
- - ">="
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: redis
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 4.1.0
|
230
|
+
type: :runtime
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 4.1.0
|
223
237
|
description: Using redis streams to keep your primary database in sync with secondary
|
224
238
|
datastores
|
225
239
|
email:
|
@@ -229,7 +243,9 @@ extensions: []
|
|
229
243
|
extra_rdoc_files: []
|
230
244
|
files:
|
231
245
|
- ".gitignore"
|
246
|
+
- ".rubocop.yml"
|
232
247
|
- ".travis.yml"
|
248
|
+
- CHANGELOG.md
|
233
249
|
- Gemfile
|
234
250
|
- LICENSE.txt
|
235
251
|
- README.md
|