jruby-hornetq 0.2.3.alpha → 0.2.5.alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env jruby
2
+ #
3
+ # HornetQ Producer:
4
+ # Write messages to the queue
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'hornetq'
10
+ require 'logger'
11
+ require 'test_object'
12
+
13
+ config = YAML.load_file(File.dirname(__FILE__) + '/hornetq.yml')
14
+ client = config['client']
15
+
16
+ # Create a HornetQ session
17
+ logger = Logger.new($stdout)
18
+ factory = HornetQ::Client::Factory.new(client[:connector])
19
+ session_pool = factory.create_session_pool(client[:session_pool])
20
+ producer_manager = HornetQ::Client::ProducerManager.new(session_pool, client[:addresses], true)
21
+
22
+ ['HUP', 'INT', 'TERM'].each do |signal_name|
23
+ Signal.trap(signal_name) do
24
+ puts "caught #{signal_name}"
25
+ $stopped = true
26
+ end
27
+ end
28
+
29
+ $stopped = false
30
+ threads = []
31
+ (1..5).each do |i|
32
+ threads << Thread.new(i) do |thread_count|
33
+ msg_count = 0
34
+ while !$stopped
35
+ msg_count += 1
36
+ obj = TestObject.new("Message ##{thread_count}-#{msg_count}")
37
+ producer_manager.send('address1', obj)
38
+ sleep 1
39
+ end
40
+ end
41
+ end
42
+ (6..10).each do |i|
43
+ threads << Thread.new(i) do |thread_count|
44
+ msg_count = 0
45
+ while !$stopped
46
+ msg_count += 1
47
+ obj = {:thread => thread_count, :message => msg_count}
48
+ producer_manager.send('address2', obj)
49
+ sleep 2
50
+ end
51
+ end
52
+ end
53
+
54
+ threads.each { |thread| thread.join }
@@ -0,0 +1,11 @@
1
+ class TestObject
2
+ attr_reader :message
3
+
4
+ def initialize(message)
5
+ @message = message
6
+ end
7
+
8
+ def to_s
9
+ @message
10
+ end
11
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env jruby
2
+ #
3
+ # HornetQ Consumer:
4
+ # Write messages to the queue
5
+ #
6
+
7
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'hornetq'
10
+ require 'test_object'
11
+
12
+ $config = YAML.load_file(File.dirname(__FILE__) + '/hornetq.yml')
13
+ $client = $config['client']
14
+ factory = HornetQ::Client::Factory.new($client[:connector])
15
+ $consumer_manager = HornetQ::Client::ConsumerManager.new(factory, $client[:session], $client[:addresses])
16
+
17
+ ['HUP', 'INT', 'TERM'].each do |signal_name|
18
+ Signal.trap(signal_name) do
19
+ puts "caught #{signal_name}"
20
+ consumer_manager.close
21
+ end
22
+ end
23
+
24
+ $threads = []
25
+ def create_workers(address, queue, count, sleep_time)
26
+ address_config = $client[:addresses][address]
27
+ queue_config = address_config[:queues][queue]
28
+ (1..count).each do |i|
29
+ $threads << Thread.new(i) do |thread_count|
30
+ prefix = "#{address}-#{queue}-#{thread_count}"
31
+ begin
32
+ $consumer_manager.each(address,queue) do |obj|
33
+ puts "#{prefix} read #{obj.inspect}"
34
+ sleep sleep_time
35
+ end
36
+ puts "#{prefix} end of thread"
37
+ rescue Exception => e
38
+ puts "#{prefix} Exception: #{e.message}\n#{e.backtrace.join("\n")}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ create_workers('address1', 'queue1_1', 5, 1)
45
+ create_workers('address1', 'queue1_2', 5, 2)
46
+ create_workers('address2', 'queue2_1', 5, 2)
47
+ create_workers('address2', 'queue2_2', 5, 1)
48
+
49
+ $threads.each { |thread| thread.join }
data/lib/hornetq.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  include Java
2
- require 'hornetq/server'
3
- require 'hornetq/client'
4
- require 'hornetq/uri'
5
2
 
6
3
  module HornetQ
7
4
 
@@ -27,4 +24,10 @@ module HornetQ
27
24
  port ||= DEFAULT_NETTY_PORT
28
25
  return java.lang.Integer.new(port)
29
26
  end
27
+
30
28
  end
