qpid_proton 0.9.0 → 0.10
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.
- checksums.yaml +4 -4
- data/lib/codec/data.rb +912 -0
- data/lib/codec/mapping.rb +169 -0
- data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
- data/lib/core/connection.rb +328 -0
- data/lib/core/delivery.rb +271 -0
- data/lib/core/disposition.rb +158 -0
- data/lib/core/endpoint.rb +140 -0
- data/lib/{qpid_proton → core}/exceptions.rb +43 -2
- data/lib/core/link.rb +387 -0
- data/lib/core/message.rb +633 -0
- data/lib/core/receiver.rb +95 -0
- data/lib/core/sasl.rb +94 -0
- data/lib/core/selectable.rb +130 -0
- data/lib/core/sender.rb +76 -0
- data/lib/core/session.rb +163 -0
- data/lib/core/ssl.rb +164 -0
- data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
- data/lib/core/ssl_domain.rb +156 -0
- data/lib/core/terminus.rb +218 -0
- data/lib/core/transport.rb +411 -0
- data/lib/core/url.rb +77 -0
- data/lib/event/collector.rb +148 -0
- data/lib/event/event.rb +318 -0
- data/lib/event/event_base.rb +91 -0
- data/lib/event/event_type.rb +71 -0
- data/lib/handler/acking.rb +70 -0
- data/lib/handler/c_adaptor.rb +47 -0
- data/lib/handler/c_flow_controller.rb +33 -0
- data/lib/handler/endpoint_state_handler.rb +217 -0
- data/lib/handler/incoming_message_handler.rb +74 -0
- data/lib/handler/messaging_handler.rb +218 -0
- data/lib/handler/outgoing_message_handler.rb +98 -0
- data/lib/handler/wrapped_handler.rb +76 -0
- data/lib/messenger/messenger.rb +702 -0
- data/lib/messenger/subscription.rb +37 -0
- data/lib/messenger/tracker.rb +38 -0
- data/lib/messenger/tracker_status.rb +69 -0
- data/lib/qpid_proton.rb +106 -16
- data/lib/reactor/acceptor.rb +41 -0
- data/lib/reactor/backoff.rb +41 -0
- data/lib/reactor/connector.rb +98 -0
- data/lib/reactor/container.rb +272 -0
- data/lib/reactor/global_overrides.rb +44 -0
- data/lib/reactor/link_option.rb +90 -0
- data/lib/reactor/reactor.rb +198 -0
- data/lib/reactor/session_per_connection.rb +45 -0
- data/lib/reactor/ssl_config.rb +41 -0
- data/lib/reactor/task.rb +39 -0
- data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
- data/lib/{qpid_proton → types}/array.rb +28 -29
- data/lib/types/described.rb +63 -0
- data/lib/{qpid_proton → types}/hash.rb +4 -3
- data/lib/types/strings.rb +62 -0
- data/lib/util/class_wrapper.rb +54 -0
- data/lib/util/condition.rb +45 -0
- data/lib/util/constants.rb +85 -0
- data/lib/util/engine.rb +82 -0
- data/lib/util/error_handler.rb +127 -0
- data/lib/util/handler.rb +41 -0
- data/lib/util/reactor.rb +32 -0
- data/lib/util/swig_helper.rb +114 -0
- data/lib/util/timeout.rb +50 -0
- data/lib/util/uuid.rb +32 -0
- data/lib/util/version.rb +30 -0
- data/lib/util/wrapper.rb +124 -0
- metadata +67 -21
- data/ext/cproton/cproton.c +0 -22196
- data/lib/qpid_proton/data.rb +0 -788
- data/lib/qpid_proton/described.rb +0 -66
- data/lib/qpid_proton/exception_handling.rb +0 -127
- data/lib/qpid_proton/filters.rb +0 -67
- data/lib/qpid_proton/mapping.rb +0 -170
- data/lib/qpid_proton/message.rb +0 -621
- data/lib/qpid_proton/messenger.rb +0 -702
- data/lib/qpid_proton/selectable.rb +0 -126
- data/lib/qpid_proton/strings.rb +0 -65
- data/lib/qpid_proton/tracker_status.rb +0 -73
@@ -0,0 +1,272 @@
|
|
1
|
+
#--
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
4
|
+
# distributed with this work for additional information
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
7
|
+
# "License"); you may not use this file except in compliance
|
8
|
+
# with the License. You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
13
|
+
# software distributed under the License is distributed on an
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
+
# KIND, either express or implied. See the License for the
|
16
|
+
# specific language governing permissions and limitations
|
17
|
+
# under the License.
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Qpid::Proton::Reactor
|
21
|
+
|
22
|
+
# @private
|
23
|
+
class InternalTransactionHandler < Qpid::Proton::Handler::OutgoingMessageHandler
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_settled(event)
|
30
|
+
if event.delivery.respond_to? :transaction
|
31
|
+
event.transaction = event.delivery.transaction
|
32
|
+
event.delivery.transaction.handle_outcome(event)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# A representation of the AMQP concept of a container which, loosely
|
40
|
+
# speaking, is something that establishes links to or from another
|
41
|
+
# container on which messages are transferred.
|
42
|
+
#
|
43
|
+
# This is an extension to the Reactor classthat adds convenience methods
|
44
|
+
# for creating instances of Qpid::Proton::Connection, Qpid::Proton::Sender
|
45
|
+
# and Qpid::Proton::Receiver.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
#
|
49
|
+
class Container < Reactor
|
50
|
+
|
51
|
+
include Qpid::Proton::Util::Reactor
|
52
|
+
|
53
|
+
include Qpid::Proton::Util::UUID
|
54
|
+
|
55
|
+
attr_accessor :container_id
|
56
|
+
attr_accessor :global_handler
|
57
|
+
|
58
|
+
def initialize(handlers, options = {})
|
59
|
+
super(handlers, options)
|
60
|
+
|
61
|
+
# only do the following if we're creating a new instance
|
62
|
+
if !options.has_key?(:impl)
|
63
|
+
@ssl = SSLConfig.new
|
64
|
+
if options[:global_handler]
|
65
|
+
self.global_handler = GlobalOverrides.new(options[:global_handler])
|
66
|
+
else
|
67
|
+
# very ugly, but using self.global_handler doesn't work in the constructor
|
68
|
+
ghandler = Reactor.instance_method(:global_handler).bind(self).call
|
69
|
+
ghandler = GlobalOverrides.new(ghandler)
|
70
|
+
Reactor.instance_method(:global_handler=).bind(self).call(ghandler)
|
71
|
+
end
|
72
|
+
@trigger = nil
|
73
|
+
@container_id = generate_uuid
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Initiates the establishment of an AMQP connection.
|
78
|
+
#
|
79
|
+
# @param options [Hash] A hash of named arguments.
|
80
|
+
#
|
81
|
+
def connect(options = {})
|
82
|
+
conn = self.connection(options[:handler])
|
83
|
+
conn.container = self.container_id || generate_uuid
|
84
|
+
connector = Connector.new(conn)
|
85
|
+
conn.overrides = connector
|
86
|
+
if !options[:url].nil?
|
87
|
+
connector.address = URLs.new([options[:url]])
|
88
|
+
elsif !options[:urls].nil?
|
89
|
+
connector.address = URLs.new(options[:urls])
|
90
|
+
elsif !options[:address].nil?
|
91
|
+
connector.address = URLs.new([Qpid::Proton::URL.new(options[:address])])
|
92
|
+
else
|
93
|
+
raise ::ArgumentError.new("either :url or :urls or :address required")
|
94
|
+
end
|
95
|
+
|
96
|
+
connector.heartbeat = options[:heartbeat] if !options[:heartbeat].nil?
|
97
|
+
if !options[:reconnect].nil?
|
98
|
+
connector.reconnect = options[:reconnect]
|
99
|
+
else
|
100
|
+
connector.reconnect = Backoff.new()
|
101
|
+
end
|
102
|
+
|
103
|
+
connector.ssl_domain = SessionPerConnection.new # TODO seems this should be configurable
|
104
|
+
|
105
|
+
conn.open
|
106
|
+
|
107
|
+
return conn
|
108
|
+
end
|
109
|
+
|
110
|
+
def _session(context)
|
111
|
+
if context.is_a?(Qpid::Proton::URL)
|
112
|
+
return self._session(self.connect(:url => context))
|
113
|
+
elsif context.is_a?(Qpid::Proton::Session)
|
114
|
+
return context
|
115
|
+
elsif context.is_a?(Qpid::Proton::Connection)
|
116
|
+
if context.session_policy?
|
117
|
+
return context.session_policy.session(context)
|
118
|
+
else
|
119
|
+
return self.create_session(context)
|
120
|
+
end
|
121
|
+
else
|
122
|
+
return context.session
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Initiates the establishment of a link over which messages can be sent.
|
127
|
+
#
|
128
|
+
# @param context [String, URL] The context.
|
129
|
+
# @param opts [Hash] Additional options.
|
130
|
+
# @param opts [String, Qpid::Proton::URL] The target address.
|
131
|
+
# @param opts [String] :source The source address.
|
132
|
+
# @param opts [Boolean] :dynamic
|
133
|
+
# @param opts [Object] :handler
|
134
|
+
# @param opts [Object] :tag_generator The tag generator.
|
135
|
+
# @param opts [Hash] :options Addtional link options
|
136
|
+
#
|
137
|
+
# @return [Sender] The sender.
|
138
|
+
#
|
139
|
+
def create_sender(context, opts = {})
|
140
|
+
if context.is_a?(::String)
|
141
|
+
context = Qpid::Proton::URL.new(context)
|
142
|
+
end
|
143
|
+
|
144
|
+
target = opts[:target]
|
145
|
+
if context.is_a?(Qpid::Proton::URL) && target.nil?
|
146
|
+
target = context.path
|
147
|
+
end
|
148
|
+
|
149
|
+
session = self._session(context)
|
150
|
+
|
151
|
+
sender = session.sender(opts[:name] ||
|
152
|
+
id(session.connection.container,
|
153
|
+
target, opts[:source]))
|
154
|
+
sender.source.address = opts[:source] if !opts[:source].nil?
|
155
|
+
sender.target.address = target if target
|
156
|
+
sender.handler = opts[:handler] if !opts[:handler].nil?
|
157
|
+
sender.tag_generator = opts[:tag_generator] if !opts[:tag_gnenerator].nil?
|
158
|
+
self._apply_link_options(opts[:options], sender)
|
159
|
+
sender.open
|
160
|
+
return sender
|
161
|
+
end
|
162
|
+
|
163
|
+
# Initiates the establishment of a link over which messages can be received.
|
164
|
+
#
|
165
|
+
# There are two accepted arguments for the context
|
166
|
+
# 1. If a Connection is supplied then the link is established using that
|
167
|
+
# object. The source, and optionally the target, address can be supplied
|
168
|
+
# 2. If it is a String or a URL then a new Connection is created on which
|
169
|
+
# the link will be attached. If a path is specified, but not the source
|
170
|
+
# address, then the path of the URL is used as the target address.
|
171
|
+
#
|
172
|
+
# The name will be generated for the link if one is not specified.
|
173
|
+
#
|
174
|
+
# @param context [Connection, URL, String] The connection or the address.
|
175
|
+
# @param opts [Hash] Additional otpions.
|
176
|
+
# @option opts [String, Qpid::Proton::URL] The source address.
|
177
|
+
# @option opts [String] :target The target address
|
178
|
+
# @option opts [String] :name The link name.
|
179
|
+
# @option opts [Boolean] :dynamic
|
180
|
+
# @option opts [Object] :handler
|
181
|
+
# @option opts [Hash] :options Additional link options.
|
182
|
+
#
|
183
|
+
# @return [Receiver
|
184
|
+
#
|
185
|
+
def create_receiver(context, opts = {})
|
186
|
+
if context.is_a?(::String)
|
187
|
+
context = Qpid::Proton::URL.new(context)
|
188
|
+
end
|
189
|
+
|
190
|
+
source = opts[:source]
|
191
|
+
if context.is_a?(Qpid::Proton::URL) && source.nil?
|
192
|
+
source = context.path
|
193
|
+
end
|
194
|
+
|
195
|
+
session = self._session(context)
|
196
|
+
|
197
|
+
receiver = session.receiver(opts[:name] ||
|
198
|
+
id(session.connection.container,
|
199
|
+
source, opts[:target]))
|
200
|
+
receiver.source.address = source if source
|
201
|
+
receiver.source.dynamic = true if opts.has_key?(:dynamic) && opts[:dynamic]
|
202
|
+
receiver.target.address = opts[:target] if !opts[:target].nil?
|
203
|
+
receiver.handler = opts[:handler] if !opts[:handler].nil?
|
204
|
+
self._apply_link_options(opts[:options], receiver)
|
205
|
+
receiver.open
|
206
|
+
return receiver
|
207
|
+
end
|
208
|
+
|
209
|
+
def declare_transaction(context, handler = nil, settle_before_discharge = false)
|
210
|
+
if context.respond_to? :txn_ctl && !context.__send__(:txn_ctl).nil?
|
211
|
+
class << context
|
212
|
+
attr_accessor :txn_ctl
|
213
|
+
end
|
214
|
+
context.txn_ctl = self.create_sender(context, nil, "txn-ctl",
|
215
|
+
InternalTransactionHandler.new())
|
216
|
+
end
|
217
|
+
return Transaction.new(context.txn_ctl, handler, settle_before_discharge)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Initiates a server socket, accepting incoming AMQP connections on the
|
221
|
+
# interface and port specified.
|
222
|
+
#
|
223
|
+
# @param url []
|
224
|
+
# @param ssl_domain []
|
225
|
+
#
|
226
|
+
def listen(url, ssl_domain = nil)
|
227
|
+
url = Qpid::Proton::URL.new(url)
|
228
|
+
acceptor = self.acceptor(url.host, url.port)
|
229
|
+
ssl_config = ssl_domain
|
230
|
+
if ssl_config.nil? && (url.scheme == 'amqps') && @ssl
|
231
|
+
ssl_config = @ssl.server
|
232
|
+
end
|
233
|
+
if !ssl_config.nil?
|
234
|
+
acceptor.ssl_domain(ssl_config)
|
235
|
+
end
|
236
|
+
return acceptor
|
237
|
+
end
|
238
|
+
|
239
|
+
def do_work(timeout = nil)
|
240
|
+
self.timeout = timeout unless timeout.nil?
|
241
|
+
self.process
|
242
|
+
end
|
243
|
+
|
244
|
+
def id(container, remote, local)
|
245
|
+
if !local.nil? && !remote.nil?
|
246
|
+
"#{container}-#{remote}-#{local}"
|
247
|
+
elsif !local.nil?
|
248
|
+
"#{container}-#{local}"
|
249
|
+
elsif !remote.nil?
|
250
|
+
"#{container}-#{remote}"
|
251
|
+
else
|
252
|
+
"#{container}-#{generate_uuid}"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def _apply_link_options(options, link)
|
257
|
+
if !options.nil? && !options.empty?
|
258
|
+
if !options.is_a?(::List)
|
259
|
+
options = [Options].flatten
|
260
|
+
end
|
261
|
+
|
262
|
+
options.each {|option| o.apply(link) if o.test(link)}
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def to_s
|
267
|
+
"#{self.class}<@impl=#{Cproton.pni_address_of(@impl)}>"
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
4
|
+
# distributed with this work for additional information
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
7
|
+
# "License"); you may not use this file except in compliance
|
8
|
+
# with the License. You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
13
|
+
# software distributed under the License is distributed on an
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
+
# KIND, either express or implied. See the License for the
|
16
|
+
# specific language governing permissions and limitations
|
17
|
+
# under the License.
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Qpid::Proton::Reactor
|
21
|
+
|
22
|
+
class GlobalOverrides
|
23
|
+
|
24
|
+
def initialize(base)
|
25
|
+
@base = base
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_unhandled(name, event)
|
29
|
+
event.dispatch(@base) unless self.override?(event)
|
30
|
+
end
|
31
|
+
|
32
|
+
def override?(event)
|
33
|
+
conn = event.connection
|
34
|
+
if !conn.nil? && conn.overrides?
|
35
|
+
overrides = conn.overrides
|
36
|
+
result = event.dispatch(overrides)
|
37
|
+
return result
|
38
|
+
end
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#--
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
4
|
+
# distributed with this work for additional information
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
7
|
+
# "License"); you may not use this file except in compliance
|
8
|
+
# with the License. You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
13
|
+
# software distributed under the License is distributed on an
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
+
# KIND, either express or implied. See the License for the
|
16
|
+
# specific language governing permissions and limitations
|
17
|
+
# under the License.
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Qpid::Proton::Reactor
|
21
|
+
|
22
|
+
class LinkOption
|
23
|
+
def apply(link)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Subclasses should override this to selectively apply an option.
|
27
|
+
def test(link)
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class AtMostOne < LinkOption
|
33
|
+
def apply(link)
|
34
|
+
link.snd_settle_mod = Link::SND_SETTLED
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class AtLeastOnce < LinkOption
|
39
|
+
def apply(link)
|
40
|
+
link.snd_settle_mode = Link::SND_UNSETTLED
|
41
|
+
link.rcv_settle_mode = Link::RCV_FIRST
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class SenderOption < LinkOption
|
46
|
+
def test(link)
|
47
|
+
link.sender?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class ReceiverOption < LinkOption
|
52
|
+
def test(link)
|
53
|
+
link.receiver?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class DynamicNodeProperties < LinkOption
|
58
|
+
def initialize(properties = {})
|
59
|
+
@properties = []
|
60
|
+
properties.each do |property|
|
61
|
+
@properties << property.to_sym
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def apply(link)
|
66
|
+
if link.receiver?
|
67
|
+
link.source.properties.dict = @properties
|
68
|
+
else
|
69
|
+
link.target.properties.dict = @properties
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Filter < ReceiverOption
|
75
|
+
def initialize(filter_set = {})
|
76
|
+
@filter_set = filter_set
|
77
|
+
end
|
78
|
+
|
79
|
+
def apply(receiver)
|
80
|
+
receiver.source.filter.dict = @filter_set
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
#class Selector < Filter
|
85
|
+
# def initialize(value, name = 'selector')
|
86
|
+
#
|
87
|
+
# end
|
88
|
+
#end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
#--
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
4
|
+
# distributed with this work for additional information
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
7
|
+
# "License"); you may not use this file except in compliance
|
8
|
+
# with the License. You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
13
|
+
# software distributed under the License is distributed on an
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
+
# KIND, either express or implied. See the License for the
|
16
|
+
# specific language governing permissions and limitations
|
17
|
+
# under the License.
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Qpid::Proton::Reactor
|
21
|
+
|
22
|
+
class Reactor
|
23
|
+
|
24
|
+
include Qpid::Proton::Util::Handler
|
25
|
+
|
26
|
+
# @private
|
27
|
+
include Qpid::Proton::Util::SwigHelper
|
28
|
+
|
29
|
+
# @private
|
30
|
+
PROTON_METHOD_PREFIX = "pn_reactor"
|
31
|
+
|
32
|
+
proton_caller :yield
|
33
|
+
|
34
|
+
proton_caller :mark
|
35
|
+
|
36
|
+
proton_caller :start
|
37
|
+
|
38
|
+
proton_caller :stop
|
39
|
+
|
40
|
+
# @private
|
41
|
+
include Qpid::Proton::Util::Timeout
|
42
|
+
|
43
|
+
include Qpid::Proton::Util::Wrapper
|
44
|
+
|
45
|
+
attr_reader :errors
|
46
|
+
|
47
|
+
def self.wrap(impl)
|
48
|
+
return nil if impl.nil?
|
49
|
+
|
50
|
+
self.fetch_instance(impl, :pn_reactor_attachments) || Reactor.new(nil, :impl => impl)
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(handlers, options = {})
|
54
|
+
@impl = options[:impl]
|
55
|
+
if @impl.nil?
|
56
|
+
@impl = Cproton.pn_reactor
|
57
|
+
end
|
58
|
+
if !handlers.nil?
|
59
|
+
[handlers].flatten.each {|handler| self.handler.add(handler)}
|
60
|
+
end
|
61
|
+
@errors = []
|
62
|
+
@handlers = []
|
63
|
+
self.class.store_instance(self, :pn_reactor_attachments)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns whether the reactor has any unbuffered data.
|
67
|
+
#
|
68
|
+
# @return [Boolean] True if there is no unbuffered data.
|
69
|
+
#
|
70
|
+
def quiesced?
|
71
|
+
Cproton.pn_reactor_quiesced(@impl)
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_error(info)
|
75
|
+
self.errors << info
|
76
|
+
self.yield
|
77
|
+
end
|
78
|
+
|
79
|
+
def global_handler
|
80
|
+
impl = Cproton.pn_reactor_get_global_handler(@impl)
|
81
|
+
Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
|
82
|
+
end
|
83
|
+
|
84
|
+
def global_handler=(handler)
|
85
|
+
impl = chandler(handler, self.method(:on_error))
|
86
|
+
Cproton.pn_reactor_set_global_handler(@impl, impl)
|
87
|
+
Cproton.pn_decref(impl)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the timeout period.
|
91
|
+
#
|
92
|
+
# @return [Fixnum] The timeout period, in seconds.
|
93
|
+
#
|
94
|
+
def timeout
|
95
|
+
millis_to_timeout(Cproton.pn_reactor_get_timeout(@impl))
|
96
|
+
end
|
97
|
+
|
98
|
+
# Sets the timeout period.
|
99
|
+
#
|
100
|
+
# @param timeout [Fixnum] The timeout, in seconds.
|
101
|
+
#
|
102
|
+
def timeout=(timeout)
|
103
|
+
Cproton.pn_reactor_set_timeout(@impl, timeout_to_millis(timeout))
|
104
|
+
end
|
105
|
+
|
106
|
+
def handler
|
107
|
+
impl = Cproton.pn_reactor_get_handler(@impl)
|
108
|
+
Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
|
109
|
+
end
|
110
|
+
|
111
|
+
def handler=(handler)
|
112
|
+
impl = chandler(handler, set.method(:on_error))
|
113
|
+
Cproton.pn_reactor_set_handler(@impl, impl)
|
114
|
+
Cproton.pn_decref(impl)
|
115
|
+
end
|
116
|
+
|
117
|
+
def run(&block)
|
118
|
+
self.timeout = 3.14159265359
|
119
|
+
self.start
|
120
|
+
while self.process do
|
121
|
+
if block_given?
|
122
|
+
yield
|
123
|
+
end
|
124
|
+
end
|
125
|
+
self.stop
|
126
|
+
end
|
127
|
+
|
128
|
+
def wakeup
|
129
|
+
n = Cproton.pn_reactor_wakeup(@impl)
|
130
|
+
unless n.zero?
|
131
|
+
io = Cproton.pn_reactor_io(@impl)
|
132
|
+
raise IOError.new(Cproton.pn_io_error(io))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def process
|
137
|
+
result = Cproton.pn_reactor_process(@impl)
|
138
|
+
if !self.errors.nil? && !self.errors.empty?
|
139
|
+
(0...self.errors.size).each do |index|
|
140
|
+
error_set = self.errors[index]
|
141
|
+
print error.backtrace.join("\n")
|
142
|
+
end
|
143
|
+
raise self.errors.last
|
144
|
+
end
|
145
|
+
return result
|
146
|
+
end
|
147
|
+
|
148
|
+
def schedule(delay, task)
|
149
|
+
impl = chandler(task, self.method(:on_error))
|
150
|
+
task = Task.wrap(Cproton.pn_reactor_schedule(@impl, sec_to_millis(delay), impl))
|
151
|
+
Cproton.pn_decref(impl)
|
152
|
+
return task
|
153
|
+
end
|
154
|
+
|
155
|
+
def acceptor(host, port, handler = nil)
|
156
|
+
impl = chandler(handler, self.method(:on_error))
|
157
|
+
aimpl = Cproton.pn_reactor_acceptor(@impl, host, "#{port}", impl)
|
158
|
+
Cproton.pn_decref(impl)
|
159
|
+
if !aimpl.nil?
|
160
|
+
return Acceptor.new(aimpl)
|
161
|
+
else
|
162
|
+
io = Cproton.pn_reactor_io(@impl)
|
163
|
+
io_error = Cproton.pn_io_error(io)
|
164
|
+
error_text = Cproton.pn_error_text(io_error)
|
165
|
+
text = "(#{Cproton.pn_error_text(io_error)} (#{host}:#{port}))"
|
166
|
+
raise IOError.new(text)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def connection(handler = nil)
|
171
|
+
impl = chandler(handler, self.method(:on_error))
|
172
|
+
conn = Qpid::Proton::Connection.wrap(Cproton.pn_reactor_connection(@impl, impl))
|
173
|
+
Cproton.pn_decref(impl)
|
174
|
+
return conn
|
175
|
+
end
|
176
|
+
|
177
|
+
def selectable(handler = nil)
|
178
|
+
impl = chandler(handler, self.method(:on_error))
|
179
|
+
result = Selectable.wrap(Cproton.pn_reactor_selectable(@impl))
|
180
|
+
if !impl.nil?
|
181
|
+
record = Cproton.pn_selectable_attachments(result.impl)
|
182
|
+
Cproton.pn_record_set_handler(record, impl)
|
183
|
+
Cproton.pn_decref(impl)
|
184
|
+
end
|
185
|
+
return result
|
186
|
+
end
|
187
|
+
|
188
|
+
def update(sel)
|
189
|
+
Cproton.pn_reactor_update(@impl, sel.impl)
|
190
|
+
end
|
191
|
+
|
192
|
+
def push_event(obj, etype)
|
193
|
+
Cproton.pn_collector_put(Cproton.pn_reactor_collector(@impl), Qpid::Proton::Util::RBCTX, Cproton.pn_py2void(obj), etype.number)
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|