backrub 1.0.0 → 2.0.0

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: 27968ba3418abbcab97c0b582bcfab4c70a18178
4
- data.tar.gz: b38040b3676d3c4a765e7cf4ce8711a6c50e5aac
3
+ metadata.gz: 4d42c9e5402d9150f81a77e3d2359c563db3de03
4
+ data.tar.gz: dee8d063247b1a74db02a20807a814f24ced01c7
5
5
  SHA512:
6
- metadata.gz: 5fe540cc437d3766e524506ed6dc60499a376b6a478e0a349ecf676c1ffa9c1e991a969ae7a32681540c6e7fd48b6dc8a8f90b85de7d9f3982f1a188d5d77ace
7
- data.tar.gz: 75cc23037ab89e3bfc1d9fe9f503008a3ce510da7c5527ff6fdb92bdb68cfbd92a6109aaa6dfe9326363a027881f2aa8919502e1e99249a97b92cef518b40f0a
6
+ metadata.gz: 77cc4d20ba3e9b1ff5c1dfadef7c25e601d56aa95badd7390573f8708f5b868f4222cc2d81ee78e24365430a8df07817246ca40a58ee554abf813d75ed798db3
7
+ data.tar.gz: 2b55a4e20b6e55dad15a7898ac0d5e0075201a4e5dc673793c02de112547c812166df3e4acac6ec97153f782ac1b516d04c1ac4bbc6a500e32373f146281cd5c
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- backrub (0.0.1)
4
+ backrub (2.0.0)
5
5
  redis (~> 3.0)
6
6
 
7
7
  GEM
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/testtask'
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << 'test'
7
7
  t.libs << 'lib'
8
- t.test_files = FileList['test/*_test.rb']
8
+ t.test_files = FileList['test/**/*_test.rb']
9
9
  t.verbose = true
10
10
  end
11
11
 
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'backrub'
4
+ require 'backrub/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "backrub"
@@ -1,68 +1,26 @@
1
- require 'redis'
1
+ require 'backrub/store/base'
2
+ require 'backrub/store/redis'
3
+ require 'backrub/version'
2
4
 
3
5
  module Backrub
4
- VERSION = "1.0.0"
5
-
6
- DEFAULT_BACKLOG_SIZE = 100
7
-
8
6
  extend self
9
7
 
10
- attr_writer :redis, :backlog_size, :redis_config
11
-
12
- def redis_config
13
- @redis_config ||= {}
14
- end
15
-
16
- def redis
17
- @redis ||= new_redis
8
+ attr_writer :store
9
+ def store
10
+ @store ||= Backrub::Store::Redis.new
18
11
  end
19
12
 
20
- def subscribe(*channels)
21
- raise ArgumentError.new "You have to pass at least one channel" if channels.count.zero?
22
-
23
- if channels.count == 1 && channels.first.is_a?(Hash)
24
- hash = channels.first
25
-
26
- hash.each do |channel, offset|
27
- if offset > 0
28
- backlog = redis.lrange(channel, 0, offset - 1)
29
-
30
- backlog.reverse_each do |message|
31
- yield channel.to_s, message
32
- end
33
- end
34
- end
35
-
36
- channels = hash.keys
37
- end
38
-
39
- begin
40
- # Open a new connection because the connection blocks, causing other threads to be unable to use it
41
- local_redis = new_redis
42
- local_redis.subscribe(*channels) do |on|
43
- on.message do |channel, message|
44
- yield channel, message
45
- end
46
- end
47
- ensure
48
- local_redis.quit
13
+ def subscribe(channels_with_backlog, &block)
14
+ channels_with_backlog.each do |channel, count|
15
+ store.backlog(channel.to_s, count.to_i, &block) unless count.zero?
49
16
  end
50
- end
51
17
 