29
+
30
+ require 'hornetq/server'
31
+ require 'hornetq/client'
32
+ require 'hornetq/uri'
33
+ require 'hornetq/common/logging'
@@ -1,19 +1,22 @@
1
+ HornetQ.require_jar 'hornetq-core-client'
2
+ HornetQ.require_jar 'netty'
3
+
1
4
  module HornetQ
2
5
  module Client
3
- # Only load as needed
4
- def self.load_requirements
5
- HornetQ.require_jar 'hornetq-core-client'
6
- HornetQ.require_jar 'netty'
7
- require 'hornetq/client/org_hornetq_api_core_client_client_session'
8
- require 'hornetq/client/org_hornetq_core_client_impl_client_message_impl'
9
- require 'hornetq/client/org_hornetq_utils_typed_properties'
10
-
11
- # Import Message Constants
12
- import Java::org.hornetq.api.core::Message
13
- end
6
+ # Import Message Constants
7
+ java_import Java::org.hornetq.api.core::Message
14
8
  end
15
9
  end
16
10
 
17
11
  require 'hornetq/client/factory'
18
- require 'hornetq/client/requestor'
19
- require 'hornetq/client/server'
12
+ require 'hornetq/common/org_hornetq_core_logging_logger'
13
+ require 'hornetq/client/org_hornetq_api_core_client_client_session'
14
+ require 'hornetq/client/org_hornetq_core_client_impl_client_message_impl'
15
+ require 'hornetq/client/org_hornetq_core_client_impl_client_consumer_impl'
16
+ require 'hornetq/client/org_hornetq_core_client_impl_client_producer_impl'
17
+ require 'hornetq/client/org_hornetq_utils_typed_properties'
18
+ require 'hornetq/common/logging'
19
+ require 'hornetq/common/log_delegate'
20
+ require 'hornetq/client/message_handler'
21
+ require 'hornetq/client/requestor_pattern'
22
+ require 'hornetq/client/server_pattern'
@@ -1,378 +1,443 @@
1
- require 'uri'
1
+ module HornetQ
2
+ module Client
2
3
 
3
- module HornetQ::Client
4
-
5
- class Factory
6
- # Create a new Factory from which sessions can be created
7
- #
8
- # Parameters:
9
- # * a Hash consisting of one or more of the named parameters
10
- # * Summary of parameters and their default values
11
- # HornetQ::Client::Factory.new(
12
- # :uri => 'hornetq://localhost',
13
- # :ack_batch_size => ,
14
- # :auto_group => ,
15
- # :block_on_acknowledge => ,
16
- # :block_on_durable_send => ,
17
- # :block_on_non_durable_send => ,
18
- # :cache_large_messages_client => ,
19
- # :call_timeout => ,
20
- # :client_failure_check_period => ,
21
- # :confirmation_window_size => ,
22
- # :connection_load_balancing_policy_class_name => ,
23
- # :connection_ttl => ,
24
- # :consumer_max_rate => ,
25
- # :consumer_window_size => ,
26
- # :discovery_address => ,
27
- # :discovery_initial_wait_timeout => ,
28
- # :discovery_port => ,
29
- # :discovery_refresh_timeout => ,
30
- # :failover_on_initial_connection => true,
31
- # :failover_on_server_shutdown => true,
32
- # :group_id => ,
33
- # :initial_message_packet_size => ,
34
- # :java_object => ,
35
- # :local_bind_address => ,
36
- # :max_retry_interval => ,
37
- # :min_large_message_size => ,
38
- # :pre_acknowledge => ,
39
- # :producer_max_rate => ,
40
- # :producer_window_size => ,
41
- # :reconnect_attempts => 1,
42
- # :retry_interval => ,
43
- # :retry_interval_multiplier => ,
44
- # :scheduled_thread_pool_max_size => ,
45
- # :static_connectors => ,
46
- # :thread_pool_max_size => ,
47
- # :use_global_pools =>
48
- # )
49
- #
50
- # Mandatory Parameters
51
- # * :uri
52
- # * The hornetq uri as to which server to connect with and which
53
- # transport protocol to use. Format:
54
- # hornetq://server:port,backupserver:port/?protocol=[netty|discover]
55
- # * To use the default netty transport
56
- # hornetq://server:port
57
- # * To use the default netty transport and specify a backup server
58
- # hornetq://server:port,backupserver:port
59
- # * To use auto-discovery
60
- # hornetq://server:port/?protocol=discovery
61
- # * To use HornetQ within the current JVM
62
- # hornetq://invm
63
- #
64
- # Optional Parameters
65
- # * :ack_batch_size
66
- # * :auto_group
67
- # * :block_on_acknowledge
68
- # * :block_on_durable_send
69
- # * :block_on_non_durable_send
70
- # * :cache_large_messages_client
71
- # * :call_timeout
72
- # * :client_failure_check_period
73
- # * :confirmation_window_size
74
- # * :connection_load_balancing_policy_class_name
75
- # * :connection_ttl
76
- # * :consumer_max_rate
77
- # * :consumer_window_size
78
- # * :discovery_address
79
- # * :discovery_initial_wait_timeout
80
- # * :discovery_port
81
- # * :discovery_refresh_timeout
82
- # * :failover_on_initial_connection
83
- # * :failover_on_server_shutdown
84
- # * :group_id
85
- # * :initial_message_packet_size
86
- # * :java_object
87
- # * :local_bind_address
88
- # * :max_retry_interval
89
- # * :min_large_message_size
90
- # * :pre_acknowledge
91
- # * :producer_max_rate
92
- # * :producer_window_size
93
- # * :reconnect_attempts
94
- # * :retry_interval
95
- # * :retry_interval_multiplier
96
- # * :scheduled_thread_pool_max_size
97
- # * :static_connectors
98
- # * :thread_pool_max_size
99
- # * :use_global_pools
4
+ class Factory
5
+ # Create a new Factory and Session
6
+ #
7
+ # Creates a new factory and session, then passes the session to the supplied
8
+ # block. Upon completion the session and factory are both closed
9
+ # See Factory::initialize and Factory::create_session for the list
10
+ # of parameters
11
+ def self.session(params={},&proc)
12
+ raise "Missing mandatory code block" unless proc
13
+ factory = nil
14
+ session = nil
15
+ begin
16
+ if params.kind_of?(String)
17
+ # TODO: Support passing username and password from URI to Session
18
+ factory = self.new(params)
19
+ session = factory.session({}, &proc)
20
+ else
21
+ factory = self.new(params[:connector] || {})
22
+ session = factory.session(params[:session] || {}, &proc)
23
+ end
24
+ ensure
25
+ session.close if session
26
+ factory.close if factory
27
+ end
28
+ end
100
29
 
