torquebox-messaging 1.1-java → 1.1.1-java

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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  module TorqueboxMessaging
2
- VERSION = '1.1'
3
- MAVEN_VERSION = '1.1'
2
+ VERSION = '1.1.1'
3
+ MAVEN_VERSION = '1.1.1'
4
4
  end
5
5
  begin
6
6
  require 'java'
@@ -20,12 +20,17 @@ module TorqueBox
20
20
  # A Future encapsulates the result of a long running
21
21
  # process, and is used in conjunction with a {FutureResponder}.
22
22
  class Future
23
-
23
+ # We can't really do no timeout - 1ms is as close as we can get.
24
+ NO_TIMEOUT = 1
25
+
24
26
  # Returns the remote error (if any)
25
27
  attr_reader :error
26
28
  attr_reader :correlation_id
27
29
  attr_accessor :default_result_timeout
28
-
30
+
31
+ # Returns all of the statuses seen by this future as an array.
32
+ attr_reader :all_statuses
33
+
29
34
  # @param [TorqueBox::Messaging::Queue] response_queue The queue
30
35
  # where response messages are to be received.
31
36
  # @param [Hash] options Additional options
@@ -39,6 +44,7 @@ module TorqueBox
39
44
  @queue = response_queue
40
45
  @correlation_id = options[:correlation_id] || self.class.unique_id
41
46
  @default_result_timeout = options[:default_result_timeout] || 30_000
47
+ @all_statuses = []
42
48
  end
43
49
 
44
50
  def started?
@@ -61,8 +67,13 @@ module TorqueBox
61
67
  # processed task itself.
62
68
  # @see FutureResponder#status
63
69
  def status
64
- receive unless @complete || @error
65
- @status
70
+ @prior_status = retrieve_status
71
+ end
72
+
73
+ # Returns true if the status has changed since the last call to
74
+ # {#status}.
75
+ def status_changed?
76
+ @prior_status != retrieve_status
66
77
  end
67
78
 
68
79
  # Attempts to return the remote result.
@@ -92,12 +103,20 @@ module TorqueBox
92
103
  end
93
104
 
94
105
  protected
95
- def receive(timeout = 1)
106
+ def retrieve_status
107
+ receive unless @complete || @error
108
+ @status
109
+ end
110
+
111
+ def receive(timeout = NO_TIMEOUT)
96
112
  response = @queue.receive( :timeout => timeout, :selector => "JMSCorrelationID = '#{@correlation_id}'" )
97
113
 
98
114
  if response
99
115
  @started = true
100
- @status = response[:status] if response.has_key?( :status )
116
+ if response.has_key?( :status )
117
+ @status = response[:status]
118
+ @all_statuses << @status
119
+ end
101
120
  @complete = response.has_key?( :result )
102
121
  @result ||= response[:result]
103
122
  @error ||= response[:error]
@@ -36,25 +36,30 @@ module TorqueBox
36
36
 
37
37
  # Signal that processing has started.
38
38
  def started
39
- publish( :started => true, :priority => :low )
39
+ send_response(:low)
40
40
  end
41
41
 
42
42
  # Report the current status back to the client. The status value
43
43
  # is application specific.
44
44
  def status=(status)
45
- publish( :status => status )
45
+ @status_set = true
46
+ @status = status
47
+ send_response
46
48
  end
47
49
 
48
50
  # Signal that processing has completed.
49
51
  # @param The result of the operation.
50
52
  def result=(result)
51
- publish( :result => result, :priority => :high )
53
+ @result_set = true
54
+ @result = result
55
+ send_response :high
52
56
  end
53
57
 
54
58
  # Signal that an error occurred during processing.
55
59
  # @param [Exception] The error!
56
60
  def error=(error)
57
- publish( :error => error, :priority => :high )
61
+ @error = error
62
+ send_response :high
58
63
  end
59
64
 
60
65
  # Handles started/complete/error for you around the given
