qpid_proton 0.21.0 → 0.22.0
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/examples/README.md +26 -10
- data/examples/broker.rb +99 -91
- data/examples/example_test.rb +11 -11
- data/ext/cproton/cproton.c +3 -3
- data/lib/core/connection.rb +18 -12
- data/lib/core/connection_driver.rb +13 -3
- data/lib/core/container.rb +276 -120
- data/lib/core/disposition.rb +1 -1
- data/lib/core/endpoint.rb +3 -0
- data/lib/core/listener.rb +6 -0
- data/lib/core/message.rb +5 -9
- data/lib/core/messaging_handler.rb +5 -1
- data/lib/core/receiver.rb +1 -2
- data/lib/core/sasl.rb +1 -1
- data/lib/core/session.rb +6 -4
- data/lib/core/terminus.rb +10 -4
- data/lib/core/transfer.rb +3 -0
- data/lib/core/transport.rb +1 -0
- data/lib/core/uri.rb +9 -10
- data/lib/core/work_queue.rb +76 -0
- data/lib/qpid_proton.rb +2 -8
- data/lib/types/array.rb +1 -0
- data/lib/types/hash.rb +0 -11
- data/lib/util/schedule.rb +79 -0
- data/lib/util/wrapper.rb +4 -0
- data/tests/old_examples/old_example_test.rb +0 -8
- data/tests/test_container.rb +203 -126
- data/tests/test_container_sasl.rb +141 -0
- data/tests/test_interop.rb +1 -1
- data/tests/test_messaging_adapter.rb +1 -1
- data/tests/test_tools.rb +30 -5
- data/tests/test_uri.rb +2 -0
- metadata +5 -9
- data/lib/messenger/messenger.rb +0 -703
- data/lib/messenger/subscription.rb +0 -36
- data/lib/messenger/tracker.rb +0 -37
- data/lib/messenger/tracker_status.rb +0 -68
- data/lib/util/timeout.rb +0 -49
- data/tests/old_examples/recv.rb +0 -23
- data/tests/old_examples/send.rb +0 -21
data/lib/core/transport.rb
CHANGED
data/lib/core/uri.rb
CHANGED
@@ -43,19 +43,16 @@ module Qpid::Proton
|
|
43
43
|
|
44
44
|
public
|
45
45
|
|
46
|
-
# Convert +s+ to
|
46
|
+
# Convert +s+ to an amqp: or amqps: URI
|
47
47
|
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# @note this does not give the same result as a standard URI parser in all cases.
|
52
|
-
# For standard conversion to a URI use: {#URI}(s)
|
48
|
+
# This does not give the same result as the standard URI parser in all cases.
|
49
|
+
# Short-cut strings like "host:port" are allowed, an "amqp://" prefix is added if +s+ does
|
50
|
+
# not already look like an 'amqp:' or 'amqps:' URI.
|
53
51
|
#
|
54
52
|
# @param s [String,URI] String to convert to a URI, or a URI object.
|
55
|
-
#
|
56
|
-
# @
|
57
|
-
# @raise [
|
58
|
-
# @raise [InvalidURIError] s cannot be parsed as a URI or shortcut
|
53
|
+
# @return [URI] A valid AMQP or AMQPS URI
|
54
|
+
# @raise [URI::BadURIError] s is a URI object with a non-AMQP scheme
|
55
|
+
# @raise [URI::InvalidURIError] s cannot be parsed as a URI or shortcut
|
59
56
|
# @raise [::ArgumentError] s is not a string or URI
|
60
57
|
#
|
61
58
|
def self.uri(s)
|
@@ -75,5 +72,7 @@ module Qpid::Proton
|
|
75
72
|
else DEFAULT_URI_PARSER.parse("amqp://#{s}") # Treat as a bare host:port/path string
|
76
73
|
end
|
77
74
|
end
|
75
|
+
rescue =>e
|
76
|
+
raise e.class, "#{self}.#{__method__}(#{s.inspect}): #{e}"
|
78
77
|
end
|
79
78
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
module Qpid::Proton
|
19
|
+
|
20
|
+
# A thread-safe queue of work for multi-threaded programs.
|
21
|
+
#
|
22
|
+
# Instances of {Connection} and objects associated with it ({Session}, {Sender},
|
23
|
+
# {Receiver}, {Delivery}, {Tracker}) are not thread-safe and must be
|
24
|
+
# used correctly when multiple threads call {Container#run}
|
25
|
+
#
|
26
|
+
# Calls to {MessagingHandler} methods by the {Container} are automatically
|
27
|
+
# serialized for each connection instance. Other threads may have code
|
28
|
+
# similarly serialized by adding it to the {Connection#work_queue} for the
|
29
|
+
# connection. Each object related to a {Connection} also provides a
|
30
|
+
# +work_queue+ method.
|
31
|
+
#
|
32
|
+
class WorkQueue
|
33
|
+
|
34
|
+
# Add code to be executed in series with other {Container} operations on the
|
35
|
+
# work queue's owner. The code will be executed as soon as possible.
|
36
|
+
#
|
37
|
+
# @note Thread Safe: may be called in any thread.
|
38
|
+
# @param non_block [Boolean] if true raise {ThreadError} if the operation would block.
|
39
|
+
# @yield [ ] the block will be invoked with no parameters in the {WorkQueue} context,
|
40
|
+
# which may be a different thread.
|
41
|
+
# @return [void]
|
42
|
+
# @raise [ThreadError] if +non_block+ is true and the operation would block
|
43
|
+
# @raise [EOFError] if the queue is closed and cannot accept more work
|
44
|
+
def add(non_block=false, &block)
|
45
|
+
@schedule.add(Time.at(0), non_block, &block)
|
46
|
+
@container.send :wake
|
47
|
+
end
|
48
|
+
|
49
|
+
# Schedule code to be executed after +delay+ seconds in series with other
|
50
|
+
# {Container} operations on the work queue's owner.
|
51
|
+
#
|
52
|
+
# Work scheduled for after the {WorkQueue} has closed will be silently dropped.
|
53
|
+
#
|
54
|
+
# @note (see #add)
|
55
|
+
# @param delay delay in seconds until the block is added to the queue.
|
56
|
+
# @param (see #add)
|
57
|
+
# @yield (see #add)
|
58
|
+
# @return [void]
|
59
|
+
# @raise (see #add)
|
60
|
+
def schedule(delay, non_block=false, &block)
|
61
|
+
@schedule.add(Time.now + delay, non_block, &block)
|
62
|
+
@container.send :wake
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def initialize(container)
|
68
|
+
@schedule = Schedule.new
|
69
|
+
@container = container
|
70
|
+
end
|
71
|
+
|
72
|
+
def close() @schedule.close; end
|
73
|
+
def process(now) @schedule.process(now); end
|
74
|
+
def next_tick() @schedule.next_tick; end
|
75
|
+
end
|
76
|
+
end
|
data/lib/qpid_proton.rb
CHANGED
@@ -26,6 +26,7 @@ rescue LoadError
|
|
26
26
|
require "kconv" # Ruby < 1.9
|
27
27
|
end
|
28
28
|
|
29
|
+
# @api qpid
|
29
30
|
# Qpid is the top level module for the Qpid project http://qpid.apache.org
|
30
31
|
# Definitions for this library are in module {Qpid::Proton}
|
31
32
|
module Qpid
|
@@ -43,8 +44,8 @@ require "core/exceptions"
|
|
43
44
|
require "util/deprecation"
|
44
45
|
require "util/version"
|
45
46
|
require "util/error_handler"
|
47
|
+
require "util/schedule"
|
46
48
|
require "util/wrapper"
|
47
|
-
require "util/timeout"
|
48
49
|
|
49
50
|
# Types
|
50
51
|
require "types/type"
|
@@ -93,10 +94,3 @@ require "core/container"
|
|
93
94
|
require "handler/reactor_messaging_adapter"
|
94
95
|
require "handler/messaging_handler" # Keep original name for compatibility
|
95
96
|
require "reactor/container"
|
96
|
-
|
97
|
-
# DEPRECATED Messenger API classes
|
98
|
-
require "messenger/subscription"
|
99
|
-
require "messenger/tracker_status"
|
100
|
-
require "messenger/tracker"
|
101
|
-
require "messenger/messenger"
|
102
|
-
|
data/lib/types/array.rb
CHANGED
@@ -49,6 +49,7 @@ module Qpid::Proton
|
|
49
49
|
# @param descriptor [Object] Optional array descriptor
|
50
50
|
def initialize(type, elements=nil, descriptor=nil)
|
51
51
|
@type, @descriptor = type, descriptor
|
52
|
+
@proton_array_header = nil
|
52
53
|
raise ArgumentError, "no type specified for array" if @type.nil?
|
53
54
|
super elements if elements
|
54
55
|
end
|
data/lib/types/hash.rb
CHANGED
@@ -37,14 +37,3 @@ class Hash # :nodoc:
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
module Qpid::Proton::Types
|
41
|
-
# @private
|
42
|
-
def self.symbol_keys(h)
|
43
|
-
h && h.reduce({}) { |x, (k, v)| x[k.to_sym] = v; x }
|
44
|
-
end
|
45
|
-
|
46
|
-
# @private
|
47
|
-
def self.symbol_array(a)
|
48
|
-
a && UniformArray.new(SYMBOL, a.collect { |v| v.to_sym })
|
49
|
-
end
|
50
|
-
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
module Qpid::Proton
|
19
|
+
|
20
|
+
# @private
|
21
|
+
module TimeCompare
|
22
|
+
# t1 <= t2, where nil is treated as "distant future"
|
23
|
+
def before_eq(t1, t2) (t1 && t2) ? (t1 <= t2) : t1; end
|
24
|
+
|
25
|
+
# min(t1, t2) where nil is treated as "distant future"
|
26
|
+
def earliest(t1, t2) before_eq(t1, t2) ? t1 : t2; end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @private
|
30
|
+
# A sorted, thread-safe list of scheduled Proc.
|
31
|
+
# Note: calls to #process are always serialized, but calls to #add may be concurrent.
|
32
|
+
class Schedule
|
33
|
+
include TimeCompare
|
34
|
+
Item = Struct.new(:time, :proc)
|
35
|
+
|
36
|
+
def initialize()
|
37
|
+
@lock = Mutex.new
|
38
|
+
@items = []
|
39
|
+
@closed = false
|
40
|
+
end
|
41
|
+
|
42
|
+
def next_tick()
|
43
|
+
@lock.synchronize { @items.first.time unless @items.empty? }
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return true if the Schedule was previously empty
|
47
|
+
# @raise EOFError if schedule is closed
|
48
|
+
# @raise ThreadError if +non_block+ and operation would block
|
49
|
+
def add(time, non_block=false, &proc)
|
50
|
+
# non_block ignored for now, but we may implement a bounded schedule in future.
|
51
|
+
@lock.synchronize do
|
52
|
+
raise EOFError if @closed
|
53
|
+
if at = (0...@items.size).bsearch { |i| @items[i].time > time }
|
54
|
+
@items.insert(at, Item.new(time, proc))
|
55
|
+
else
|
56
|
+
@items << Item.new(time, proc)
|
57
|
+
end
|
58
|
+
return @items.size == 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return true if the Schedule became empty as a result of this call
|
63
|
+
def process(now)
|
64
|
+
due = []
|
65
|
+
empty = @lock.synchronize do
|
66
|
+
due << @items.shift while (!@items.empty? && before_eq(@items.first.time, now))
|
67
|
+
@items.empty?
|
68
|
+
end
|
69
|
+
due.each { |i| i.proc.call() }
|
70
|
+
return empty && !due.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
# #add raises EOFError after #close.
|
74
|
+
# #process can still be called to drain the schedule.
|
75
|
+
def close()
|
76
|
+
@lock.synchronize { @closed = true }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/util/wrapper.rb
CHANGED
@@ -115,6 +115,10 @@ module Qpid::Proton
|
|
115
115
|
end
|
116
116
|
|
117
117
|
# @private
|
118
|
+
#
|
119
|
+
# Instance methods to include in classes that wrap pn_object types
|
120
|
+
# that support pn_inspect etc. Automatically extends SWIGClassHelper
|
121
|
+
#
|
118
122
|
module Wrapper
|
119
123
|
|
120
124
|
def self.included(base)
|
@@ -52,14 +52,6 @@ class OldExampleTest < MiniTest::Test
|
|
52
52
|
assert_output want, ["simple_recv.rb", "-a", make_url($port, __method__)]
|
53
53
|
end
|
54
54
|
|
55
|
-
def test_smoke
|
56
|
-
url = "127.0.0.1:#{unused_port}"
|
57
|
-
recv = run_script("recv.rb", "~#{url}")
|
58
|
-
recv.readline # Wait for "Listening"
|
59
|
-
assert_output("Status: ACCEPTED", ["send.rb", url])
|
60
|
-
assert_equal "Got: Hello World!", recv.read.strip
|
61
|
-
end
|
62
|
-
|
63
55
|
def test_client_server
|
64
56
|
want = <<EOS
|
65
57
|
-> Twas brillig, and the slithy toves
|