pub_sub 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +9 -0
- data/Rakefile +2 -0
- data/lib/pub_sub.rb +10 -0
- data/lib/pub_sub/bunny_config.rb +16 -0
- data/lib/pub_sub/fanout_publisher.rb +59 -0
- data/lib/pub_sub/publisher.rb +73 -0
- data/lib/pub_sub/subscriber.rb +62 -0
- data/lib/pub_sub/version.rb +3 -0
- data/pub_sub.gemspec +26 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/lib/pub_sub.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module PubSub
|
2
|
+
module BunnyConfig
|
3
|
+
def bunny_config
|
4
|
+
defaults = {
|
5
|
+
:host => 'localhost',
|
6
|
+
:port => 5672,
|
7
|
+
:user => 'guest',
|
8
|
+
:pass => 'guest',
|
9
|
+
|
10
|
+
:spec => '09',
|
11
|
+
:heartbeat => 60
|
12
|
+
}
|
13
|
+
defined?(BUNNY_CONFIG) ? defaults.merge(BUNNY_CONFIG) : defaults
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module PubSub
|
2
|
+
module FanoutPublisher
|
3
|
+
include BunnyConfig
|
4
|
+
|
5
|
+
RETRY_WAIT = 5
|
6
|
+
|
7
|
+
def logger=(logger)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def logger
|
12
|
+
@logger ||= begin
|
13
|
+
logger = Logger.new(STDOUT)
|
14
|
+
logger.level = Logger::WARN
|
15
|
+
logger
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def bunny
|
20
|
+
@bunny ||= begin
|
21
|
+
logger.info("PubSub:FanoutPublisher#bunny: initializing and starting new bunny instance")
|
22
|
+
|
23
|
+
b = Bunny.new(bunny_config)
|
24
|
+
b.start
|
25
|
+
b
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def publish(msg, exchange_name)
|
30
|
+
begin
|
31
|
+
|
32
|
+
begin
|
33
|
+
exchange = bunny.exchange(exchange_name, :type => :fanout, :durable => true)
|
34
|
+
rescue StandardError, Timeout::Error => error
|
35
|
+
logger.info("PubSub:FanoutPublisher#publish: resetting and reconnecting to #{exchange_name}, because - #{error}")
|
36
|
+
sleep RETRY_WAIT
|
37
|
+
reset
|
38
|
+
retry
|
39
|
+
end
|
40
|
+
|
41
|
+
# non-persistent to a fanout exchange
|
42
|
+
exchange.publish(msg)
|
43
|
+
|
44
|
+
rescue StandardError, Timeout::Error => error
|
45
|
+
logger.info("PubSub:FanoutPublisher#publish: error encountered while publishing to #{exchange_name} with routing_key #{routing_key}, retrying - #{error}")
|
46
|
+
sleep RETRY_WAIT
|
47
|
+
reset
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset
|
53
|
+
logger.info("PubSub:FanoutPublisher#reset: stopping bunny")
|
54
|
+
|
55
|
+
@bunny.stop rescue nil
|
56
|
+
@bunny = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module PubSub
|
2
|
+
module Publisher
|
3
|
+
include BunnyConfig
|
4
|
+
|
5
|
+
RETRY_WAIT = 5
|
6
|
+
|
7
|
+
def logger=(logger)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def logger
|
12
|
+
@logger ||= begin
|
13
|
+
logger = Logger.new(STDOUT)
|
14
|
+
logger.level = Logger::WARN
|
15
|
+
logger
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def transactional=(transactional)
|
20
|
+
@transactional=transactional
|
21
|
+
end
|
22
|
+
|
23
|
+
def bunny
|
24
|
+
@bunny ||= begin
|
25
|
+
logger.info("PubSub:Publisher#bunny: initializing and starting new bunny instance")
|
26
|
+
|
27
|
+
b = Bunny.new(bunny_config)
|
28
|
+
b.start
|
29
|
+
|
30
|
+
if(@transactional)
|
31
|
+
logger.info("PubSub:Publisher#bunny: publisher is transactional, calling tx_select")
|
32
|
+
b.tx_select
|
33
|
+
end
|
34
|
+
|
35
|
+
b
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def publish(msg, exchange_name, routing_key)
|
40
|
+
begin
|
41
|
+
|
42
|
+
begin
|
43
|
+
exchange = bunny.exchange(exchange_name, :type => :topic, :durable => true)
|
44
|
+
rescue StandardError, Timeout::Error => error
|
45
|
+
logger.info("PubSub:Publisher#publish: resetting and reconnecting to #{exchange_name}, because - #{error}")
|
46
|
+
sleep RETRY_WAIT
|
47
|
+
reset
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
|
51
|
+
exchange.publish(msg, :key => routing_key, :persistent => true)
|
52
|
+
|
53
|
+
if(@transactional)
|
54
|
+
logger.debug("PubSub:Publisher#bunny: publisher is transactional, calling tx_commit")
|
55
|
+
bunny.tx_commit
|
56
|
+
end
|
57
|
+
|
58
|
+
rescue StandardError, Timeout::Error => error
|
59
|
+
logger.info("PubSub:Publisher#publish: error encountered while publishing to #{exchange_name} with routing_key #{routing_key}, retrying - #{error}")
|
60
|
+
sleep RETRY_WAIT
|
61
|
+
reset
|
62
|
+
retry
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def reset
|
67
|
+
logger.info("PubSub:Publisher#reset: stopping bunny")
|
68
|
+
|
69
|
+
@bunny.stop rescue nil
|
70
|
+
@bunny = nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module PubSub
|
2
|
+
module Subscriber
|
3
|
+
include BunnyConfig
|
4
|
+
|
5
|
+
RETRY_WAIT = 5
|
6
|
+
|
7
|
+
def logger=(logger)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def logger
|
12
|
+
@logger ||= begin
|
13
|
+
logger = Logger.new(STDOUT)
|
14
|
+
logger.level = Logger::WARN
|
15
|
+
logger
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def queue_name=(queue_name)
|
20
|
+
@queue_name = queue_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def bunny
|
24
|
+
@bunny ||= begin
|
25
|
+
logger.info("PubSub:Subscriber#bunny: initializing and starting new bunny instance")
|
26
|
+
|
27
|
+
b = Bunny.new(bunny_config)
|
28
|
+
b.start
|
29
|
+
b.qos
|
30
|
+
b
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset
|
35
|
+
logger.info("PubSub:Subscriber#reset: unsubscribing from queue and stopping bunny")
|
36
|
+
|
37
|
+
@queue.unsubscribe rescue nil
|
38
|
+
@queue = nil
|
39
|
+
@bunny.stop rescue nil
|
40
|
+
@bunny = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# simple subsciption loop on a durable queue, automatic acks
|
44
|
+
# creates the queue if it does not already exist
|
45
|
+
def subscribe(&block)
|
46
|
+
raise "queue_name must be set before calling subscribe" unless @queue_name
|
47
|
+
|
48
|
+
logger.info("PubSub:Subscriber#subscribe: subscribing to queue - #{@queue_name}")
|
49
|
+
begin
|
50
|
+
@queue = bunny.queue(@queue_name, :durable => true)
|
51
|
+
@queue.subscribe(:ack => true) do |msg|
|
52
|
+
block.call(msg)
|
53
|
+
end
|
54
|
+
rescue StandardError, Timeout::Error => error
|
55
|
+
logger.info("PubSub:Subscriber: error encountered while subscribing to #{@queue_name}, retrying - #{error}")
|
56
|
+
sleep RETRY_WAIT
|
57
|
+
reset
|
58
|
+
retry
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/pub_sub.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "pub_sub/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "pub_sub"
|
7
|
+
s.version = PubSub::VERSION
|
8
|
+
s.authors = ["Simon Horne"]
|
9
|
+
s.email = ["simon@soulware.co.uk"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Minimal Publisher/Subscriber}
|
12
|
+
s.description = %q{Minimal Publisher/Subscriber}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
# specify any dependencies here; for example:
|
20
|
+
# s.add_development_dependency "rspec"
|
21
|
+
# s.add_runtime_dependency "rest-client"
|
22
|
+
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
|
25
|
+
s.add_runtime_dependency "bunny", ["= 0.7.8"]
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pub_sub
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Simon Horne
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-03-30 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rake
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bunny
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - "="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 19
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 7
|
47
|
+
- 8
|
48
|
+
version: 0.7.8
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: Minimal Publisher/Subscriber
|
52
|
+
email:
|
53
|
+
- simon@soulware.co.uk
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- Gemfile
|
63
|
+
- README.rdoc
|
64
|
+
- Rakefile
|
65
|
+
- lib/pub_sub.rb
|
66
|
+
- lib/pub_sub/bunny_config.rb
|
67
|
+
- lib/pub_sub/fanout_publisher.rb
|
68
|
+
- lib/pub_sub/publisher.rb
|
69
|
+
- lib/pub_sub/subscriber.rb
|
70
|
+
- lib/pub_sub/version.rb
|
71
|
+
- pub_sub.gemspec
|
72
|
+
has_rdoc: true
|
73
|
+
homepage: ""
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 1.3.7
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Minimal Publisher/Subscriber
|
106
|
+
test_files: []
|
107
|
+
|