@@ -84,8 +89,17 @@ module TorqueBox
84
89
  end
85
90
 
86
91
  protected
87
- def publish(message)
88
- @queue.publish( message, :correlation_id => @correlation_id, :ttl => @message_ttl )
92
+ def send_response(priority = :normal)
93
+ message = {}
94
+ message[:status] = @status if @status_set
95
+ message[:error] = @error if @error
96
+ message[:result] = @result if @result_set
97
+ @queue.publish( message,
98
+ {
99
+ :correlation_id => @correlation_id,
100
+ :ttl => @message_ttl,
101
+ :priority => priority
102
+ } )
89
103
  end
90
104
  end
91
105
  end
@@ -110,15 +110,15 @@ describe TorqueBox::Messaging::Destination do
110
110
  @container.stop
111
111
  end
112
112
 
113
- {
114
- true => 'prop = true',
115
- true => 'prop <> false',
116
- 5 => 'prop = 5',
117
- 5 => 'prop > 4',
118
- 5.5 => 'prop = 5.5',
119
- 5.5 => 'prop < 6',
120
- 'string' => "prop = 'string'"
121
- }.each do |value, selector|
113
+ [
114
+ [true, 'prop = true'],
115
+ [true, 'prop <> false'],
116
+ [5, 'prop = 5'],
117
+ [5, 'prop > 4'],
118
+ [5.5, 'prop = 5.5'],
119
+ [5.5, 'prop < 6'],
120
+ ['string', "prop = 'string'"]
121
+ ].each do |value, selector|
122
122
  it "should be able to select with property set to #{value} using selector '#{selector}'" do
123
123
  @queue.publish value.to_s, :properties => { :prop => value }
124
124
  message = @queue.receive(:timeout => 1000, :selector => selector)
@@ -270,9 +270,9 @@ describe TorqueBox::Messaging::Destination do
270
270
  queue.start
271
271
 
272
272
  response_thread = Thread.new {
273
- queue.receive_and_publish( :timeout => 10000 ) { |msg| msg.upcase }
273
+ queue.receive_and_publish( :timeout => 120_000 ) { |msg| msg.upcase }
274
274
  }
275
- message = queue.publish_and_receive "ping", :timeout => 10000
275
+ message = queue.publish_and_receive "ping", :timeout => 120_000
276
276
  response_thread.join
277
277
 
278
278
  queue.destroy
@@ -284,9 +284,9 @@ describe TorqueBox::Messaging::Destination do
284
284
  queue.start
285
285
 
286
286
  response_thread = Thread.new {
287
- queue.receive_and_publish( :timeout => 10000 )
287
+ queue.receive_and_publish( :timeout => 120_000 )
288
288
  }
289
- message = queue.publish_and_receive "ping", :timeout => 10000
289
+ message = queue.publish_and_receive "ping", :timeout => 120_000
290
290
  response_thread.join
291
291
 
292
292
  queue.destroy
@@ -300,14 +300,14 @@ describe TorqueBox::Messaging::Destination do
300
300
  thread_count = 3
301
301
  response_threads = (1..thread_count).map do
302
302
  Thread.new {
303
- queue.receive_and_publish( :timeout => 10000 ) { |msg| msg.upcase }
303
+ queue.receive_and_publish( :timeout => 120_000 ) { |msg| msg.upcase }
304
304
  }
305
305
  end
306
306
 
307
- message = queue.publish_and_receive "ping", :timeout => 10000
307
+ message = queue.publish_and_receive "ping", :timeout => 120_000
308
308
  # Send extra messages to trigger all remaining response threads
309
309
  (thread_count - 1).times do
310
- queue.publish_and_receive "ping", :timeout => 10000
310
+ queue.publish_and_receive "ping", :timeout => 120_000
311
311
  end
312
312
  response_threads.each { |thread| thread.join }
313
313
 
@@ -320,7 +320,7 @@ describe TorqueBox::Messaging::Destination do
320
320
  queue.start