52
- def publish(channel, message)
53
- redis.multi do
54
- redis.publish(channel, message)
55
- redis.lpush(channel, message)
56
- redis.ltrim(channel, 0, backlog_size - 1)
57
- end
58
- end
18
+ channels = channels_with_backlog.keys.map(&:to_s)
59
19
 
60
- def backlog_size
61
- @backlog_size || DEFAULT_BACKLOG_SIZE
20
+ store.subscribe(*channels, &block)
62
21
  end
63
22
 
64
- private
65
- def new_redis
66
- Redis.new(redis_config)
23
+ def publish(channel, message)
24
+ store.publish(channel, message)
67
25
  end
68
26
  end
@@ -0,0 +1,17 @@
1
+ module Backrub
2
+ module Store
3
+ class Base
4
+ def backlog(channel, count)
5
+ raise NotImplementedError
6
+ end
7
+
8
+ def publish(channel, message)
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def subscribe(*channel)
13
+ raise NotImplementedError
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require 'redis'
2
+
3
+ module Backrub
4
+ module Store
5
+ class Redis < Base
6
+ attr_reader :config, :backlog_size
7
+
8
+ def initialize(config={}, backlog_size=100)
9
+ @config = config
10
+ @backlog_size = backlog_size
11
+ end
12
+
13
+ def redis
14
+ @redis ||= ::Redis.new(config)
15
+ end
16
+
17
+ def backlog(channel, count)
18
+ backlog = redis.lrange(channel, 0, count - 1)
19
+
20
+ backlog.reverse_each do |message|
21
+ yield channel, message
22
+ end
23
+ end
24
+
25
+ def publish(channel, message)
26
+ redis.multi do
27
+ redis.publish(channel, message)
28
+ redis.lpush(channel, message)
29
+ redis.ltrim(channel, 0, backlog_size - 1)
30
+ end
31
+ end
32
+
33
+ def subscribe(*channels)
34
+ # Open a new connection because the connection blocks, causing other threads to be unable to use it
35
+ local_redis = ::Redis.new(config)
36
+ local_redis.subscribe(*channels) do |on|
37
+ on.message do |channel, message|
38
+ yield channel, message
39
+ end
40
+ end
41
+ ensure
42
+ local_redis.quit
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Backrub
2
+ VERSION = "2.0.0"
3
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ class BackrubRedisTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ @backlog = 20
6
+ @config = {}
7
+ @store = Backrub::Store::Redis.new(@config, @backlog)
8
+ @redis = @store.redis
9
+ end
10
+
11
+ def test_backlog
12
+ backlog = 20.times.map {|n| "a" * (n+1)}
13
+ channel = "test"
14
+ count = 5
15
+ @redis.expects(:lrange).with(channel, 0, count - 1).returns(backlog[0...count])
16
+
17
+ received_backlog = []
18
+
19
+ @store.backlog(channel, count) do |channel, message|
20
+ received_backlog << message
21
+ end
22
+
23
+ assert_equal backlog[0...count].reverse, received_backlog
24
+ end
25
+
26
+ def test_publishing
27
+ channel = "test"
28
+ message = "data"
29
+ @redis.expects(:publish).with(channel, message)
30
+ @redis.expects(:lpush).with(channel, message)
31
+ @redis.expects(:ltrim).with(channel, 0, @backlog - 1)
32
+
33
+ @store.publish(channel, message)
34
+ end
35
+
36
+ def test_subscribing
37
+ test_messages = [["test", "data"], ["test2", "data2"]]
38
+
39
+ mock_redis = mock()
40
+ mock_message_handler = mock()
41
+ mock_message_handler.expects(:message).multiple_yields(*test_messages)
42
+ mock_redis.expects(:subscribe).with("test", "test2").yields(mock_message_handler)
43
+ mock_redis.expects(:quit)
44
+ ::Redis.expects(:new).returns(mock_redis)
45
+
46
+ @store.subscribe("test", "test2") do |channel, message|
47
+ assert_equal test_messages.shift, [channel, message]
48
+ end
49
+ end
50
+ end
@@ -1,52 +1,39 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class BackrubTest < MiniTest::Unit::TestCase
4
- def test_publishing_messages
5
- channel = "test"
6
- message = "data"
7
- Backrub.redis.expects(:publish).with(channel, message)
8
- Backrub.redis.expects(:lpush).with(channel, message)
9
- Backrub.redis.expects(:ltrim).with(channel, 0, Backrub::DEFAULT_BACKLOG_SIZE - 1)
10
-
11
- Backrub.publish(channel, message)
12
- end
13
-
14
- def test_subscribing
15
- fake_redis = mock()
16
- subscribe_object = mock()
17
- subscribe_object.expects(:message).yields(["test", "data"])
18
- fake_redis.expects(:subscribe).with("test").yields(subscribe_object)
19
- fake_redis.expects(:quit)
4
+ class MockStore < Backrub::Store::Base
20
5
 