101
- def initialize(params={})
102
- HornetQ::Client.load_requirements
103
- uri = nil
104
- # TODO: Support :uri as an array for cluster configurations
105
- if params.kind_of?(String)
106
- uri = HornetQ::URI.new(params)
107
- params = uri.params
108
- else
109
- raise "Missing :uri param in HornetQ::Server.create_server" unless params[:uri]
110
- uri = HornetQ::URI.new(params.delete(:uri))
111
- # params override uri params
112
- params = uri.params.merge(params)
30
+ # Create a new Factory along with a Session, and then start the session
31
+ #
32
+ # Creates a new factory and session, then passes the session to the supplied
33
+ # block. Upon completion the session and factory are both closed
34
+ # See Factory::initialize and Factory::create_session for the list
35
+ # of parameters
36
+ def self.start(params={},&proc)
37
+ session(params) do |session|
38
+ session.start
39
+ proc.call(session)
40
+ end
113
41
  end
114
-
115
- @factory = nil
116
- # In-VM Transport has no fail-over or additional parameters
117
- if uri.host == 'invm'
118
- transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::INVM_CONNECTOR_CLASS_NAME)
119
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
120
- elsif params[:protocol]
121
- # Auto-Discovery just has a host name and port
122
- if params[:protocol] == 'discovery'
123
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(uri.host, uri.port)
124
- elsif params[:protocol] != 'netty'
125
- raise "Unknown HornetQ protocol:#{params[:protocol]}"
42
+
43
+ # Call the supplied code block after creating a factory instance
44
+ # See initialize for the parameter list
45
+ # The factory is closed before returning
46
+ #
47
+ # Returns the result of the code block
48
+ def self.create_factory(params={}, &proc)
49
+ raise "Missing mandatory code block" unless proc
50
+ factory = nil
51
+ result = nil
52
+ begin
53
+ factory=self.new(params)
54
+ result = proc.call(factory)
55
+ ensure
56
+ factory.close
126
57
  end
58
+ result
127
59
  end
128
60
 