321
321
 
322
322
  response_thread = Thread.new {
323
- queue.receive_and_publish( :timeout => 10000,
323
+ queue.receive_and_publish( :timeout => 120_000,
324
324
  :selector => "age > 60 or tan = true" )
325
325
  }
326
326
 
@@ -332,7 +332,7 @@ describe TorqueBox::Messaging::Destination do
332
332
  :properties => { :age => 25 } )
333
333
  # Publish a synchronous message that should match selector
334
334
  message = queue.publish_and_receive( "wrinkled",
335
- :timeout => 10000,
335
+ :timeout => 120_000,
336
336
  :properties => { :age => 65, :tan => true } )
337
337
  message.should eql( "wrinkled" )
338
338
  response_thread.join
@@ -0,0 +1,81 @@
1
+ require 'torquebox/messaging/future_responder'
2
+
3
+ include TorqueBox::Messaging
4
+
5
+ describe TorqueBox::Messaging::FutureResponder do
6
+ def self.it_should_publish(message, priority=nil, &block)
7
+ it "should publish with #{message.inspect}#{priority ? ' and priority :' + priority.to_s : ''}" do
8
+ opts = { :correlation_id => 'ham-biscuit', :ttl => 1234 }
9
+ opts[:priority] = priority if priority
10
+ queue = mock('queue')
11
+ responder = FutureResponder.new(queue, 'ham-biscuit', 1234)
12
+ queue.should_receive( :publish ).with( hash_including(message), hash_including( opts ) )
13
+ block.call( responder )
14
+ end
15
+ end
16
+
17
+ before(:each) do
18
+ @queue = mock('queue')
19
+ @queue.stub(:publish)
20
+ @responder = FutureResponder.new(@queue, 'correlation-id')
21
+ end
22
+
23
+ describe '#started' do
24
+ it_should_publish({}, :low) do |responder|
25
+ responder.started
26
+ end
27
+ end
28
+
29
+ describe '#status=' do
30
+ it "should set the status" do
31
+ @responder.status = 'biscuit'
32
+ @responder.instance_variable_get('@status').should == 'biscuit'
33
+ end
34
+
35
+ it_should_publish({:status => 'biscuit'}, :normal) do |responder|
36
+ responder.status = 'biscuit'
37
+ end
38
+ end
39
+
40
+ describe '#result=' do
41
+ it "should set the result" do
42
+ @responder.result = 'biscuit'
43
+ @responder.instance_variable_get('@result').should == 'biscuit'
44
+ end
45
+
46
+ it_should_publish({:result => 'biscuit'}, :high) do |responder|
47
+ responder.result = 'biscuit'
48
+ end
49
+
50
+ it "should include the last status with the result" do
51
+ queue = mock('queue')
52
+ responder = FutureResponder.new(queue, 'ham-biscuit')
53
+ queue.should_receive( :publish )
54
+ responder.status = 'crepe'
55
+ queue.should_receive( :publish ).with( hash_including({:result => 'biscuit', :status => 'crepe'}), anything )
56
+ responder.result = 'biscuit'
57
+ end
58
+ end
59
+
60
+ describe '#error=' do
61
+ it "should set the error" do
62
+ @responder.error = 'biscuit'
63
+ @responder.instance_variable_get('@error').should == 'biscuit'
64
+ end
65
+
66
+ it_should_publish({:error => 'biscuit'}, :high) do |responder|
67
+ responder.error = 'biscuit'
68
+ end
69
+
70
+ it "should include the last status with the error" do
71
+ queue = mock('queue')
72
+ responder = FutureResponder.new(queue, 'ham-biscuit')
73
+ queue.should_receive( :publish )
74
+ responder.status = 'crepe'
75
+ queue.should_receive( :publish ).with( hash_including({:error => 'biscuit', :status => 'crepe'}), anything )
76
+ responder.error = 'biscuit'
77
+ end
78
+
79
+ end
80
+
81
+ end
data/spec/future_spec.rb CHANGED
@@ -2,45 +2,147 @@ require 'torquebox/messaging/future'
2
2
 
