qup 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,14 @@
1
1
  = Changelog
2
2
 
3
- == Version 1.0.0 - 2012-03-10
3
+ == Version 1.2.0 - 2012-03-17
4
4
 
5
- * Initial public release
5
+ * Persistent subscriptions for the Redis Adapter (thanks aniero)
6
6
 
7
7
  == Version 1.1.0 - 2012-03-12
8
8
 
9
9
  * Addition of a Redis Adapter (thanks aniero)
10
+
11
+ == Version 1.0.0 - 2012-03-10
12
+
13
+ * Initial public release
14
+
@@ -8,9 +8,10 @@ Qup is a generalized API for Message Queue and Publish/Subscribe messaging
8
8
  patterns with the ability to plug in an appropriate messaging infrastructure
9
9
  based upon your needs.
10
10
 
11
- Qup ships with support for {Kestrel}[https://github.com/robey/kestrel] and a
12
- filesystem infrastructure based on {Maildir}[https://rubygems.org/gems/maildir].
13
- Additional Adapters will be developed as needs arise. {Please submit an
11
+ Qup ships with support for {Kestrel}[https://github.com/robey/kestrel],
12
+ {Redis}[http://redis.io], and a filesystem infrastructure based on
13
+ {Maildir}[https://rubygems.org/gems/maildir]. Additional Adapters will be
14
+ developed as needs arise. {Please submit an
14
15
  Issue}[https://github.com/copiousfreetime/qup/issues] to have a new Adapter
15
16
  created. Pull requests gladly accepted.
16
17
 
data/Rakefile CHANGED
@@ -62,6 +62,7 @@ end
62
62
  # RDoc
63
63
  #------------------------------------------------------------------------------
64
64
  begin
65
+ gem 'rdoc' # otherwise we get the wrong task from stdlib
65
66
  require 'rdoc/task'
66
67
  RDoc::Task.new do |t|
67
68
  t.markup = 'tomdoc'
@@ -237,7 +238,7 @@ BEGIN {
237
238
  This = OpenStruct.new
238
239
  desc = Util.section_of( 'README.rdoc', 'DESCRIPTION')
239
240
  This.summary = desc.first
240
- This.description = desc.join("\n\n")
241
+ This.description = desc.join(" ").tr("\n", ' ').gsub(/[{}]/,'').gsub(/\[[^\]]+\]/,'') # strip rdoc
241
242
 
242
243
 
243
244
  This.exclude_from_manifest = %r/tmp$|\.(git|DS_Store)|^(doc|coverage|pkg)|\.gemspec$|\.swp$|\.jar|\.rvmrc$|~$/
data/lib/qup.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Qup
2
2
  # The Current Version of the library
3
- VERSION = '1.1.0'
3
+ VERSION = '1.2.0'
4
4
 
5
5
  class Error < StandardError; end
6
6
 
@@ -9,12 +9,14 @@ class Qup::Adapter::Redis
9
9
 
10
10
  # Internal: create a new Queue
11
11
  #
12
- # uri - the connection uri for the Redis Client
13
- # name - the String name of the Queue
12
+ # uri - the connection uri for the Redis Client
13
+ # name - the String name of the Queue
14
+ # topic_name - (optional) the String name of a parent topic
14
15
  #
15
16
  # Returns a new Queue.
16
- def initialize( uri, name )
17
- super
17
+ def initialize( uri, name, topic_name = nil )
18
+ super uri, name
19
+ @topic_name = topic_name
18
20
  @open_messages = {}
19
21
  end
20
22
 
@@ -25,6 +27,7 @@ class Qup::Adapter::Redis
25
27
  # Returns nothing.
26
28
  def destroy
27
29
  @client.del name
30
+ @client.srem @topic_name, name if @topic_name
28
31
  end
29
32
 
30
33
  # Internal: Empty the queue
@@ -73,7 +76,7 @@ class Qup::Adapter::Redis
73
76
  #
74
77
  # Returns a Message
75
78
  def consume(&block)
76
- queue_name, data = @client.brpop @name, 0 # blocking pop
79
+ queue_name, data = @client.brpop name, 0 # blocking pop
77
80
  message = ::Qup::Message.new( data.object_id, data )
78
81
  @open_messages[message.key] = message
79
82
  if block_given? then
@@ -11,17 +11,6 @@ class Qup::Adapter::Redis
11
11
  class Topic < Connection
12
12
  include Qup::TopicAPI
13
13
 
14
- # Internal: create a new Topic
15
- #
16
- # uri - the connection uri for the Redis Client
17
- # name - the String name of the Topic
18
- #
19
- # Returns a new Topic.
20
- def initialize(uri, name)
21
- super
22
- @subscribers = Hash.new
23
- end
24
-
25
14
  # Internal: Creates a Publisher for the Topic
26
15
  #
27
16
  # Returns a new Publisher
@@ -29,7 +18,7 @@ class Qup::Adapter::Redis
29
18
  ::Qup::Publisher.new( self )
30
19
  end
31
20
 
32
- # Internal: Create a subscriber for the Topic
21
+ # Internal: Create and register a subscriber for the Topic
33
22
  #
34
23
  # name - the String name of the subscriber
35
24
  #
@@ -38,14 +27,17 @@ class Qup::Adapter::Redis
38
27
  #
39
28
  # Returns a Subscriber
40
29
  def subscriber(name)
41
- ::Qup::Subscriber.new( self, subscriber_queue_for(name) )
30
+ subscriber_name = "#{@name}.#{name}"
31
+ @client.sadd @name, subscriber_name
32
+ queue = ::Qup::Adapter::Redis::Queue.new(@uri, subscriber_name, @name)
33
+ ::Qup::Subscriber.new( self, queue )
42
34
  end
43
35
 
44
36
  # Internal: Return the number of Subscribers to this Topic
45
37
  #
46
38
  # Returns integer
47
39
  def subscriber_count
48
- @subscribers.size
40
+ subscribers.size
49
41
  end
50
42
 
51
43
  # Internal: Publish a Message to all the Subscribers
@@ -54,8 +46,8 @@ class Qup::Adapter::Redis
54
46
  #
55
47
  # Returns nothing
56
48
  def publish( message )
57
- @subscribers.values.each do |subscriber|
58
- subscriber.produce message
49
+ subscribers.each do |subscriber|
50
+ @client.lpush subscriber, message
59
51
  end
60
52
  end
61
53
 
@@ -63,14 +55,12 @@ class Qup::Adapter::Redis
63
55
  private
64
56
  #######
65
57
 
66
- # Private: create and register new sub-Queue for the given subscriber
67
- #
68
- # name - the name of the subscriber
58
+ # Private: retrieve the current list of subscribers
69
59
  #
70
- # Returns a Queue
71
- def subscriber_queue_for(name)
72
- @subscribers[name] ||=
73
- ::Qup::Adapter::Redis::Queue.new(@uri, "#{@name}-#{name}")
60
+ # Returns an array of subscriber queue names
61
+ def subscribers
62
+ @client.smembers @name
74
63
  end
64
+
75
65
  end
76
66
  end
@@ -7,6 +7,7 @@ module Qup
7
7
  #
8
8
  # Session.new( 'maildir:///tmp/qup' )
9
9
  # Session.new( 'kestrel://user:pass@host:port/' )
10
+ # Session.new( 'redis://host:port' )
10
11
  #
11
12
  # session.queue( 'foo' ) # => Queue
12
13
  # session.topic( 'bar' ) # => Topic
@@ -6,4 +6,28 @@ describe 'Qup::Adapter::Redis::Queue', :redis => true do
6
6
  include_context "Qup::Adapter::Redis"
7
7
  include_context "Qup::Queue"
8
8
  it_behaves_like Qup::QueueAPI
9
+
10
+ context "when initialized with a parent topic's name" do
11
+ let(:redis) { Redis.new :host => uri.host, :port => uri.port }
12
+ let(:queue) { Qup::Adapter::Redis::Queue.new(uri, "test", "parent") }
13
+
14
+ before do
15
+ redis.del "parent"
16
+ redis.sadd "parent", "test"
17
+ end
18
+
19
+ after do
20
+ redis.del "parent"
21
+ redis.client.disconnect
22
+ end
23
+
24
+ describe "#destroy" do
25
+ it "removes its name from the parent topic's subscriber set" do
26
+ redis.smembers("parent").should == ["test"]
27
+ queue.destroy
28
+ redis.smembers("parent").should == []
29
+ end
30
+ end
31
+
32
+ end
9
33
  end
@@ -6,4 +6,24 @@ describe 'Qup::Adapter::Redis::Topic', :redis => true do
6
6
  include_context "Qup::Adapter::Redis"
7
7
  include_context "Qup::Topic"
8
8
  it_behaves_like Qup::TopicAPI
9
+
10
+ describe "#subscriber" do
11
+
12
+ let(:topic) { adapter.topic "test" }
13
+ let(:subscriber) { topic.subscriber "testing" }
14
+
15
+ before do
16
+ topic && subscriber # create and register the subscriber
17
+ end
18
+
19
+ after do
20
+ topic.destroy
21
+ end
22
+
23
+ it "unregisters itself from the Topic when unsubscribed" do
24
+ lambda do
25
+ subscriber.unsubscribe
26
+ end.should change(topic, :subscriber_count).by(-1)
27
+ end
28
+ end
9
29
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qup
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 1.1.0
10
+ version: 1.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Hinegardner
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-12 00:00:00 Z
18
+ date: 2012-03-17 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: maildir
@@ -145,16 +145,7 @@ dependencies:
145
145
  version: "3.12"
146
146
  type: :development
147
147
  version_requirements: *id008
148
- description: |-
149
- Qup is a generalized API for Message Queue and Publish/Subscribe messaging
150
- patterns with the ability to plug in an appropriate messaging infrastructure
151
- based upon your needs.
152
-
153
- Qup ships with support for {Kestrel}[https://github.com/robey/kestrel] and a
154
- filesystem infrastructure based on {Maildir}[https://rubygems.org/gems/maildir].
155
- Additional Adapters will be developed as needs arise. {Please submit an
156
- Issue}[https://github.com/copiousfreetime/qup/issues] to have a new Adapter
157
- created. Pull requests gladly accepted.
148
+ description: Qup is a generalized API for Message Queue and Publish/Subscribe messaging patterns with the ability to plug in an appropriate messaging infrastructure based upon your needs. Qup ships with support for Kestrel, Redis, and a filesystem infrastructure based on Maildir. Additional Adapters will be developed as needs arise. Please submit an Issue to have a new Adapter created. Pull requests gladly accepted.
158
149
  email: jeremy@copiousfreetime.org
159
150
  executables: []
160
151