129
- # Unless already created, then the factory will use the netty protocol
130
- unless @factory
131
- # Primary Transport
132
- transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.host, 'port' => uri.port })
61
+ # Create a new Factory from which sessions can be created
62
+ #
63
+ # Parameters:
64
+ # * a Hash consisting of one or more of the named parameters
65
+ # * Summary of parameters and their default values
66
+ # HornetQ::Client::Factory.new(
67
+ # :uri => 'hornetq://localhost',
68
+ # :ack_batch_size => ,
69
+ # :auto_group => ,
70
+ # :block_on_acknowledge => ,
71
+ # :block_on_durable_send => ,
72
+ # :block_on_non_durable_send => ,
73
+ # :cache_large_messages_client => ,
74
+ # :call_timeout => ,
75
+ # :client_failure_check_period => ,
76
+ # :confirmation_window_size => ,
77
+ # :connection_load_balancing_policy_class_name => ,
78
+ # :connection_ttl => ,
79
+ # :consumer_max_rate => ,
80
+ # :consumer_window_size => ,
81
+ # :discovery_address => ,
82
+ # :discovery_initial_wait_timeout => ,
83
+ # :discovery_port => ,
84
+ # :discovery_refresh_timeout => ,
85
+ # :failover_on_initial_connection => true,
86
+ # :failover_on_server_shutdown => true,
87
+ # :group_id => ,
88
+ # :initial_message_packet_size => ,
89
+ # :java_object => ,
90
+ # :local_bind_address => ,
91
+ # :max_retry_interval => ,
92
+ # :min_large_message_size => ,
93
+ # :pre_acknowledge => ,
94
+ # :producer_max_rate => ,
95
+ # :producer_window_size => ,
96
+ # :reconnect_attempts => 1,
97
+ # :retry_interval => ,
98
+ # :retry_interval_multiplier => ,
99
+ # :scheduled_thread_pool_max_size => ,
100
+ # :static_connectors => ,
101
+ # :thread_pool_max_size => ,
102
+ # :use_global_pools =>
103
+ # )
104
+ #
105
+ # Mandatory Parameters
106
+ # * :uri
107
+ # * The hornetq uri as to which server to connect with and which
108
+ # transport protocol to use. Format:
109
+ # hornetq://server:port,backupserver:port/?protocol=[netty|discover]
110
+ # * To use the default netty transport
111
+ # hornetq://server:port
112
+ # * To use the default netty transport and specify a backup server
113
+ # hornetq://server:port,backupserver:port
114
+ # * To use auto-discovery
115
+ # hornetq://server:port/?protocol=discovery
116
+ # * To use HornetQ within the current JVM
117
+ # hornetq://invm
118
+ #
119
+ # Optional Parameters
120
+ # * :ack_batch_size
121
+ # * :auto_group
122
+ # * :block_on_acknowledge
123
+ # * :block_on_durable_send
124
+ # * :block_on_non_durable_send
125
+ # * :cache_large_messages_client
126
+ # * :call_timeout
127
+ # * :client_failure_check_period
128
+ # * :confirmation_window_size
129
+ # * :connection_load_balancing_policy_class_name
130
+ # * :connection_ttl
131
+ # * :consumer_max_rate
132
+ # * :consumer_window_size
133
+ # * :discovery_address
134
+ # * :discovery_initial_wait_timeout
135
+ # * :discovery_port
136
+ # * :discovery_refresh_timeout
137
+ # * :failover_on_initial_connection
138
+ # * :failover_on_server_shutdown
139
+ # * :group_id
140
+ # * :initial_message_packet_size
141
+ # * :java_object
142
+ # * :local_bind_address
143
+ # * :max_retry_interval
144
+ # * :min_large_message_size
145
+ # * :pre_acknowledge
146
+ # * :producer_max_rate
147
+ # * :producer_window_size
148
+ # * :reconnect_attempts
149
+ # * :retry_interval
150
+ # * :retry_interval_multiplier
151
+ # * :scheduled_thread_pool_max_size
152
+ # * :static_connectors
153
+ # * :thread_pool_max_size
154
+ # * :use_global_pools
133
155
 
134
- # Check for backup server connection information
135
- if uri.backup_host
136
- backup_transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.backup_host, 'port' => uri.backup_port })
137
- @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport, backup_transport)
156
+ def initialize(params={})
157
+ uri = nil
158
+ # TODO: Support :uri as an array for cluster configurations
159
+ if params.kind_of?(String)
160
+ uri = HornetQ::URI.new(params)
161
+ params = uri.params
138
162
  else