3
3
  include TorqueBox::Messaging
4
4
 
5
- class Future
6
- attr_writer :started
7
- attr_writer :complete
8
- attr_writer :error
9
- attr_writer :result
10
- end
11
-
12
5
  describe TorqueBox::Messaging::Future do
13
6
 
14
7
  before(:each) do
15
8
  @queue = mock( Queue )
9
+ @response = nil
10
+ @queue.stub( :receive ).and_return { @response }
16
11
  @future = Future.new( @queue )
17
12
  end
18
13
 
14
+ describe "#started?" do
15
+ it "should be false if the remote side hasn't started" do
16
+ @future.should_not be_started
17
+ end
18
+
19
+ it "should be true if the remote side has started" do
20
+ @response = { }
21
+ @future.should be_started
22
+ end
23
+
24
+ it "should be true if an error occurs" do
25
+ @response = { :error => 'foo' }
26
+ @future.should be_started
27
+ end
28
+
29
+ it "should be true if an processing is complete" do
30
+ @response = { :result => 'foo' }
31
+ @future.should be_started
32
+ end
33
+ end
34
+
35
+ describe "#complete?" do
36
+ it "should be false if the remote side hasn't started" do
37
+ @future.should_not be_complete
38
+ end
39
+
40
+ it "should be false if the remote side hasn't completed" do
41
+ @response = { }
42
+ @future.should_not be_complete
43
+ end
44
+
45
+ it "should be false if an error occurs" do
46
+ @response = { :error => 'foo' }
47
+ @future.should_not be_complete
48
+ end
49
+
50
+ it "should be true if an processing is complete" do
51
+ @response = { :result => 'foo' }
52
+ @future.should be_complete
53
+ end
54
+ end
55
+
56
+ describe "#error?" do
57
+ it "should be false if the remote side hasn't started" do
58
+ @future.should_not be_error
59
+ end
60
+
61
+ it "should be false if the remote side hasn't completed" do
62
+ @response = { }
63
+ @future.should_not be_error
64
+ end
65
+
66
+ it "should be true if an error occurs" do
67
+ @response = { :error => 'foo' }
68
+ @future.should be_error
69
+ end
70
+
71
+ it "should be false if an processing is complete" do
72
+ @response = { :result => 'foo' }
73
+ @future.should_not be_error
74
+ end
75
+ end
76
+
77
+ describe '#status' do
78
+ it "should return nil if no status set" do
79
+ @future.status.should be_nil
80
+ end
81
+
82
+ it "should return the remote status" do
83
+ @response = { :status => 'biscuit' }
84
+ @future.status.should == 'biscuit'
85
+ end
86
+
87
+ it "should remember the last status" do
88
+ @response = { :status => 'biscuit' }
89
+ @future.status.should == 'biscuit'
90
+ @response = { }
91
+ @future.status.should == 'biscuit'
92
+ end
93
+ end
94
+
95
+ describe "#all_statuses" do
96
+ it "should be an emtpy array if no status has been received" do
97
+ @future.all_statuses.should == []
98
+ end
99
+
100
+ it "should be an have all the seen statuses" do
101
+ @response = { :status => :ham }
102
+ @future.status
103
+ @response = { :status => :biscuit }
104
+ @future.status
105
+ @future.all_statuses.should == [:ham, :biscuit]
106
+ end
107
+ end
108
+
109
+ describe "#status_changed?" do
110
+ it "should return false if no status has been sent" do
111
+ @future.should_not be_status_changed
112
+ end
113
+
114
+ it "should be true for the first status" do
115
+ @response = { :status => :ham }
116
+ @future.should be_status_changed
117
+ end
118
+
119
+ it "should return true if the status doesn't match the last" do
120
+ @response = { :status => :ham }
121
+ @future.status
122
+ @future.should_not be_status_changed
123
+ @response = { :status => :biscuit }
124
+ @future.should be_status_changed
125
+ end
126
+ end
127
+
19
128
  describe "#result" do
