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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codec/data.rb +912 -0
  3. data/lib/codec/mapping.rb +169 -0
  4. data/lib/{qpid_proton/tracker.rb → core/base_handler.rb} +4 -15
  5. data/lib/core/connection.rb +328 -0
  6. data/lib/core/delivery.rb +271 -0
  7. data/lib/core/disposition.rb +158 -0
  8. data/lib/core/endpoint.rb +140 -0
  9. data/lib/{qpid_proton → core}/exceptions.rb +43 -2
  10. data/lib/core/link.rb +387 -0
  11. data/lib/core/message.rb +633 -0
  12. data/lib/core/receiver.rb +95 -0
  13. data/lib/core/sasl.rb +94 -0
  14. data/lib/core/selectable.rb +130 -0
  15. data/lib/core/sender.rb +76 -0
  16. data/lib/core/session.rb +163 -0
  17. data/lib/core/ssl.rb +164 -0
  18. data/lib/{qpid_proton/version.rb → core/ssl_details.rb} +7 -6
  19. data/lib/core/ssl_domain.rb +156 -0
  20. data/lib/core/terminus.rb +218 -0
  21. data/lib/core/transport.rb +411 -0
  22. data/lib/core/url.rb +77 -0
  23. data/lib/event/collector.rb +148 -0
  24. data/lib/event/event.rb +318 -0
  25. data/lib/event/event_base.rb +91 -0
  26. data/lib/event/event_type.rb +71 -0
  27. data/lib/handler/acking.rb +70 -0
  28. data/lib/handler/c_adaptor.rb +47 -0
  29. data/lib/handler/c_flow_controller.rb +33 -0
  30. data/lib/handler/endpoint_state_handler.rb +217 -0
  31. data/lib/handler/incoming_message_handler.rb +74 -0
  32. data/lib/handler/messaging_handler.rb +218 -0
  33. data/lib/handler/outgoing_message_handler.rb +98 -0
  34. data/lib/handler/wrapped_handler.rb +76 -0
  35. data/lib/messenger/messenger.rb +702 -0
  36. data/lib/messenger/subscription.rb +37 -0
  37. data/lib/messenger/tracker.rb +38 -0
  38. data/lib/messenger/tracker_status.rb +69 -0
  39. data/lib/qpid_proton.rb +106 -16
  40. data/lib/reactor/acceptor.rb +41 -0
  41. data/lib/reactor/backoff.rb +41 -0
  42. data/lib/reactor/connector.rb +98 -0
  43. data/lib/reactor/container.rb +272 -0
  44. data/lib/reactor/global_overrides.rb +44 -0
  45. data/lib/reactor/link_option.rb +90 -0
  46. data/lib/reactor/reactor.rb +198 -0
  47. data/lib/reactor/session_per_connection.rb +45 -0
  48. data/lib/reactor/ssl_config.rb +41 -0
  49. data/lib/reactor/task.rb +39 -0
  50. data/lib/{qpid_proton/subscription.rb → reactor/urls.rb} +12 -13
  51. data/lib/{qpid_proton → types}/array.rb +28 -29
  52. data/lib/types/described.rb +63 -0
  53. data/lib/{qpid_proton → types}/hash.rb +4 -3
  54. data/lib/types/strings.rb +62 -0
  55. data/lib/util/class_wrapper.rb +54 -0
  56. data/lib/util/condition.rb +45 -0
  57. data/lib/util/constants.rb +85 -0
  58. data/lib/util/engine.rb +82 -0
  59. data/lib/util/error_handler.rb +127 -0
  60. data/lib/util/handler.rb +41 -0
  61. data/lib/util/reactor.rb +32 -0
  62. data/lib/util/swig_helper.rb +114 -0
  63. data/lib/util/timeout.rb +50 -0
  64. data/lib/util/uuid.rb +32 -0
  65. data/lib/util/version.rb +30 -0
  66. data/lib/util/wrapper.rb +124 -0
  67. metadata +67 -21
  68. data/ext/cproton/cproton.c +0 -22196
  69. data/lib/qpid_proton/data.rb +0 -788
  70. data/lib/qpid_proton/described.rb +0 -66
  71. data/lib/qpid_proton/exception_handling.rb +0 -127
  72. data/lib/qpid_proton/filters.rb +0 -67
  73. data/lib/qpid_proton/mapping.rb +0 -170
  74. data/lib/qpid_proton/message.rb +0 -621
  75. data/lib/qpid_proton/messenger.rb +0 -702
  76. data/lib/qpid_proton/selectable.rb +0 -126
  77. data/lib/qpid_proton/strings.rb +0 -65
  78. 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