163
+ raise "Missing :uri param in HornetQ::Server.create_server" unless params[:uri]
164
+ uri = HornetQ::URI.new(params.delete(:uri))
165
+ # params override uri params
166
+ params = uri.params.merge(params)
167
+ end
168
+
169
+ @factory = nil
170
+ # In-VM Transport has no fail-over or additional parameters
171
+ if uri.host == 'invm'
172
+ transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::INVM_CONNECTOR_CLASS_NAME)
139
173
  @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
174
+ elsif params[:protocol]
175
+ # Auto-Discovery just has a host name and port
176
+ if params[:protocol] == 'discovery'
177
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(uri.host, uri.port)
178
+ elsif params[:protocol] != 'netty'
179
+ raise "Unknown HornetQ protocol:#{params[:protocol]}"
180
+ end
181
+ end
182
+
183
+ # Unless already created, then the factory will use the netty protocol
184
+ unless @factory
185
+ # Primary Transport
186
+ transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.host, 'port' => uri.port })
187
+
188
+ # Check for backup server connection information
189
+ if uri.backup_host
190
+ backup_transport = Java::org.hornetq.api.core.TransportConfiguration.new(HornetQ::NETTY_CONNECTOR_CLASS_NAME, {'host' => uri.backup_host, 'port' => uri.backup_port })
191
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport, backup_transport)
192
+ else
193
+ @factory = Java::org.hornetq.api.core.client.HornetQClient.create_client_session_factory(transport)
194
+ end
195
+ end
196
+
197
+ # If any other options were supplied, apply them to the created Factory instance
198
+ params.each_pair do |key, val|
199
+ next if key == :uri
200
+ method = key.to_s+'='
201
+ if @factory.respond_to? method
202
+ @factory.send method, val
203
+ #puts "Debug: #{key} = #{@factory.send key}" if @factory.respond_to? key.to_sym
204
+ else
205
+ puts "Warning: Option:#{key}, with value:#{val} is invalid and being ignored"
206
+ end
140
207
  end
141
208
  end
142
209
 