20
129
 
21
130
  it "should raise if it fails to start before timeout" do
22
- @future.stub(:receive)
23
131
  lambda { @future.result( 1 ) }.should raise_error( TimeoutException )
24
132
  end
25
133
 
26
134
  it "should raise if it fails to complete before timeout" do
27
- @future.stub(:receive)
28
- @future.started = true
135
+ @response = { }
29
136
  lambda { @future.result( 1 ) }.should raise_error( TimeoutException )
30
137
  end
31
138
 
32
139
  it "should raise if a remote error occurs" do
33
- @future.stub(:receive)
34
- @future.started = true
35
- @future.error = ArgumentError.new
140
+ @response = { :error => ArgumentError.new }
36
141
  lambda { @future.result( 1 ) }.should raise_error( ArgumentError )
37
142
  end
38
143
 
39
144
  it "should return the result if complete" do
40
- @future.stub(:receive)
41
- @future.started = true
42
- @future.complete = true
43
- @future.result = :success!
145
+ @response = { :result => :success! }
44
146
  @future.result.should == :success!
45
147
  end
46
148
 
@@ -50,10 +152,12 @@ describe TorqueBox::Messaging::Future do
50
152
 
51
153
  it "should delegate to #result" do
52
154
  @result = mock(:result)
53
- @future.should_receive(:result).and_return(@result)
54
155
  @result.should_receive(:blah)
156
+ @response = { :result => @result }
55
157
  @future.blah
56
158
  end
57
159
 
58
160
  end
161
+
162
+
59
163
  end
metadata CHANGED
@@ -2,15 +2,15 @@
2
2
  name: torquebox-messaging
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: "1.1"
5
+ version: 1.1.1
6
6
  platform: java
7
- authors: ["The TorqueBox Team"]
8
-
7
+ authors:
8
+ - The TorqueBox Team
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-13 00:00:00 -04:00
13
+ date: 2011-08-09 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  requirements:
22
22
  - - "="
23
23
  - !ruby/object:Gem::Version
24
- version: "1.1"
24
+ version: 1.1.1
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - "="
34
34
  - !ruby/object:Gem::Version
35
- version: "1.1"
35
+ version: 1.1.1
36
36
  type: :development
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - "="
45
45
  - !ruby/object:Gem::Version
46
- version: "1.1"
46
+ version: 1.1.1
47
47
  type: :development
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
@@ -54,7 +54,7 @@ dependencies:
54
54
  requirements:
55
55
  - - "="
56
56
  - !ruby/object:Gem::Version
57
- version: "1.1"
57
+ version: 1.1.1
58
58
  type: :runtime
59
59
  version_requirements: *id004
60
60
  - !ruby/object:Gem::Dependency
@@ -70,6 +70,7 @@ dependencies:
70
70
  version_requirements: *id005
71
71
  description: ""
72
72
  email:
73
+ - torquebox-dev@torquebox.org
73
74
  executables: []
74
75
 
75
76
  extensions: []
@@ -127,6 +128,7 @@ files:
127
128
  - spec/destination_spec.rb
128
129
  - spec/dispatcher-queues.yml
129
130
  - spec/dispatcher_not_running.rb
131
+ - spec/future_responder_spec.rb
130
132
  - spec/future_spec.rb
131
133
  - spec/queues.yml
132
134
  - spec/task_spec.rb
@@ -163,6 +165,7 @@ test_files:
163
165
  - spec/backgroundable_spec.rb
164
166
  - spec/client_spec.rb
165
167
  - spec/destination_spec.rb
168
+ - spec/future_responder_spec.rb
166
169
  - spec/future_spec.rb
167
170
  - spec/task_spec.rb
168
171
  - spec/ext/java_jmx_session_spec.rb