qpid_proton 0.9.0 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
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