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,702 @@
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::Messenger
21
+
22
+ # The +Messenger+ class defines a high level interface for
23
+ # sending and receiving Messages. Every Messenger contains
24
+ # a single logical queue of incoming messages and a single
25
+ # logical queue of outgoing messages. These messages in these
26
+ # queues may be destined for, or originate from, a variety of
27
+ # addresses.
28
+ #
29
+ # The messenger interface is single-threaded. All methods
30
+ # except one ( #interrupt ) are intended to be used from within
31
+ # the messenger thread.
32
+ #
33
+ # === Sending & Receiving Messages
34
+ #
35
+ # The Messenger class works in conjuction with the Message class. The
36
+ # Message class is a mutable holder of message content.
37
+ #
38
+ # The put method copies its Message to the outgoing queue, and may
39
+ # send queued messages if it can do so without blocking. The send
40
+ # method blocks until it has sent the requested number of messages,
41
+ # or until a timeout interrupts the attempt.
42
+ #
43
+ # Similarly, the recv method receives messages into the incoming
44
+ # queue, and may block as it attempts to receive the requested number
45
+ # of messages, or until timeout is reached. It may receive fewer
46
+ # than the requested number. The get method pops the
47
+ # eldest Message off the incoming queue and copies it into the Message
48
+ # object that you supply. It will not block.
49
+ #
50
+ # The blocking attribute allows you to turn off blocking behavior entirely,
51
+ # in which case send and recv will do whatever they can without
52
+ # blocking, and then return. You can then look at the number
53
+ # of incoming and outgoing messages to see how much outstanding work
54
+ # still remains.
55
+ #
56
+ class Messenger
57
+
58
+ include Qpid::Proton::Util::ErrorHandler
59
+
60
+ can_raise_error [:send, :receive, :password=, :start, :stop,
61
+ :perform_put, :perform_get, :interrupt,
62
+ :route, :rewrite, :accept, :reject,
63
+ :incoming_window=, :outgoing_window=]
64
+
65
+ # Creates a new +Messenger+.
66
+ #
67
+ # The +name+ parameter is optional. If one is not provided then
68
+ # a unique name is generated.
69
+ #
70
+ # ==== Options
71
+ #
72
+ # * name - the name (def. nil)
73
+ #
74
+ def initialize(name = nil)
75
+ @impl = Cproton.pn_messenger(name)
76
+ @selectables = {}
77
+ ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
78
+ end
79
+
80
+ def self.finalize!(impl) # :nodoc:
81
+ proc {
82
+ Cproton.pn_messenger_free(impl)
83
+ }
84
+ end
85
+
86
+ # Returns the name.
87
+ #
88
+ def name
89
+ Cproton.pn_messenger_name(@impl)
90
+ end
91
+
92
+ # This property contains the password for the Messenger.private_key
93
+ # file, or +nil+ if the file is not encrypted.
94
+ #
95
+ # ==== Arguments
96
+ #
97
+ # * password - the password
98
+ #
99
+ def password=(password)
100
+ Cproton.pn_messenger_set_password(@impl, password)
101
+ end
102
+
103
+ # Returns the password property for the Messenger.private_key file.
104
+ #
105
+ def password
106
+ Cproton.pn_messenger_get_password(@impl)
107
+ end
108
+
109
+ # Sets the timeout period, in milliseconds.
110
+ #
111
+ # A negative timeout period implies an infinite timeout.
112
+ #
113
+ # ==== Options
114
+ #
115
+ # * timeout - the timeout period
116
+ #
117
+ def timeout=(timeout)
118
+ raise TypeError.new("invalid timeout: #{timeout}") if timeout.nil?
119
+ Cproton.pn_messenger_set_timeout(@impl, timeout)
120
+ end
121
+
122
+ # Returns the timeout period
123
+ #
124
+ def timeout
125
+ Cproton.pn_messenger_get_timeout(@impl)
126
+ end
127
+
128
+ # Returns true if blocking mode is enabled.
129
+ #
130
+ # Enable or disable blocking behavior during message sending
131
+ # and receiving. This affects every blocking call, with the
132
+ # exception of work(). Currently, the affected calls are
133
+ # send, recv, and stop.
134
+ def blocking?
135
+ Cproton.pn_messenger_is_blocking(@impl)
136
+ end
137
+
138
+ # Sets the blocking mode.
139
+ def blocking=(blocking)
140
+ Cproton.pn_messenger_set_blocking(@impl, blocking)
141
+ end
142
+
143
+ # Returns true if passive mode is enabled.
144
+ #
145
+ def passive?
146
+ Cproton.pn_messenger_is_passive(@impl)
147
+ end
148
+
149
+ # Turns passive mode on or off.
150
+ #
151
+ # When set to passive mode, Messenger will not attempt to perform I/O
152
+ # operations internally. In this mode it is necesssary to use the
153
+ # Selectable type to drive any I/O needed to perform requestioned
154
+ # actions.
155
+ #
156
+ # In this mode Messenger will never block.
157
+ #
158
+ def passive=(mode)
159
+ Cproton.pn_messenger_set_passive(@impl, mode)
160
+ end
161
+
162
+ def deadline
163
+ tstamp = Cproton.pn_messenger_deadline(@impl)
164
+ return tstamp / 1000.0 unless tstamp.nil?
165
+ end
166
+
167
+ # Reports whether an error occurred.
168
+ #
169
+ def error?
170
+ !Cproton.pn_messenger_errno(@impl).zero?
171
+ end
172
+
173
+ # Returns the most recent error number.
174
+ #
175
+ def errno
176
+ Cproton.pn_messenger_errno(@impl)
177
+ end
178
+
179
+ # Returns the most recent error message.
180
+ #
181
+ def error
182
+ Cproton.pn_error_text(Cproton.pn_messenger_error(@impl))
183
+ end
184
+
185
+ # Clears the current error state.
186
+ #
187
+ def clear_error
188
+ error = Cproton.pn_messenger_error(@impl)
189
+ unless error.nil?
190
+ Cproton.pn_error_clear(error)
191
+ end
192
+ end
193
+
194
+ # Currently a no-op placeholder.
195
+ # For future compatibility, do not send or recv messages
196
+ # before starting the +Messenger+.
197
+ #
198
+ def start
199
+ Cproton.pn_messenger_start(@impl)
200
+ end
201
+
202
+ # Stops the +Messenger+, preventing it from sending or receiving
203
+ # any more messages.
204
+ #
205
+ def stop
206
+ Cproton.pn_messenger_stop(@impl)
207
+ end
208
+
209
+ # Returns true if a Messenger is in the stopped state.
210
+ # This function does not block.
211
+ #
212
+ def stopped?
213
+ Cproton.pn_messenger_stopped(@impl)
214
+ end
215
+
216
+ # Subscribes the Messenger to messages originating from the
217
+ # specified source. The source is an address as specified in the
218
+ # Messenger introduction with the following addition. If the
219
+ # domain portion of the address begins with the '~' character, the
220
+ # Messenger will interpret the domain as host/port, bind to it,
221
+ # and listen for incoming messages. For example "~0.0.0.0",
222
+ # "amqp://~0.0.0.0" will all bind to any local interface and
223
+ # listen for incoming messages. An address of "amqps://~0.0.0.0"
224
+ # will only permit incoming SSL connections.
225
+ #
226
+ # ==== Options
227
+ #
228
+ # * address - the source address to be subscribe
229
+ # * timeout - an optional time-to-live value, in seconds, for the
230
+ # subscription
231
+ #
232
+ def subscribe(address, timeout=0)
233
+ raise TypeError.new("invalid address: #{address}") if address.nil?
234
+ subscription = Cproton.pn_messenger_subscribe_ttl(@impl, address, timeout)
235
+ raise Qpid::Proton::ProtonError.new("Subscribe failed") if subscription.nil?
236
+ Subscription.new(subscription)
237
+ end
238
+
239
+ # Path to a certificate file for the +Messenger+.
240
+ #
241
+ # This certificate is used when the +Messenger+ accepts or establishes
242
+ # SSL/TLS connections. This property must be specified for the
243
+ # Messenger to accept incoming SSL/TLS connections and to establish
244
+ # client authenticated outgoing SSL/TLS connection. Non client authenticated
245
+ # outgoing SSL/TLS connections do not require this property.
246
+ #
247
+ # ==== Options
248
+ #
249
+ # * certificate - the certificate
250
+ #
251
+ def certificate=(certificate)
252
+ Cproton.pn_messenger_set_certificate(@impl, certificate)
253
+ end
254
+
255
+ # Returns the path to a certificate file.
256
+ #
257
+ def certificate
258
+ Cproton.pn_messenger_get_certificate(@impl)
259
+ end
260
+
261
+ # Path to a private key file for the +Messenger+.
262
+ #
263
+ # The property must be specified for the +Messenger+ to accept incoming
264
+ # SSL/TLS connections and to establish client authenticated outgoing
265
+ # SSL/TLS connections. Non client authenticated SSL/TLS connections
266
+ # do not require this property.
267
+ #
268
+ # ==== Options
269
+ #
270
+ # * key - the key file
271
+ #
272
+ def private_key=(key)
273
+ Cproton.pn_messenger_set_private_key(@impl, key)
274
+ end
275
+
276
+ # Returns the path to a private key file.
277
+ #
278
+ def private_key
279
+ Cproton.pn_messenger_get_private_key(@impl)
280
+ end
281
+
282
+ # A path to a database of trusted certificates for use in verifying the
283
+ # peer on an SSL/TLS connection. If this property is +nil+, then the
284
+ # peer will not be verified.
285
+ #
286
+ # ==== Options
287
+ #
288
+ # * certificates - the certificates path
289
+ #
290
+ def trusted_certificates=(certificates)
291
+ Cproton.pn_messenger_set_trusted_certificates(@impl,certificates)
292
+ end
293
+
294
+ # The path to the databse of trusted certificates.
295
+ #
296
+ def trusted_certificates
297
+ Cproton.pn_messenger_get_trusted_certificates(@impl)
298
+ end
299
+
300
+ # Places the content contained in the message onto the outgoing
301
+ # queue of the Messenger.
302
+ #
303
+ # This method will never block, however it will send any unblocked
304
+ # Messages in the outgoing queue immediately and leave any blocked
305
+ # Messages remaining in the outgoing queue.
306
+ # The send call may then be used to block until the outgoing queue
307
+ # is empty. The outgoing attribute may be used to check the depth
308
+ # of the outgoing queue.
309
+ #
310
+ # ==== Options
311
+ #
312
+ # * message - the message
313
+ #
314
+ def put(message)
315
+ if message.nil?
316
+ raise TypeError.new("invalid message: #{message}")
317
+ end
318
+ unless message.kind_of?(Qpid::Proton::Message)
319
+ raise ::ArgumentError.new("invalid message type: #{message.class}")
320
+ end
321
+ # encode the message first
322
+ message.pre_encode
323
+ perform_put(message)
324
+ return outgoing_tracker
325
+ end
326
+
327
+ private
328
+
329
+ def perform_put(message) # :nodoc:
330
+ Cproton.pn_messenger_put(@impl, message.impl)
331
+ end
332
+
333
+ public
334
+
335
+
336
+ # This call will block until the indicated number of messages
337
+ # have been sent, or until the operation times out.
338
+ # If n is -1 this call will block until all outgoing messages
339
+ # have been sent. If n is 0 then this call will send whatever
340
+ # it can without blocking.
341
+ #
342
+ def send(n = -1)
343
+ Cproton.pn_messenger_send(@impl, n)
344
+ end
345
+
346
+ # Moves the message from the head of the incoming message queue into
347
+ # the supplied message object. Any content in the supplied message
348
+ # will be overwritten.
349
+ # A tracker for the incoming Message is returned. The tracker can
350
+ # later be used to communicate your acceptance or rejection of the
351
+ # Message.
352
+ #
353
+ # If no message is provided in the argument, then one is created. In
354
+ # either case, the one returned will be the fetched message.
355
+ #
356
+ # ==== Options
357
+ #
358
+ # * msg - the (optional) +Message+ instance to be used
359
+ #
360
+ def get(msg = nil)
361
+ msg_impl = nil
362
+ if msg.nil? then
363
+ msg_impl = nil
364
+ else
365
+ msg_impl = msg.impl
366
+ end
367
+ perform_get(msg_impl)
368
+ msg.post_decode unless msg.nil?
369
+ return incoming_tracker
370
+ end
371
+
372
+ private
373
+
374
+ def perform_get(msg) # :nodoc:
375
+ Cproton.pn_messenger_get(@impl, msg)
376
+ end
377
+
378
+ public
379
+
380
+ # Receives up to limit messages into the incoming queue. If no value
381
+ # for limit is supplied, this call will receive as many messages as it
382
+ # can buffer internally. If the Messenger is in blocking mode, this
383
+ # call will block until at least one Message is available in the
384
+ # incoming queue.
385
+ #
386
+ # Options ====
387
+ #
388
+ # * limit - the maximum number of messages to receive
389
+ #
390
+ def receive(limit = -1)
391
+ Cproton.pn_messenger_recv(@impl, limit)
392
+ end
393
+
394
+ # Returns true if the messenger is currently receiving data.
395
+ def receiving?
396
+ Cproton.pn_messenger_receiving(@impl)
397
+ end
398
+
399
+ # Attempts interrupting of the messenger thread.
400
+ #
401
+ # The Messenger interface is single-threaded, and this is the only
402
+ # function intended to be called from outside of is thread.
403
+ #
404
+ # Call this from a non-Messenger thread to interrupt it while it
405
+ # is blocking. This will cause a ::InterruptError to be raised.
406
+ #
407
+ # If there is no currently blocking call, then the next blocking
408
+ # call will be affected, even if it is within the same thread that
409
+ # originated the interrupt.
410
+ #
411
+ def interrupt
412
+ Cproton.pn_messenger_interrupt(@impl)
413
+ end
414
+
415
+ # Sends or receives any outstanding messages queued for a Messenger.
416
+ #
417
+ # This will block for the indicated timeout. This method may also do I/O
418
+ # other than sending and receiving messages. For example, closing
419
+ # connections after stop() has been called.
420
+ #
421
+ def work(timeout=-1)
422
+ err = Cproton.pn_messenger_work(@impl, timeout)
423
+ if (err == Cproton::PN_TIMEOUT) then
424
+ return false
425
+ else
426
+ check_for_error(err)
427
+ return true
428
+ end
429
+ end
430
+
431
+ # Returns the number messages in the outgoing queue that have not been
432
+ # transmitted.
433
+ #
434
+ def outgoing
435
+ Cproton.pn_messenger_outgoing(@impl)
436
+ end
437
+
438
+ # Returns the number of messages in the incoming queue that have not
439
+ # been retrieved.
440
+ #
441
+ def incoming
442
+ Cproton.pn_messenger_incoming(@impl)
443
+ end
444
+
445
+ # Adds a routing rule to the Messenger's internal routing table.
446
+ #
447
+ # The route procedure may be used to influence how a Messenger will
448
+ # internally treat a given address or class of addresses. Every call
449
+ # to the route procedure will result in Messenger appending a routing
450
+ # rule to its internal routing table.
451
+ #
452
+ # Whenever a Message is presented to a Messenger for delivery, it
453
+ # will match the address of this message against the set of routing
454
+ # rules in order. The first rule to match will be triggered, and
455
+ # instead of routing based on the address presented in the message,
456
+ # the Messenger will route based on the address supplied in the rule.
457
+ #
458
+ # The pattern matching syntax supports two types of matches, a '%'
459
+ # will match any character except a '/', and a '*' will match any
460
+ # character including a '/'.
461
+ #
462
+ # A routing address is specified as a normal AMQP address, however it
463
+ # may additionally use substitution variables from the pattern match
464
+ # that triggered the rule.
465
+ #
466
+ # ==== Arguments
467
+ #
468
+ # * pattern - the address pattern
469
+ # * address - the target address
470
+ #
471
+ # ==== Examples
472
+ #
473
+ # # route messages sent to foo to the destionaty amqp://foo.com
474
+ # messenger.route("foo", "amqp://foo.com")
475
+ #
476
+ # # any message to foobar will be routed to amqp://foo.com/bar
477
+ # messenger.route("foobar", "amqp://foo.com/bar")
478
+ #
479
+ # # any message to bar/<path> will be routed to the same path within
480
+ # # the amqp://bar.com domain
481
+ # messenger.route("bar/*", "amqp://bar.com/$1")
482
+ #
483
+ # # route all Message objects over TLS
484
+ # messenger.route("amqp:*", "amqps:$1")
485
+ #
486
+ # # supply credentials for foo
487
+ # messenger.route("amqp://foo.com/*", "amqp://user:password@foo.com/$1")
488
+ #
489
+ # # supply credentials for all domains
490
+ # messenger.route("amqp://*", "amqp://user:password@$1")
491
+ #
492
+ # # route all addresses through a single proxy while preserving the
493
+ # # original destination
494
+ # messenger.route("amqp://%$/*", "amqp://user:password@proxy/$1/$2")
495
+ #
496
+ # # route any address through a single broker
497
+ # messenger.route("*", "amqp://user:password@broker/$1")
498
+ #
499
+ def route(pattern, address)
500
+ Cproton.pn_messenger_route(@impl, pattern, address)
501
+ end
502
+
503
+ # Similar to #route, except that the destination of
504
+ # the Message is determined before the message address is rewritten.
505
+ #
506
+ # The outgoing address is only rewritten after routing has been
507
+ # finalized. If a message has an outgoing address of
508
+ # "amqp://0.0.0.0:5678", and a rewriting rule that changes its
509
+ # outgoing address to "foo", it will still arrive at the peer that
510
+ # is listening on "amqp://0.0.0.0:5678", but when it arrives there,
511
+ # the receiver will see its outgoing address as "foo".
512
+ #
513
+ # The default rewrite rule removes username and password from addresses
514
+ # before they are transmitted.
515
+ #
516
+ # ==== Arguments
517
+ #
518
+ # * pattern - the outgoing address
519
+ # * address - the target address
520
+ #
521
+ def rewrite(pattern, address)
522
+ Cproton.pn_messenger_rewrite(@impl, pattern, address)
523
+ end
524
+
525
+ def selectable
526
+ impl = Cproton.pn_messenger_selectable(@impl)
527
+
528
+ # if we don't have any selectables, then return
529
+ return nil if impl.nil?
530
+
531
+ fd = Cproton.pn_selectable_get_fd(impl)
532
+
533
+ selectable = @selectables[fd]
534
+ if selectable.nil?
535
+ selectable = Selectable.new(self, impl)
536
+ @selectables[fd] = selectable
537
+ end
538
+ return selectable
539
+ end
540
+
541
+ # Returns a +Tracker+ for the message most recently sent via the put
542
+ # method.
543
+ #
544
+ def outgoing_tracker
545
+ impl = Cproton.pn_messenger_outgoing_tracker(@impl)
546
+ return nil if impl == -1
547
+ Tracker.new(impl)
548
+ end
549
+
550
+ # Returns a +Tracker+ for the most recently received message.
551
+ #
552
+ def incoming_tracker
553
+ impl = Cproton.pn_messenger_incoming_tracker(@impl)
554
+ return nil if impl == -1
555
+ Tracker.new(impl)
556
+ end
557
+
558
+ # Signal the sender that you have acted on the Message
559
+ # pointed to by the tracker. If no tracker is supplied,
560
+ # then all messages that have been returned by the get
561
+ # method are accepted, except those that have already been
562
+ # auto-settled by passing beyond your incoming window size.
563
+ #
564
+ # ==== Options
565
+ #
566
+ # * tracker - the tracker
567
+ #
568
+ def accept(tracker = nil)
569
+ raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? or valid_tracker?(tracker)
570
+ if tracker.nil? then
571
+ tracker = self.incoming_tracker
572
+ flag = Cproton::PN_CUMULATIVE
573
+ else
574
+ flag = 0
575
+ end
576
+ Cproton.pn_messenger_accept(@impl, tracker.impl, flag)
577
+ end
578
+
579
+ # Rejects the incoming message identified by the tracker.
580
+ # If no tracker is supplied, all messages that have been returned
581
+ # by the get method are rejected, except those that have already
582
+ # been auto-settled by passing beyond your outgoing window size.
583
+ #
584
+ # ==== Options
585
+ #
586
+ # * tracker - the tracker
587
+ #
588
+ def reject(tracker)
589
+ raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? or valid_tracker?(tracker)
590
+ if tracker.nil? then
591
+ tracker = self.incoming_tracker
592
+ flag = Cproton::PN_CUMULATIVE
593
+ else
594
+ flag = 0
595
+ end
596
+ Cproton.pn_messenger_reject(@impl, tracker.impl, flag)
597
+ end
598
+
599
+ # Gets the last known remote state of the delivery associated with
600
+ # the given tracker, as long as the Message is still within your
601
+ # outgoing window. (Also works on incoming messages that are still
602
+ # within your incoming queue. See TrackerStatus for details on the
603
+ # values returned.
604
+ #
605
+ # ==== Options
606
+ #
607
+ # * tracker - the tracker
608
+ #
609
+ def status(tracker)
610
+ raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
611
+ TrackerStatus.by_value(Cproton.pn_messenger_status(@impl, tracker.impl))
612
+ end
613
+
614
+ # Frees a Messenger from tracking the status associated
615
+ # with a given tracker. If you don't supply a tracker, all
616
+ # outgoing messages up to the most recent will be settled.
617
+ #
618
+ # ==== Options
619
+ #
620
+ # * tracker - the tracker
621
+ #
622
+ # ==== Examples
623
+ #
624
+ def settle(tracker)
625
+ raise TypeError.new("invalid tracker: #{tracker}") unless valid_tracker?(tracker)
626
+ if tracker.nil? then
627
+ tracker = self.incoming_tracker
628
+ flag = Cproton::PN_CUMULATIVE
629
+ else
630
+ flag = 0
631
+ end
632
+ Cproton.pn_messenger_settle(@impl, tracker.impl, flag)
633
+ end
634
+
635
+ # Sets the incoming window.
636
+ #
637
+ # The Messenger will track the remote status of this many incoming
638
+ # deliveries after they have been accepted or rejected.
639
+ #
640
+ # Messages enter this window only when you take them into your application
641
+ # using get(). If your incoming window size is n, and you get n+1 messages
642
+ # without explicitly accepting or rejecting the oldest message, then the
643
+ # message that passes beyond the edge of the incoming window will be
644
+ # assigned the default disposition of its link.
645
+ #
646
+ # ==== Options
647
+ #
648
+ # * window - the window size
649
+ #
650
+ def incoming_window=(window)
651
+ raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
652
+ Cproton.pn_messenger_set_incoming_window(@impl, window)
653
+ end
654
+
655
+ # Returns the incoming window.
656
+ #
657
+ def incoming_window
658
+ Cproton.pn_messenger_get_incoming_window(@impl)
659
+ end
660
+
661
+ # Sets the outgoing window.
662
+ #
663
+ # The Messenger will track the remote status of this many outgoing
664
+ # deliveries after calling send.
665
+ # A Message enters this window when you call the put() method with the
666
+ # message. If your outgoing window size is n, and you call put n+1
667
+ # times, status information will no longer be available for the
668
+ # first message.
669
+ #
670
+ # ==== Options
671
+ #
672
+ # * window - the window size
673
+ #
674
+ def outgoing_window=(window)
675
+ raise TypeError.new("invalid window: #{window}") unless valid_window?(window)
676
+ Cproton.pn_messenger_set_outgoing_window(@impl, window)
677
+ end
678
+
679
+ # Returns the outgoing window.
680
+ #
681
+ def outgoing_window
682
+ Cproton.pn_messenger_get_outgoing_window(@impl)
683
+ end
684
+
685
+ # Unregisters a selectable object.
686
+ def unregister_selectable(fileno) # :nodoc:
687
+ @selectables.delete(fileno)
688
+ end
689
+
690
+ private
691
+
692
+ def valid_tracker?(tracker)
693
+ !tracker.nil? && tracker.is_a?(Tracker)
694
+ end
695
+
696
+ def valid_window?(window)
697
+ !window.nil? && [Float, Fixnum].include?(window.class)
698
+ end
699
+
700
+ end
701
+
702
+ end