onstomp 1.0.0pre1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/Rakefile +8 -0
- data/examples/openuri.rb +36 -0
- data/lib/onstomp.rb +4 -0
- data/lib/onstomp/client.rb +6 -5
- data/lib/onstomp/components.rb +0 -1
- data/lib/onstomp/components/frame_headers.rb +35 -38
- data/lib/onstomp/components/threaded_processor.rb +13 -0
- data/lib/onstomp/connections/base.rb +15 -8
- data/lib/onstomp/connections/stomp_1.rb +0 -6
- data/lib/onstomp/connections/stomp_1_0.rb +8 -0
- data/lib/onstomp/connections/stomp_1_1.rb +8 -0
- data/lib/onstomp/failover.rb +16 -0
- data/lib/onstomp/failover/buffers.rb +8 -0
- data/lib/onstomp/failover/buffers/written.rb +91 -0
- data/lib/onstomp/failover/client.rb +127 -0
- data/lib/onstomp/failover/failover_configurable.rb +63 -0
- data/lib/onstomp/failover/failover_events.rb +96 -0
- data/lib/onstomp/failover/new_with_failover.rb +20 -0
- data/lib/onstomp/failover/pools.rb +8 -0
- data/lib/onstomp/failover/pools/base.rb +39 -0
- data/lib/onstomp/failover/pools/round_robin.rb +17 -0
- data/lib/onstomp/failover/uri.rb +34 -0
- data/lib/onstomp/interfaces/client_configurable.rb +2 -6
- data/lib/onstomp/interfaces/client_events.rb +4 -0
- data/lib/onstomp/interfaces/connection_events.rb +3 -3
- data/lib/onstomp/interfaces/event_manager.rb +8 -0
- data/lib/onstomp/interfaces/uri_configurable.rb +7 -7
- data/lib/onstomp/open-uri.rb +37 -0
- data/lib/onstomp/open-uri/client_extensions.rb +88 -0
- data/lib/onstomp/open-uri/message_queue.rb +38 -0
- data/lib/onstomp/version.rb +1 -1
- data/spec/onstomp/client_spec.rb +1 -4
- data/spec/onstomp/components/frame_headers_spec.rb +2 -5
- data/spec/onstomp/connections/stomp_1_0_spec.rb +22 -0
- data/spec/onstomp/connections/stomp_1_1_spec.rb +22 -0
- data/spec/onstomp/connections/stomp_1_spec.rb +2 -19
- data/spec/onstomp/connections_spec.rb +4 -0
- data/spec/onstomp/failover/buffers/written_spec.rb +8 -0
- data/spec/onstomp/failover/client_spec.rb +38 -0
- data/spec/onstomp/failover/failover_events_spec.rb +75 -0
- data/spec/onstomp/failover/new_with_failover_spec.rb +16 -0
- data/spec/onstomp/failover/pools/base_spec.rb +54 -0
- data/spec/onstomp/failover/pools/round_robin_spec.rb +27 -0
- data/spec/onstomp/failover/uri_spec.rb +21 -0
- data/spec/onstomp/full_stacks/failover_spec.rb +55 -0
- data/spec/onstomp/full_stacks/onstomp_spec.rb +15 -0
- data/spec/onstomp/full_stacks/open-uri_spec.rb +40 -0
- data/spec/onstomp/full_stacks/ssl/README +6 -0
- data/spec/onstomp/full_stacks/ssl/broker_cert.csr +17 -0
- data/spec/onstomp/full_stacks/ssl/broker_cert.pem +72 -0
- data/spec/onstomp/full_stacks/ssl/broker_key.pem +27 -0
- data/spec/onstomp/full_stacks/ssl/client_cert.csr +17 -0
- data/spec/onstomp/full_stacks/ssl/client_cert.pem +72 -0
- data/spec/onstomp/full_stacks/ssl/client_key.pem +27 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/cacert.pem +17 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/index.txt +2 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/index.txt.attr +1 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/index.txt.attr.old +1 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/index.txt.old +1 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/newcerts/01.pem +72 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/newcerts/02.pem +72 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/private/cakey.pem +17 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/serial +1 -0
- data/spec/onstomp/full_stacks/ssl/demoCA/serial.old +1 -0
- data/spec/onstomp/full_stacks/test_broker.rb +251 -0
- data/spec/onstomp/interfaces/connection_events_spec.rb +3 -1
- data/spec/onstomp/open-uri/client_extensions_spec.rb +113 -0
- data/spec/onstomp/open-uri/message_queue_spec.rb +29 -0
- data/spec/onstomp/open-uri_spec.rb +43 -0
- data/spec/spec_helper.rb +2 -0
- data/yard_extensions.rb +5 -1
- metadata +82 -8
- data/lib/onstomp/components/nil_processor.rb +0 -20
- data/spec/onstomp/components/nil_processor_spec.rb +0 -32
@@ -0,0 +1,127 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# A failover client that wraps multiple {OnStomp::Client clients} and maintains
|
4
|
+
# a connection to one of these clients. Frames are sent to the currently
|
5
|
+
# connected client. If the connection is lost, a failover client will
|
6
|
+
# automatically reconnect to another client in the pool, re-transmit any
|
7
|
+
# necessary frames and resume operation.
|
8
|
+
class OnStomp::Failover::Client
|
9
|
+
include OnStomp::Failover::FailoverConfigurable
|
10
|
+
include OnStomp::Failover::FailoverEvents
|
11
|
+
include OnStomp::Interfaces::FrameMethods
|
12
|
+
|
13
|
+
# The class to use when instantiating a new {#client_pool}.
|
14
|
+
# Defaults to {OnStomp::Failover::Pools::RoundRobin}
|
15
|
+
# @return [Class]
|
16
|
+
attr_configurable_pool :pool
|
17
|
+
# The class to use when instantiating a new frame buffer.
|
18
|
+
# Defaults to {OnStomp::Failover::Buffers::Written}
|
19
|
+
# @return [Class]
|
20
|
+
attr_configurable_buffer :buffer
|
21
|
+
# The delay in seconds to wait between connection retries.
|
22
|
+
# Defaults to +10+.
|
23
|
+
# @return [Fixnum]
|
24
|
+
attr_configurable_int :retry_delay, :default => 10
|
25
|
+
# The maximum number of times to retry connecting during a reconnect
|
26
|
+
# loop. A non-positive number will force the failover client to try to
|
27
|
+
# reconnect indefinitely. Defaults to +0+
|
28
|
+
# @return [Fixnum]
|
29
|
+
attr_configurable_int :retry_attempts, :default => 0
|
30
|
+
# Whether or not to randomize the {#client_pool} before connecting through
|
31
|
+
# any of its {OnStomp::Client clients}. Defaults to +false+
|
32
|
+
# @return [true,false]
|
33
|
+
attr_configurable_bool :randomize, :default => false
|
34
|
+
|
35
|
+
attr_reader :uri, :client_pool, :active_client, :frame_buffer, :connection
|
36
|
+
|
37
|
+
def initialize(uris, options={})
|
38
|
+
if uris.is_a?(Array)
|
39
|
+
uris = "failover:(#{uris.map { |u| u.to_s }.join(',')})"
|
40
|
+
end
|
41
|
+
@client_mutex = Mutex.new
|
42
|
+
@uri = URI.parse(uris)
|
43
|
+
configure_configurable options
|
44
|
+
create_client_pool
|
45
|
+
@active_client = nil
|
46
|
+
@connection = nil
|
47
|
+
@frame_buffer = buffer.new self
|
48
|
+
@disconnecting = false
|
49
|
+
@client_ready = false
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns true if there is an {#active_client} and it is
|
53
|
+
# {OnStomp::Client#connected? connected}.
|
54
|
+
# @return [true,false,nil]
|
55
|
+
def connected?
|
56
|
+
active_client && active_client.connected?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Transmits a frame to the {#active_client} if one exists.
|
60
|
+
# @return [OnStomp::Components::Frame,nil]
|
61
|
+
def transmit frame, cbs={}
|
62
|
+
active_client && active_client.transmit(frame, cbs)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Connects to one of the clients in the {#client_pool}
|
66
|
+
# @return [self]
|
67
|
+
def connect
|
68
|
+
@disconnecting = false
|
69
|
+
unless reconnect
|
70
|
+
raise OnStomp::Failover::MaximumRetriesExceededError
|
71
|
+
end
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Ensures that a connection is properly established, then invokes
|
76
|
+
# {OnStomp::Client#disconnect disconnect} on the {#active_client}
|
77
|
+
def disconnect *args, &block
|
78
|
+
return unless active_client
|
79
|
+
@disconnecting = true
|
80
|
+
Thread.pass until @client_ready
|
81
|
+
active_client.disconnect *args, &block
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
def reconnect
|
86
|
+
@client_mutex.synchronize do
|
87
|
+
@client_ready = false
|
88
|
+
attempt = 1
|
89
|
+
until connected? || retry_exceeded?(attempt)
|
90
|
+
sleep_for_retry attempt
|
91
|
+
begin
|
92
|
+
trigger_failover_retry :before, attempt
|
93
|
+
@active_client = client_pool.next_client
|
94
|
+
# +reconnect+ could be called again within the marked range.
|
95
|
+
active_client.connect # <--- From here
|
96
|
+
@connection = active_client.connection
|
97
|
+
rescue Exception
|
98
|
+
trigger_failover_event :connect_failure, :on, active_client, $!.message
|
99
|
+
end
|
100
|
+
trigger_failover_retry :after, attempt
|
101
|
+
attempt += 1
|
102
|
+
end
|
103
|
+
connected?.tap do |b|
|
104
|
+
b && trigger_failover_event(:connected, :on, active_client)
|
105
|
+
@client_ready = b
|
106
|
+
end # <--- Until here
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def retry_exceeded? attempt
|
111
|
+
retry_attempts > 0 && attempt > retry_attempts
|
112
|
+
end
|
113
|
+
|
114
|
+
def sleep_for_retry attempt
|
115
|
+
sleep(retry_delay) if retry_delay > 0 && attempt > 1
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_client_pool
|
119
|
+
@client_pool = pool.new(uri.failover_uris)
|
120
|
+
on_connection_closed do |client, *_|
|
121
|
+
unless @disconnecting
|
122
|
+
trigger_failover_event(:lost, :on, active_client)
|
123
|
+
reconnect
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Module for configurable attributes specific to
|
4
|
+
# {OnStomp::Failover::Client failover} clients.
|
5
|
+
module OnStomp::Failover::FailoverConfigurable
|
6
|
+
# Includes {OnStomp::Interfaces::ClientConfigurable} into +base+ and
|
7
|
+
# extends {OnStomp::Failover::FailoverConfigurable::ClassMethods}
|
8
|
+
# @param [Module] base
|
9
|
+
def self.included(base)
|
10
|
+
base.__send__ :include, OnStomp::Interfaces::ClientConfigurable
|
11
|
+
base.extend ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
# Provides attribute methods for {OnStomp::Failover::Client failover}
|
15
|
+
# clients.
|
16
|
+
module ClassMethods
|
17
|
+
# Creates readable and writeable attributes that are automatically
|
18
|
+
# converted into integers.
|
19
|
+
def attr_configurable_int *args, &block
|
20
|
+
trans = attr_configurable_wrap lambda { |v| v.to_i }, block
|
21
|
+
attr_configurable_single(*args, &trans)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates readable and writeable attributes that are automatically
|
25
|
+
# converted into boolean values. Assigning the attributes any of
|
26
|
+
# +true+, +'true'+, +'1'+ or +1+ will set the attribute to +true+, all
|
27
|
+
# other values with be treated as +false+. This method will also alias
|
28
|
+
# the reader methods with +attr_name?+
|
29
|
+
def attr_configurable_bool *args, &block
|
30
|
+
trans = attr_configurable_wrap lambda { |v|
|
31
|
+
[true, 'true', '1', 1].include?(v) }, block
|
32
|
+
attr_configurable_single(*args, &trans)
|
33
|
+
args.each do |a|
|
34
|
+
unless a.is_a?(Hash)
|
35
|
+
alias_method :"#{a}?", a
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates a readable and writeable attribute with the given name that
|
41
|
+
# defaults to the {OnStomp::Failover::Pools::RoundRobin}. Corresponds
|
42
|
+
# the the class to use when creating new
|
43
|
+
# {OnStomp::Failover::Client#client_pool client pools}.
|
44
|
+
# @param [Symbol] nm name of attribute
|
45
|
+
def attr_configurable_pool nm
|
46
|
+
attr_configurable_class(nm,
|
47
|
+
:default => OnStomp::Failover::Pools::RoundRobin) do |p|
|
48
|
+
p || OnStomp::Failover::Pools::RoundRobin
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates a readable and writeable attribute with the given name that
|
53
|
+
# defaults to the {OnStomp::Failover::Buffers::Written}. Corresponds
|
54
|
+
# the the class to use for frame buffering and de-buffering.
|
55
|
+
# @param [Symbol] nm name of attribute
|
56
|
+
def attr_configurable_buffer nm
|
57
|
+
attr_configurable_class(nm,
|
58
|
+
:default => OnStomp::Failover::Buffers::Written) do |b|
|
59
|
+
b || OnStomp::Failover::Buffers::Written
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Events mixin for {OnStomp::Failover::Client failover} clients.
|
4
|
+
module OnStomp::Failover::FailoverEvents
|
5
|
+
include OnStomp::Interfaces::EventManager
|
6
|
+
|
7
|
+
# We do this one using +class << self+ instead of the +self.included+ hook
|
8
|
+
# because we need 'create_client_event_method+ immediately.
|
9
|
+
class << self
|
10
|
+
# Creates a forwarded binding for client events.
|
11
|
+
def create_client_event_method name
|
12
|
+
module_eval "def #{name}(&block); bind_client_event(:#{name}, block); end"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create forwarded bindings for all {OnStomp::Client} events.
|
17
|
+
OnStomp::Interfaces::ClientEvents.event_methods.each do |ev|
|
18
|
+
create_client_event_method ev
|
19
|
+
end
|
20
|
+
|
21
|
+
# Binds a callback to {OnStomp::Client#on_connction_established}. This has
|
22
|
+
# to be handled directly because :on_connection_established isn't a true
|
23
|
+
# event.
|
24
|
+
def on_connection_established &block
|
25
|
+
bind_client_event(:on_connection_established, block)
|
26
|
+
end
|
27
|
+
# Binds a callback to {OnStomp::Client#on_connection_died}. This has
|
28
|
+
# to be handled directly because :on_connection_died isn't a true
|
29
|
+
# event.
|
30
|
+
def on_connection_died &block
|
31
|
+
bind_client_event(:on_connection_died, block)
|
32
|
+
end
|
33
|
+
# Binds a callback to {OnStomp::Client#on_connection_terminated}. This has
|
34
|
+
# to be handled directly because :on_connection_terminated isn't a true
|
35
|
+
# event.
|
36
|
+
def on_connection_terminated &block
|
37
|
+
bind_client_event(:on_connection_terminated, block)
|
38
|
+
end
|
39
|
+
# Binds a callback to {OnStomp::Client#on_connection_closed}. This has
|
40
|
+
# to be handled directly because :on_connection_closed isn't a true
|
41
|
+
# event.
|
42
|
+
def on_connection_closed &block
|
43
|
+
bind_client_event(:on_connection_closed, block)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets up a forwarded event binding, applying it to all clients in
|
47
|
+
# {OnStomp::Failover::Client#client_pool}.
|
48
|
+
def bind_client_event(name, block)
|
49
|
+
client_pool.each do |client|
|
50
|
+
client.__send__ name do |*args|
|
51
|
+
if client == active_client
|
52
|
+
block.call *args
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Binds a callback to be invoked when a failover client is attempting to
|
59
|
+
# connect through a new {OnStomp::Client client} in its
|
60
|
+
# {OnStomp::Failover::Client#pool}.
|
61
|
+
# @yield [failover, attempt, client] callback invoked when event is triggered
|
62
|
+
# @yieldparam [OnStomp::Failover::Client] failover
|
63
|
+
# @yieldparam [Fixnum] attempt
|
64
|
+
# @yieldparam [OnStomp::Client] client
|
65
|
+
create_event_methods :failover_retry, :before, :after
|
66
|
+
# Binds a callback to be invoked when a failover client fails to establish
|
67
|
+
# a connection through a {OnStomp::Client client} while reconnecting.
|
68
|
+
# @yield [failover, client, error_message] callback invoked when event is triggered
|
69
|
+
# @yieldparam [OnStomp::Failover::Client] failover
|
70
|
+
# @yieldparam [OnStomp::Client] client
|
71
|
+
# @yieldparam [String] error_message
|
72
|
+
create_event_methods :failover_connect_failure, :on
|
73
|
+
#create_event_methods :failover_retries_exceeded, :on
|
74
|
+
# Binds a callback to be invoked when an established connection through a
|
75
|
+
# client is lost.
|
76
|
+
# @yield [failover, client] callback invoked when event is triggered
|
77
|
+
# @yieldparam [OnStomp::Failover::Client] failover
|
78
|
+
# @yieldparam [OnStomp::Client] client
|
79
|
+
create_event_methods :failover_lost, :on
|
80
|
+
# Binds a callback to be invoked when a connection through a
|
81
|
+
# client is established.
|
82
|
+
# @yield [failover, client] callback invoked when event is triggered
|
83
|
+
# @yieldparam [OnStomp::Failover::Client] failover
|
84
|
+
# @yieldparam [OnStomp::Client] client
|
85
|
+
create_event_methods :failover_connected, :on
|
86
|
+
|
87
|
+
# Triggers a failover retry event
|
88
|
+
def trigger_failover_retry pref, attempt
|
89
|
+
trigger_failover_event :retry, pref, attempt, self.active_client
|
90
|
+
end
|
91
|
+
|
92
|
+
# Triggers a general failover event
|
93
|
+
def trigger_failover_event ev, pref, *args
|
94
|
+
trigger_event :"#{pref}_failover_#{ev}", self, *args
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class OnStomp::Client
|
4
|
+
class << self
|
5
|
+
# Creates an alias chain for {OnStomp::Client.new} so that if
|
6
|
+
# a failover: URI or an array of URIs are passed to the constructor,
|
7
|
+
# a {OnStomp::Failover::Client failover} client is built instead.
|
8
|
+
# @return [OnStomp::Client,OnStomp::Failover::Client]
|
9
|
+
def new_with_failover(uri, options={})
|
10
|
+
if uri.is_a?(Array) || uri.to_s =~ /^failover:/i
|
11
|
+
OnStomp::Failover::Client.new(uri, options)
|
12
|
+
else
|
13
|
+
new_without_failover(uri, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
alias :new_without_failover :new
|
18
|
+
alias :new :new_with_failover
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# An abstract pool of clients. This class manages the shared behaviors
|
4
|
+
# of client pools, but has no means of picking successive clients.
|
5
|
+
# Subclasses must define +next_client+ or pool will not function.
|
6
|
+
class OnStomp::Failover::Pools::Base
|
7
|
+
attr_reader :clients
|
8
|
+
|
9
|
+
# Creates a new client pool by mapping an array of URIs into an array of
|
10
|
+
# {OnStomp::Client clients}.
|
11
|
+
def initialize uris
|
12
|
+
@clients = uris.map do |u|
|
13
|
+
OnStomp::Client.new u
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Raises an error, because it is up to subclasses to define this behavior.
|
18
|
+
# @raise [StandardError]
|
19
|
+
def next_client
|
20
|
+
raise 'implemented in subclasses'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Shuffles the client pool.
|
24
|
+
def shuffle!
|
25
|
+
clients.shuffle!
|
26
|
+
end
|
27
|
+
|
28
|
+
# Yields each client in the pool to the supplied block. Raises an error
|
29
|
+
# if no block is provided.
|
30
|
+
# @raise [ArgumentError] if no block is given
|
31
|
+
# @yield [client] block to call for each client in the pool
|
32
|
+
# @yieldparam [OnStomp::Client] client
|
33
|
+
# @return [self]
|
34
|
+
def each &block
|
35
|
+
raise ArgumentError, 'no block provided' unless block_given?
|
36
|
+
clients.each &block
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# A round-robin client pool. Clients are processed sequentially, and once
|
4
|
+
# all clients have been processed, the pool cycles back to the beginning.
|
5
|
+
class OnStomp::Failover::Pools::RoundRobin < OnStomp::Failover::Pools::Base
|
6
|
+
def initialize uris
|
7
|
+
super
|
8
|
+
@index = -1
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the next sequential client in the pool
|
12
|
+
# @return [OnStomp::Client]
|
13
|
+
def next_client
|
14
|
+
@index = (@index + 1) % clients.size
|
15
|
+
clients[@index]
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Namespace for failover related URI classes.
|
4
|
+
module OnStomp::Failover::URI
|
5
|
+
# A URI class for representing URIs with a 'failover' scheme.
|
6
|
+
class FAILOVER < OnStomp::Components::URI::STOMP
|
7
|
+
# Matches the internal URIs and query contained in
|
8
|
+
# the +opaque+ part of a failover: URI
|
9
|
+
FAILOVER_OPAQUE_REG = /^\(([^\)]+)\)(?:\?(.*))?/
|
10
|
+
|
11
|
+
attr_reader :failover_uris
|
12
|
+
def initialize(*args)
|
13
|
+
super
|
14
|
+
_split_opaque_
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def _split_opaque_
|
19
|
+
if opaque =~ FAILOVER_OPAQUE_REG
|
20
|
+
furis, fquery = $1, $2
|
21
|
+
@failover_uris = furis.split(',').map { |u| ::URI.parse(u.strip) }
|
22
|
+
self.set_opaque nil
|
23
|
+
self.set_path ''
|
24
|
+
self.set_query fquery
|
25
|
+
else
|
26
|
+
raise OnStomp::Failover::InvalidFailoverURIError, self.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ::URI
|
33
|
+
@@schemes['FAILOVER'] = OnStomp::Failover::URI::FAILOVER
|
34
|
+
end
|
@@ -40,16 +40,12 @@ module OnStomp::Interfaces::ClientConfigurable
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# Creates a readable and writeable attribute with the given name that
|
43
|
-
# defaults to the {OnStomp::Components::ThreadedProcessor}
|
44
|
-
# to nil will instead use {OnStomp::Components::NilProcessor}. Corresponds
|
43
|
+
# defaults to the {OnStomp::Components::ThreadedProcessor}. Corresponds
|
45
44
|
# the the class to use when create new processor instances when a client
|
46
45
|
# is connected.
|
47
46
|
# @param [Symbol] nm name of attribute
|
48
47
|
def attr_configurable_processor nm
|
49
|
-
attr_configurable_class(nm,
|
50
|
-
:default => OnStomp::Components::ThreadedProcessor) do |pr|
|
51
|
-
pr || OnStomp::Components::NilProcessor
|
52
|
-
end
|
48
|
+
attr_configurable_class(nm, :default => OnStomp::Components::ThreadedProcessor)
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
@@ -12,6 +12,10 @@ module OnStomp::Interfaces::ClientEvents
|
|
12
12
|
|
13
13
|
# @group Client Frame Event Bindings
|
14
14
|
|
15
|
+
# Can't get +before+ because the CONNECT frame isn't transmitted by
|
16
|
+
# the client.
|
17
|
+
create_event_methods :connect, :on
|
18
|
+
|
15
19
|
# Binds a callback to be invoked when an ACK frame is transmitted
|
16
20
|
# @yield [frame, client] callback invoked when event is triggered
|
17
21
|
# @yieldparam [OnStomp::Components::Frame] frame
|
@@ -42,8 +42,8 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
42
42
|
|
43
43
|
# Triggers a connection specific event.
|
44
44
|
# @param [Symbol] event name
|
45
|
-
def trigger_connection_event event
|
46
|
-
trigger_event :"on_#{event}", self.client, self
|
45
|
+
def trigger_connection_event event, msg=''
|
46
|
+
trigger_event :"on_#{event}", self.client, self, msg
|
47
47
|
end
|
48
48
|
|
49
49
|
# Takes a hash of event bindings a {OnStomp::Client client} has stored
|
@@ -57,6 +57,6 @@ module OnStomp::Interfaces::ConnectionEvents
|
|
57
57
|
ev_hash.each do |ev, cbs|
|
58
58
|
cbs.each { |cb| bind_event(ev, cb) }
|
59
59
|
end
|
60
|
-
trigger_connection_event :established
|
60
|
+
trigger_connection_event :established, "STOMP #{self.version} connection negotiated"
|
61
61
|
end
|
62
62
|
end
|