qup 1.1.0 → 1.2.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.
@@ -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