bunny-ext 0.6.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/Rakefile +14 -0
- data/bunny-ext.gemspec +21 -0
- data/lib/bunny-ext/bunny/client08.rb +42 -0
- data/lib/bunny-ext/bunny/client09.rb +42 -0
- data/lib/bunny-ext/qrack/client.rb +82 -0
- data/lib/bunny-ext/version.rb +5 -0
- data/lib/bunny-ext.rb +43 -0
- data/test/bunny-ext/qrack_client_ext_test.rb +8 -0
- data/test/test_helper.rb +4 -0
- metadata +95 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.test_files = FileList['test/**/*_test.rb']
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default do
|
13
|
+
Rake::Task[:test].invoke
|
14
|
+
end
|
data/bunny-ext.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "bunny-ext/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "bunny-ext"
|
7
|
+
s.version = Bunny::Ext::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Stefan Kaes", "Pascal Friederich"]
|
10
|
+
s.email = ["developers@xing.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Reliable socket timeouts for the Bunny amqp gem}
|
13
|
+
|
14
|
+
s.rubyforge_project = "bunny-ext"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.add_dependency('bunny', '= 0.6.0')
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Bunny
|
2
|
+
class Client < Qrack::Client
|
3
|
+
# Overwritten with a version that uses Bunny::Timer::timeout
|
4
|
+
# instead of Object#timeout which is either timeout.rb (ruby 1.9.x)
|
5
|
+
# or SystemTimer (ruby 1.8.x)
|
6
|
+
# read: http://ph7spot.com/musings/system-timer
|
7
|
+
def next_frame(opts = {})
|
8
|
+
frame = nil
|
9
|
+
|
10
|
+
case
|
11
|
+
when channel.frame_buffer.size > 0
|
12
|
+
frame = channel.frame_buffer.shift
|
13
|
+
when opts.has_key?(:timeout)
|
14
|
+
Bunny::Timer::timeout(opts[:timeout], Qrack::ClientTimeout) do
|
15
|
+
frame = Qrack::Transport::Frame.parse(buffer)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
frame = Qrack::Transport::Frame.parse(buffer)
|
19
|
+
end
|
20
|
+
|
21
|
+
@logger.info("received") { frame } if @logging
|
22
|
+
|
23
|
+
raise Bunny::ConnectionError, 'No connection to server' if (frame.nil? and !connecting?)
|
24
|
+
|
25
|
+
# Monitor server activity and discard heartbeats
|
26
|
+
@message_in = true
|
27
|
+
|
28
|
+
case
|
29
|
+
when frame.is_a?(Qrack::Transport::Heartbeat)
|
30
|
+
next_frame(opts)
|
31
|
+
when frame.nil?
|
32
|
+
frame
|
33
|
+
when ((frame.channel != channel.number) and (frame.channel != 0))
|
34
|
+
channel.frame_buffer << frame
|
35
|
+
next_frame(opts)
|
36
|
+
else
|
37
|
+
frame
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Bunny
|
2
|
+
class Client < Qrack::Client
|
3
|
+
# Overwritten with a version that uses Bunny::Timer::timeout
|
4
|
+
# instead of Object#timeout which is either timeout.rb (ruby 1.9.x)
|
5
|
+
# or SystemTimer (ruby 1.8.x)
|
6
|
+
# read: http://ph7spot.com/musings/system-timer
|
7
|
+
def next_frame(opts = {})
|
8
|
+
frame = nil
|
9
|
+
|
10
|
+
case
|
11
|
+
when channel.frame_buffer.size > 0
|
12
|
+
frame = channel.frame_buffer.shift
|
13
|
+
when opts.has_key?(:timeout)
|
14
|
+
Bunny::Timer::timeout(opts[:timeout], Qrack::ClientTimeout) do
|
15
|
+
frame = Qrack::Transport09::Frame.parse(buffer)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
frame = Qrack::Transport09::Frame.parse(buffer)
|
19
|
+
end
|
20
|
+
|
21
|
+
@logger.info("received") { frame } if @logging
|
22
|
+
|
23
|
+
raise Bunny::ConnectionError, 'No connection to server' if (frame.nil? and !connecting?)
|
24
|
+
|
25
|
+
# Monitor server activity and discard heartbeats
|
26
|
+
@message_in = true
|
27
|
+
|
28
|
+
case
|
29
|
+
when frame.is_a?(Qrack::Transport09::Heartbeat)
|
30
|
+
next_frame(opts)
|
31
|
+
when frame.nil?
|
32
|
+
frame
|
33
|
+
when ((frame.channel != channel.number) and (frame.channel != 0))
|
34
|
+
channel.frame_buffer << frame
|
35
|
+
next_frame(opts)
|
36
|
+
else
|
37
|
+
frame
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'qrack/client'
|
2
|
+
|
3
|
+
|
4
|
+
module Qrack
|
5
|
+
class Client
|
6
|
+
SOCKET_TIMEOUT = 5.0
|
7
|
+
|
8
|
+
alias initialize_without_timeout_opts initialize
|
9
|
+
def initialize_with_timeout_opts(opts = {})
|
10
|
+
initialize_without_timeout_opts
|
11
|
+
@socket_timeout = opts[:socket_timeout] || SOCKET_TIMEOUT
|
12
|
+
@use_timeout = RUBY_VERSION >= "1.9"
|
13
|
+
end
|
14
|
+
alias initialize initialize_with_timeout_opts
|
15
|
+
|
16
|
+
# Overwritten with a version that uses Bunny::Timer::timeout
|
17
|
+
# instead of Object#timeout which is either timeout.rb (ruby 1.9.x)
|
18
|
+
# or SystemTimer (ruby 1.8.x)
|
19
|
+
# read: http://ph7spot.com/musings/system-timer
|
20
|
+
def send_command(cmd, *args)
|
21
|
+
begin
|
22
|
+
raise Bunny::ConnectionError, 'No connection - socket has not been created' if !@socket
|
23
|
+
if @use_timeout
|
24
|
+
Bunny::Timer::timeout(@socket_timeout, Qrack::ClientTimeout) do
|
25
|
+
@socket.__send__(cmd, *args)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
@socket.__send__(cmd, *args)
|
29
|
+
end
|
30
|
+
rescue Errno::EPIPE, Errno::EAGAIN, Qrack::ClientTimeout, IOError => e
|
31
|
+
raise Bunny::ServerDownError, e.message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set socket send and receive timeouts and let the operating system deal
|
36
|
+
# with these timeouts. If setting those isn't supported (for example on solaris)
|
37
|
+
# we use the Bunny::Timer::timeout method to wrap all socket accesses
|
38
|
+
def set_socket_timeouts
|
39
|
+
return if @status == :not_connected
|
40
|
+
secs = Integer(@socket_timeout)
|
41
|
+
usecs = Integer((@socket_timeout - secs) * 1_000_000)
|
42
|
+
optval = [secs, usecs].pack("l_2")
|
43
|
+
begin
|
44
|
+
@socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
45
|
+
@socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
46
|
+
rescue Errno::ENOPROTOOPT
|
47
|
+
@use_timeout = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def socket
|
52
|
+
return @socket if @socket and (@status == :connected) and not @socket.closed?
|
53
|
+
|
54
|
+
begin
|
55
|
+
# Attempt to connect.
|
56
|
+
@socket = Bunny::Timer::timeout(@connect_timeout, ConnectionTimeout) do
|
57
|
+
TCPSocket.new(host, port)
|
58
|
+
end
|
59
|
+
|
60
|
+
if Socket.constants.include? 'TCP_NODELAY'
|
61
|
+
@socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
62
|
+
end
|
63
|
+
|
64
|
+
if @ssl
|
65
|
+
require 'openssl' unless defined? OpenSSL::SSL
|
66
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@socket)
|
67
|
+
@socket.sync_close = true
|
68
|
+
@socket.connect
|
69
|
+
@socket.post_connection_check(host) if @verify_ssl
|
70
|
+
@socket
|
71
|
+
end
|
72
|
+
rescue => e
|
73
|
+
@status = :not_connected
|
74
|
+
raise Bunny::ServerDownError, e.message
|
75
|
+
end
|
76
|
+
|
77
|
+
set_socket_timeouts
|
78
|
+
|
79
|
+
@socket
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/bunny-ext.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
|
3
|
+
module Bunny
|
4
|
+
Timer = if RUBY_VERSION < "1.9"
|
5
|
+
begin
|
6
|
+
require 'system_timer'
|
7
|
+
SystemTimer
|
8
|
+
rescue LoadError
|
9
|
+
Timeout
|
10
|
+
end
|
11
|
+
else
|
12
|
+
Timeout
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def self.setup(version, opts)
|
17
|
+
if version == '08'
|
18
|
+
# AMQP 0-8 specification
|
19
|
+
require 'qrack/qrack08'
|
20
|
+
require 'bunny-ext/qrack/client'
|
21
|
+
require 'bunny/client08'
|
22
|
+
require 'bunny-ext/bunny/client08'
|
23
|
+
require 'bunny/exchange08'
|
24
|
+
require 'bunny/queue08'
|
25
|
+
require 'bunny/channel08'
|
26
|
+
require 'bunny/subscription08'
|
27
|
+
|
28
|
+
client = Bunny::Client.new(opts)
|
29
|
+
else
|
30
|
+
# AMQP 0-9-1 specification
|
31
|
+
require 'qrack/qrack09'
|
32
|
+
require 'bunny-ext/qrack/client'
|
33
|
+
require 'bunny/client09'
|
34
|
+
require 'bunny-ext/bunny/client09'
|
35
|
+
require 'bunny/exchange09'
|
36
|
+
require 'bunny/queue09'
|
37
|
+
require 'bunny/channel09'
|
38
|
+
require 'bunny/subscription09'
|
39
|
+
|
40
|
+
client = Bunny::Client09.new(opts)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class QrackClientExtTest < Test::Unit::TestCase
|
4
|
+
def test_should_monkeypatch_the_client_class
|
5
|
+
Bunny.send :setup, "0.8", {}
|
6
|
+
assert Bunny::Client.instance_methods.include? "set_socket_timeouts"
|
7
|
+
end
|
8
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bunny-ext
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 5
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 1
|
10
|
+
version: 0.6.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Stefan Kaes
|
14
|
+
- Pascal Friederich
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-11-19 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: bunny
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - "="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 7
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
- 6
|
34
|
+
- 0
|
35
|
+
version: 0.6.0
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
description:
|
39
|
+
email:
|
40
|
+
- developers@xing.com
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- Rakefile
|
51
|
+
- bunny-ext.gemspec
|
52
|
+
- lib/bunny-ext.rb
|
53
|
+
- lib/bunny-ext/bunny/client08.rb
|
54
|
+
- lib/bunny-ext/bunny/client09.rb
|
55
|
+
- lib/bunny-ext/qrack/client.rb
|
56
|
+
- lib/bunny-ext/version.rb
|
57
|
+
- test/bunny-ext/qrack_client_ext_test.rb
|
58
|
+
- test/test_helper.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: ""
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: bunny-ext
|
89
|
+
rubygems_version: 1.3.7
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Reliable socket timeouts for the Bunny amqp gem
|
93
|
+
test_files:
|
94
|
+
- test/bunny-ext/qrack_client_ext_test.rb
|
95
|
+
- test/test_helper.rb
|