143
- # If any other options were supplied, apply them to the created Factory instance
144
- params.each_pair do |key, val|
145
- next if key == :uri
146
- method = key.to_s+'='
147
- if @factory.respond_to? method
148
- @factory.send method, val
149
- #puts "Debug: #{key} = #{@factory.send key}" if @factory.respond_to? key.to_sym
150
- else
151
- puts "Warning: Option:#{key}, with value:#{val} is invalid and being ignored"
210
+ # Create a new HornetQ session
211
+ #
212
+ # Note: Remember to close the session once it is no longer used.
213
+ # Recommend using #session with a block over this method where possible
214
+ #
215
+ # Note:
216
+ # * The returned session MUST be closed once complete
217
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
218
+ # session = factory.create_session
219
+ # ...
220
+ # session.close
221
+ # factory.close
222
+ #
223
+ # Returns:
224
+ # * A new HornetQ ClientSession
225
+ # * See org.hornetq.api.core.client.ClientSession for documentation on returned object
226
+ #
227
+ # Throws:
228
+ # * NativeException
229
+ # * ...
230
+ #
231
+ # Example:
232
+ # require 'hornetq'
233
+ #
234
+ # factory = nil
235
+ # session = nil
236
+ # begin
237
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
238
+ # session = factory.create_session
239
+ #
240
+ # # Create a new queue
241
+ # session.create_queue('Example', 'Example', true)
242
+ #
243
+ # # Create a producer to send messages
244
+ # producer = session.create_producer('Example')
245
+ #
246
+ # # Create a Text Message
247
+ # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
248
+ # message.body_buffer.write_string('Hello World')
249
+ #
250
+ # # Send the message
251
+ # producer.send(message)
252
+ # ensure
253
+ # session.close if session
254
+ # factory.close if factory
255
+ # end
256
+ #
257
+ # Parameters:
258
+ # * a Hash consisting of one or more of the named parameters
259
+ # * Summary of parameters and their default values
260
+ # factory.create_session(
261
+ # :username => 'my_username', # Default is no authentication
262
+ # :password => 'password', # Default is no authentication
263
+ # :xa => false,
264
+ # :auto_commit_sends => true,
265
+ # :auto_commit_acks => true,
266
+ # :pre_acknowledge => false,
267
+ # :ack_batch_size => 1
268
+ # )
269
+ #
270
+ # Mandatory Parameters
271
+ # * None
272
+ #
273
+ # Optional Parameters
274
+ # * :username
275
+ # * The user name. To create an authenticated session
276
+ #
277
+ # * :password
278
+ # * The user password. To create an authenticated session
279
+ #
280
+ # * :xa
281
+ # * Whether the session supports XA transaction semantics or not
282
+ #
283
+ # * :auto_commit_sends
284
+ # * true: automatically commit message sends
285
+ # * false: commit manually
286
+ #
287
+ # * :auto_commit_acks
288
+ # * true: automatically commit message acknowledgement
289
+ # * false: commit manually
290
+ #
291
+ # * :pre_acknowledge
292
+ # * true: to pre-acknowledge messages on the server
293
+ # * false: to let the client acknowledge the messages
294
+ # * Note: It is possible to pre-acknowledge messages on the server so that the
295
+ # client can avoid additional network trip to the server to acknowledge
296
+ # messages. While this increases performance, this does not guarantee
297
+ # delivery (as messages can be lost after being pre-acknowledged on the
298
+ # server). Use with caution if your application design permits it.
299
+ #
300
+ # * :ack_batch_size
301
+ # * the batch size of the acknowledgements
302
+ #
303
+ def create_session(params={})
304
+ raise "HornetQ::Client::Factory Already Closed" unless @factory
305
+ @factory.create_session(
306
+ params[:username],
307
+ params[:password],
308
+ params[:xa] || false,
309
+ params[:auto_commit_sends].nil? ? true : params[:auto_commit_sends],
310
+ params[:auto_commit_acks].nil? ? true : params[:auto_commit_acks],
311
+ params[:pre_acknowledge] || false,
312
+ params[:ack_batch_size] || 1)
313
+ end
314
+
315
+ # Create a session, call the supplied block and once it completes
316
+ # close the session.
317
+ # See session_create for the Parameters
318
+ #
319
+ # Returns the result of the block
320
+ #
321
+ # Example
322
+ # HornetQ::Client::Factory.create_session(:uri => 'hornetq://localhost/') do |session|
323
+ # session.create_queue("Address", "Queue")
324
+ # end
325
+ #
326
+ # Example:
327
+ # require 'hornetq'
328
+ #
329
+ # factory = nil
330
+ # begin
331
+ # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
332
+ # factory.create_session do |session|
333
+ #
334
+ # # Create a new queue
335
+ # session.create_queue('Example', 'Example', true)
336
+ #
337
+ # # Create a producer to send messages
338
+ # producer = session.create_producer('Example')
339
+ #
340
+ # # Create a Text Message
341
+ # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
342
+ # message.body = 'Hello World'
343
+ #
344
+ # # Send the message
345
+ # producer.send(message)
346
+ # end
347
+ # ensure
348
+ # factory.close if factory
349
+ # end
350
+ def session(params={}, &proc)
351
+ raise "HornetQ::Client::session mandatory block missing" unless proc
352
+ session = nil
353
+ begin
354
+ session = create_session(params)
355
+ proc.call(session)
356
+ ensure
357
+ session.close if session
152
358
  end
153
359
  end
154
- end
155
360
 
156
- # Create a new HornetQ session
157
- #
158
- # Note: Remember to close the session once it is no longer used.
159
- # Recommend using #session with a block over this method where possible
160
- #
161
- # Note:
162
- # * The returned session MUST be closed once complete
163
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
164
- # session = factory.create_session
165
- # ...
166
- # session.close
167
- # factory.close
168
- #
169
- # Returns:
170
- # * A new HornetQ ClientSession
171
- # * See org.hornetq.api.core.client.ClientSession for documentation on returned object
172
- #
173
- # Throws:
174
- # * NativeException
175
- # * ...
176
- #
177
- # Example:
178
- # require 'hornetq'
179
- #
180
- # factory = nil
181
- # session = nil
182
- # begin
183
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
184
- # session = factory.create_session
185
- #
186
- # # Create a new queue
187
- # session.create_queue('Example', 'Example', true)
188
- #
189
- # # Create a producer to send messages
190
- # producer = session.create_producer('Example')
191
- #
192
- # # Create a Text Message
193
- # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
194
- # message.body_buffer.write_string('Hello World')
195
- #
196
- # # Send the message
197
- # producer.send(message)
198
- # ensure
199
- # session.close if session
200
- # factory.close if factory
201
- # end
202
- #
203
- # Parameters:
204
- # * a Hash consisting of one or more of the named parameters
205
- # * Summary of parameters and their default values
206
- # factory.create_session(
207
- # :username => 'my_username', # Default is no authentication
208
- # :password => 'password', # Default is no authentication
209
- # :xa => false,
210
- # :auto_commit_sends => true,
211
- # :auto_commit_acks => true,
212
- # :pre_acknowledge => false,
213
- # :ack_batch_size => 1
214
- # )
215
- #
216
- # Mandatory Parameters
217
- # * None
218
- #
219
- # Optional Parameters
220
- # * :username
221
- # * The user name. To create an authenticated session
222
- #
223
- # * :password
224
- # * The user password. To create an authenticated session
225
- #
226
- # * :xa
227
- # * Whether the session supports XA transaction semantics or not
228
- #
229
- # * :auto_commit_sends
230
- # * true: automatically commit message sends
231
- # * false: commit manually
232
- #
233
- # * :auto_commit_acks
234
- # * true: automatically commit message acknowledgement
235
- # * false: commit manually
236
- #
237
- # * :pre_acknowledge
238
- # * true: to pre-acknowledge messages on the server
239
- # * false: to let the client acknowledge the messages
240
- # * Note: It is possible to pre-acknowledge messages on the server so that the
241
- # client can avoid additional network trip to the server to acknowledge
242
- # messages. While this increases performance, this does not guarantee
243
- # delivery (as messages can be lost after being pre-acknowledged on the
244
- # server). Use with caution if your application design permits it.
245
- #
246
- # * :ack_batch_size
247
- # * the batch size of the acknowledgements
248
- #
249
- def create_session(params={})
250
- raise "HornetQ::Client::Factory Already Closed" unless @factory
251
- @factory.create_session(
252
- params[:username],
253
- params[:password],
254
- params[:xa] || false,
255
- params[:auto_commit_sends].nil? ? true : params[:auto_commit_sends],
256
- params[:auto_commit_acks].nil? ? true : params[:auto_commit_acks],
257
- params[:pre_acknowledge] || false,
258
- params[:ack_batch_size] || 1)
259
- end
361
+ # Create a Session pool
362
+ # TODO Raise an exception when gene_pool is not available
363
+ def create_session_pool(params={})
364
+ require 'hornetq/client/session_pool'
365
+ SessionPool.new(self, params)
366
+ end
260
367
 
261
- # Create a session, call the supplied block and once it completes
262
- # close the session.
263
- # See session_create for the Parameters
264
- #
265
- # Returns the result of the block
266
- #
267
- # Example
268
- # HornetQ::Client::Factory.create_session(:uri => 'hornetq://localhost/') do |session|
269
- # session.create_queue("Address", "Queue")
270
- # end
271
- #
272
- # Example:
273
- # require 'hornetq'
274
- #
275
- # factory = nil
276
- # begin
277
- # factory = HornetQ::Client::Factory.new(:uri => 'hornetq://localhost/')
278
- # factory.create_session do |session|
279
- #
280
- # # Create a new queue
281
- # session.create_queue('Example', 'Example', true)
282
- #
283
- # # Create a producer to send messages
284
- # producer = session.create_producer('Example')
285
- #
286
- # # Create a Text Message
287
- # message = session.create_message(HornetQ::Client::Message::TEXT_TYPE,true)
288
- # message.body = 'Hello World'
289
- #
290
- # # Send the message
291
- # producer.send(message)
292
- # end
293
- # ensure
294
- # factory.close if factory
295
- # end
296
- def session(params={}, &proc)
297
- raise "HornetQ::Client::session mandatory block missing" unless proc
298
- session = nil
299
- begin
300
- session = create_session(params)
301
- proc.call(session)
302
- ensure
303
- session.close if session
368
+ # Close Factory connections
369
+ def close
370
+ @factory.close if @factory
371
+ @factory = nil
304
372
  end
305
- end
306
-
307
- # Create a Session pool
308
- # TODO Raise an exception when gene_pool is not available
309
- def create_session_pool(params={})
310
- require 'hornetq/client/session_pool'
311
- SessionPool.new(self, params)
312
- end
313
-
314
- # Close Factory connections
315
- def close
316
- @factory.close if @factory
317
- @factory = nil
318
- end
319
373
 
320
- # Create a new Factory and Session
321
- #
322
- # Creates a new factory and session, then passes the session to the supplied
323
- # block. Upon completion the session and factory are both closed
324
- # See Factory::initialize and Factory::create_session for the list
325
- # of parameters
326
- def self.session(params={},&proc)
327
- raise "Missing mandatory code block" unless proc
328
- factory = nil
329
- session = nil
330
- begin
331
- if params.kind_of?(String)
332
- # TODO: Support passing username and password from URI to Session
333
- factory = self.new(params)
334
- session = factory.session({}, &proc)
335
- else
336
- factory = self.new(params[:connector] || {})
337
- session = factory.session(params[:session] || {}, &proc)
374
+ # Receive messages in a separate thread when they arrive
375
+ # Allows messages to be received in a separate thread. I.e. Asynchronously
376
+ # This method will return to the caller before messages are processed.
377
+ # It is then the callers responsibility to keep the program active so that messages
378
+ # can then be processed.
379
+ #
380
+ # Note:
381
+ #
382
+ # Session Parameters:
383
+ # :options => any of the javax.jms.Session constants
384
+ # Default: javax.jms.Session::AUTO_ACKNOWLEDGE
385
+ #
386
+ # :session_count : Number of sessions to create, each with their own consumer which
387
+ # in turn will call the supplied block.
388
+ # Note: The supplied block must be thread safe since it will be called
389
+ # by several threads at the same time.
390
+ # I.e. Don't change instance variables etc. without the
391
+ # necessary semaphores etc.
392
+ # Default: 1
393
+ #
394
+ # Consumer Parameters:
395
+ # :queue_name => Name of the Queue to read messages from
396
+ #
397
+ # :selector => Filter which messages should be returned from the queue
398
+ # Default: All messages
399
+ # :no_local => Determine whether messages published by its own connection
400
+ # should be delivered to it
401
+ # Default: false
402
+ #
403
+ # :statistics Capture statistics on how many messages have been read
404
+ # true : This method will capture statistics on the number of messages received
405
+ # and the time it took to process them.
406
+ # The timer starts when each() is called and finishes when either the last message was received,
407
+ # or when Destination::statistics is called. In this case MessageConsumer::statistics
408
+ # can be called several times during processing without affecting the end time.
409
+ # Also, the start time and message count is not reset until MessageConsumer::each
410
+ # is called again with :statistics => true
411
+ #
412
+ # The statistics gathered are returned when :statistics => true and :async => false
413
+ #
414
+ # Usage: For transacted sessions (the default) the Proc supplied must return
415
+ # either true or false:
416
+ # true => The session is committed
417
+ # false => The session is rolled back
418
+ # Any Exception => The session is rolled back
419
+ #
420
+ # Notes:
421
+ # * Remember to call ::start on the factory otherwise the on_message will not
422
+ # start consuming any messages
423
+ # * Remember to call message.acknowledge before completing the block so that
424
+ # the message will be removed from the queue
425
+ # * If the block throws an exception, the
426
+ def on_message(parms, &proc)
427
+ consumer_count = parms[:session_count] || 1
428
+ consumer_count.times do
429
+ session = self.create_session(parms)
430
+ consumer = session.create_consumer_from_params(parms)
431
+ consumer.on_message(parms, &proc)
432
+ @consumers << consumer
433
+ @sessions << session
338
434
  end
339
- ensure
340
- session.close if session
341
- factory.close if factory
342
- end
343
- end
344
-
345
- # Create a new Factory along with a Session, and then start the session
346
- #
347
- # Creates a new factory and session, then passes the session to the supplied
348
- # block. Upon completion the session and factory are both closed
349
- # See Factory::initialize and Factory::create_session for the list
350
- # of parameters
351
- def self.start(params={},&proc)
352
- session(params) do |session|
353
- session.start
354
- proc.call(session)
355
435
  end
356
- end
357
-
358
- # Call the supplied code block after creating a factory instance
359
- # See initialize for the parameter list
360
- # The factory is closed before returning
361
- #
362
- # Returns the result of the code block
363
- def self.create_factory(params={}, &proc)
364
- raise "Missing mandatory code block" unless proc
365
- factory = nil
366
- result = nil
367
- begin
368
- factory=self.new(params)
369
- result = proc.call(factory)
370
- ensure
371
- factory.close
436
+
437
+ def on_message_statistics
438
+ @consumers.collect{|consumer| consumer.on_message_statistics}
372
439
  end
373
- result
374
- end
375
440
 
376
- end
377
-
441
+ end
442
+ end
378
443
  end