21
- Backrub.expects(:new_redis).returns(fake_redis)
6
+ end
22
7
 
23
- Backrub.subscribe("test") do |channel, message|
24
- assert_equal "test", channel
25
- assert_equal "data", message
26
- end
8
+ def setup
9
+ Backrub.store = MockStore.new
27
10
  end
28
11
 
29
- def test_subscribing_with_hash_backlog
12
+ def test_subscribing
30
13
  channels = {
31
14
  first_channel: 0,
32
15
  second_channel: 2
33
16
  }
34
- second_channel_data = ["first_bit", "second_bit"]
35
- Backrub.redis.expects(:lrange).with(:second_channel, 0, 1).returns(second_channel_data.dup)
36
- second_channel_data.unshift("third_bit")
37
-
38
- fake_redis = mock()
39
- subscribe_object = mock()
40
- subscribe_object.expects(:message).yields(["second_channel", "third_bit"])
17
+ Backrub.store.expects(:backlog).with("second_channel", 2).multiple_yields(["second_channel", "first_bit"], ["second_channel", "second_bit"])
41
18
 
42
- fake_redis.expects(:subscribe).with(:first_channel, :second_channel).yields(subscribe_object)
43
- fake_redis.expects(:quit)
19
+ expected_data = [
20
+ ["second_channel", "first_bit"],
21
+ ["second_channel", "second_bit"],
22
+ ["first_channel", "third_bit"],
23
+ ]
44
24
 
45
- Backrub.expects(:new_redis).returns(fake_redis)
25
+ Backrub.store.expects(:subscribe).with("first_channel", "second_channel").yields(["first_channel", "third_bit"])
46
26
 
27
+ data = []
47
28
  Backrub.subscribe(channels) do |channel, message|
48
- assert_equal "second_channel", channel
49
- assert_equal second_channel_data.pop, message
29
+ data << [channel, message]
50
30
  end
31
+
32
+ assert_equal expected_data, data
33
+ end
34
+
35
+ def test_publishing
36
+ Backrub.store.expects(:publish).with("test", "data")
37
+ Backrub.publish("test", "data")
51
38
  end
52
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backrub
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bouke van der Bijl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-04 00:00:00.000000000 Z
11
+ date: 2014-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -95,6 +95,10 @@ files:
95
95
  - Rakefile
96
96
  - backrub.gemspec
97
97
  - lib/backrub.rb
98
+ - lib/backrub/store/base.rb
99
+ - lib/backrub/store/redis.rb
100
+ - lib/backrub/version.rb
101
+ - test/backrub/store/redis_test.rb
98
102
  - test/backrub_test.rb
99
103
  - test/test_helper.rb
100
104
  homepage: ''
@@ -122,6 +126,7 @@ signing_key:
122
126
  specification_version: 4
123
127
  summary: Redis-based pubsub system with a backlog
124
128
  test_files:
129
+ - test/backrub/store/redis_test.rb
125
130
  - test/backrub_test.rb
126
131
  - test/test_helper.rb
127
132
  has_rdoc: