haredo 2.0.9 → 3.0.2
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/CHANGES.md +68 -0
- data/README.md +53 -18
- data/src/lib/haredo/peer.rb +70 -23
- data/src/lib/haredo/plugin.rb +1 -1
- data/src/lib/haredo/service/config.rb +1 -1
- data/src/lib/haredo/service/daemon.rb +0 -12
- data/src/lib/haredo/version.rb +4 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ef90f8c4b3c742587932fa39460612e48d394d9
|
4
|
+
data.tar.gz: e83d8563ce838be478d7c3be168e591370c44f89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10a9b48836ea8291b7fc7f92d3be421157392d73f87d73cf7490f24fe2141e60e3e0bf80a556328a1fef2b0d97d65610fa95660fc87c42ca11b1de0f56284f89
|
7
|
+
data.tar.gz: 183c7a614608a0ee93bbe18f489706e38201694f3397fcf33f9894ff3e3eb5fbab05de345d46962729b586777db65148a5f5365e77482bbf4cc476797272bedf
|
data/CHANGES.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## Version 3.0
|
4
|
+
|
5
|
+
### `Peer`
|
6
|
+
|
7
|
+
`@queue_name` has been removed. This is replaced by optional argument in
|
8
|
+
`Peer::listen()`.
|
9
|
+
|
10
|
+
`@name` attribute added. Taken from constructor. This is a convenience variable
|
11
|
+
for generic identification. It is not used for anything.
|
12
|
+
|
13
|
+
### `Peer::listen(args={})`:
|
14
|
+
|
15
|
+
No longer creates a new queue by default. It will use the default private
|
16
|
+
queue. If you provide a `queue` argument, then it will create a new queue and
|
17
|
+
keep track of it as a listen queue internally which will be destroyed on
|
18
|
+
`disconnect()`. Also takes an optional `exchange` argument. If provided, it will
|
19
|
+
bind the new queue to that exchange.
|
20
|
+
|
21
|
+
For example say you want to create a service which listens on its private
|
22
|
+
queue. Furthermore you want to receive messages on the default AMQP Fanout
|
23
|
+
queue. Here's a working example:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
#!/usr/bin/env ruby
|
27
|
+
|
28
|
+
require 'haredo/peer'
|
29
|
+
|
30
|
+
$mq_host = 'localhost'
|
31
|
+
$mq_username = 'guest'
|
32
|
+
$mq_password = 'guest'
|
33
|
+
$queue = 'doesntmatter'
|
34
|
+
|
35
|
+
class Service < HareDo::Peer
|
36
|
+
|
37
|
+
def initialize(name)
|
38
|
+
super name
|
39
|
+
connect( :host => $mq_host,
|
40
|
+
:user => $mq_username,
|
41
|
+
:password => $mq_password,
|
42
|
+
:vhost => '' )
|
43
|
+
|
44
|
+
@queue.bind('amq.fanout')
|
45
|
+
end
|
46
|
+
|
47
|
+
def serve(msg)
|
48
|
+
dump_message msg
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
service = Service.new('service')
|
54
|
+
service.listen({:blocking=>false})
|
55
|
+
|
56
|
+
# Client
|
57
|
+
|
58
|
+
client = HareDo::Peer.new()
|
59
|
+
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
60
|
+
|
61
|
+
client.exchange = client.channel.fanout('amq.fanout')
|
62
|
+
client.send($queue, :headers => { :testing => 1 })
|
63
|
+
|
64
|
+
# Cleanup
|
65
|
+
|
66
|
+
client.disconnect()
|
67
|
+
service.disconnect()
|
68
|
+
```
|
data/README.md
CHANGED
@@ -2,8 +2,25 @@
|
|
2
2
|
|
3
3
|
## About
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
I'll bet that most people don't realize that when they use RabbitMQ they are
|
6
|
+
actually using the core software that runs big-freaking telecom systems (OTP --
|
7
|
+
Open Telecom Platform). That in itself is reason enough to consider RabbitMQ.
|
8
|
+
|
9
|
+
But RabbitMQ uses both an elegant but also somewhat elaborate model called AMQP
|
10
|
+
0-9-1. Notice the 0-9-1. This is important. Versions later than this are
|
11
|
+
crap. 0-9-1 is a work of pure genius and art which was later utterly mauled by
|
12
|
+
committees. Fortunately enough for you, RabbitMQ is and most likely always will
|
13
|
+
be AMQP 0-9-1. Hurray!
|
14
|
+
|
15
|
+
But the bottom line is this: You might be one of those pragmatic people that
|
16
|
+
doesn't want to have to know everything about AMQP. You want just want that
|
17
|
+
fancy telecom thing-a-majigger software to pump massive volumes of your messages
|
18
|
+
from one place to another using Ruby and give you 5 9's doing it.
|
19
|
+
|
20
|
+
If that's true for you then you've come to the right place.
|
21
|
+
|
22
|
+
Haredo is an easy-to-use framework for creating peer-to-peer applications in
|
23
|
+
Ruby via [RabbitMQ](http://www.rabbitmq.com/). Built atop the [Bunny AMQP
|
7
24
|
client](http://rubybunny.info/), it uses a small subset of RabbitMQ's
|
8
25
|
capabilities to provide an intuitive client/server framework for implementing
|
9
26
|
network services and simple peer to peer applications. It is specifically
|
@@ -40,6 +57,8 @@ this below).
|
|
40
57
|
```ruby
|
41
58
|
#!/usr/bin/env ruby
|
42
59
|
|
60
|
+
require 'haredo/peer'
|
61
|
+
|
43
62
|
$mq_host = 'localhost'
|
44
63
|
$mq_username = 'guest'
|
45
64
|
$mq_password = 'guest'
|
@@ -53,6 +72,7 @@ class Service < HareDo::Peer
|
|
53
72
|
end
|
54
73
|
|
55
74
|
def serve(msg)
|
75
|
+
#dump_message msg
|
56
76
|
data = msg.headers['i'].to_i + 1
|
57
77
|
reply(msg, :data => data.to_s)
|
58
78
|
end
|
@@ -60,14 +80,14 @@ class Service < HareDo::Peer
|
|
60
80
|
end
|
61
81
|
|
62
82
|
service = Service.new($queue)
|
63
|
-
service.listen(:blocking => false)
|
83
|
+
service.listen(:queue => $queue, :blocking => false)
|
64
84
|
|
65
85
|
client = HareDo::Peer.new()
|
66
86
|
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
67
87
|
|
68
88
|
1.upto(10) do |i|
|
69
|
-
client.send($queue, :headers => { :i => i })
|
70
|
-
msg =
|
89
|
+
id = client.send($queue, :headers => { :i => i })
|
90
|
+
msg = client.receive(id)
|
71
91
|
|
72
92
|
puts msg.data.to_i == i + 1
|
73
93
|
end
|
@@ -134,6 +154,10 @@ class Service < HareDo::Peer
|
|
134
154
|
connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
135
155
|
end
|
136
156
|
|
157
|
+
def listen()
|
158
|
+
super :queue => @name
|
159
|
+
end
|
160
|
+
|
137
161
|
def serve(msg)
|
138
162
|
# Log the message somewhere
|
139
163
|
end
|
@@ -187,13 +211,17 @@ class Service < HareDo::Peer
|
|
187
211
|
connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
188
212
|
end
|
189
213
|
|
214
|
+
def listen()
|
215
|
+
super :queue => @name, :blocking => false
|
216
|
+
end
|
217
|
+
|
190
218
|
def serve(msg)
|
191
219
|
# Log the data somewhere
|
192
220
|
end
|
193
221
|
|
194
222
|
end
|
195
223
|
|
196
|
-
Service.new('logger').listen(
|
224
|
+
Service.new('logger').listen()
|
197
225
|
|
198
226
|
client = HareDo::Peer.new()
|
199
227
|
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
@@ -206,10 +234,13 @@ client.disconnect()
|
|
206
234
|
### Send/Receive
|
207
235
|
|
208
236
|
The send/receive pattern is illustrated in the initial example -- the client
|
209
|
-
sends out ten integers and wait for the response.
|
210
|
-
|
211
|
-
|
212
|
-
|
237
|
+
sends out ten integers and wait for the response. Each time is calls send() it
|
238
|
+
gets a correlation ID as the return value. It passed this ID into receive()
|
239
|
+
which then looks for a return message with that correlation ID. This is how you
|
240
|
+
ensure you get back the message you are looking for (as opposed to some other
|
241
|
+
message that happened to arrive). While the responses come back in the correct
|
242
|
+
order in this example, there is no guarantee that this will happen every
|
243
|
+
time. This is why the correlation ID is important.
|
213
244
|
|
214
245
|
### Remote Procedure Call
|
215
246
|
|
@@ -240,7 +271,7 @@ class Service < HareDo::Peer
|
|
240
271
|
end
|
241
272
|
|
242
273
|
service = Service.new('rpc')
|
243
|
-
service.listen(:blocking => false)
|
274
|
+
service.listen(:queue => service.name, :blocking => false)
|
244
275
|
|
245
276
|
client = HareDo::Peer.new()
|
246
277
|
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
@@ -326,7 +357,7 @@ class Service < HareDo::Peer
|
|
326
357
|
end
|
327
358
|
end
|
328
359
|
|
329
|
-
Service.new('rpc').listen()
|
360
|
+
Service.new('rpc').listen(queue => service.name)
|
330
361
|
service.disconnect()
|
331
362
|
```
|
332
363
|
|
@@ -389,13 +420,15 @@ Now I can implement my service and call it as follows:
|
|
389
420
|
```ruby
|
390
421
|
#!/usr/bin/env ruby
|
391
422
|
|
392
|
-
|
423
|
+
$queue = 'myservice'
|
424
|
+
|
425
|
+
service = HareDo::Peer.new($queue)
|
393
426
|
service.plugins.load('echo')
|
394
|
-
service.listen(:blocking => false)
|
427
|
+
service.listen(queue => service.name, :blocking => false)
|
395
428
|
|
396
429
|
client = HareDo::Peer.new()
|
397
430
|
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
398
|
-
response = @client.call(
|
431
|
+
response = @client.call($queue, headers=>{:uuid=>'echo'}, :data=>'jujifruit')
|
399
432
|
|
400
433
|
client.disconnect()
|
401
434
|
service.disconnect()
|
@@ -453,7 +486,9 @@ For example:
|
|
453
486
|
```ruby
|
454
487
|
#!/usr/bin/env ruby
|
455
488
|
|
456
|
-
|
489
|
+
$queue = 'myservice'
|
490
|
+
|
491
|
+
service = HareDo::Peer.new($queue)
|
457
492
|
|
458
493
|
# Load modules from configuration
|
459
494
|
config = {
|
@@ -463,11 +498,11 @@ config = {
|
|
463
498
|
}
|
464
499
|
|
465
500
|
service.plugins.loadConfig(config)
|
466
|
-
service.listen(:blocking => false)
|
501
|
+
service.listen(:queue => $queue, :blocking => false)
|
467
502
|
|
468
503
|
client = HareDo::Peer.new()
|
469
504
|
client.connect(:user=>$mq_username, :password=>$mq_password, :host=>$mq_host)
|
470
|
-
response = @client.call(
|
505
|
+
response = @client.call($queue, headers=>{:uuid=>'example'}, :data => 'jujifruit')
|
471
506
|
|
472
507
|
service.disconnect()
|
473
508
|
client.disconnect()
|
data/src/lib/haredo/peer.rb
CHANGED
@@ -2,9 +2,14 @@ require 'syslog'
|
|
2
2
|
require 'bunny'
|
3
3
|
require 'haredo/version'
|
4
4
|
|
5
|
-
def dump_message(msg, name)
|
5
|
+
def dump_message(msg, name=nil)
|
6
6
|
puts name if name
|
7
7
|
|
8
|
+
if msg.nil?
|
9
|
+
puts 'Message is nil'
|
10
|
+
return
|
11
|
+
end
|
12
|
+
|
8
13
|
if msg.properties != nil
|
9
14
|
puts ' Headers:'
|
10
15
|
msg.properties.each do |k,v|
|
@@ -157,8 +162,8 @@ end # module Plugins
|
|
157
162
|
|
158
163
|
class Peer
|
159
164
|
|
160
|
-
attr_reader :queue, :plugins, :mid
|
161
|
-
attr_accessor :timeout, :sleep_interval
|
165
|
+
attr_reader :queue, :plugins, :mid, :name
|
166
|
+
attr_accessor :timeout, :sleep_interval, :channel, :exchange
|
162
167
|
attr_accessor :trace
|
163
168
|
|
164
169
|
def initialize(name=nil)
|
@@ -171,16 +176,14 @@ class Peer
|
|
171
176
|
@receive_queue = {}
|
172
177
|
@trace = false
|
173
178
|
|
174
|
-
# Server attributes
|
175
|
-
# The queue name used for listen()
|
176
|
-
@queue_name = name
|
177
|
-
|
178
179
|
@listen_queues = []
|
179
180
|
|
180
181
|
# The number of messages to prefecth from Rabbit
|
181
182
|
@prefetch = 10
|
182
183
|
|
183
184
|
@plugins = Plugins::Manager.new(self)
|
185
|
+
|
186
|
+
@name = name
|
184
187
|
end
|
185
188
|
|
186
189
|
# Connect to RabbitMQ
|
@@ -206,19 +209,38 @@ class Peer
|
|
206
209
|
port = args[:port] || '5672'
|
207
210
|
vhost = args[:vhost] || ''
|
208
211
|
queue_props = args[:queue] || queue_args
|
212
|
+
exchange = args[:exchange] || ''
|
213
|
+
exclusive = args[:exclusive] || true
|
209
214
|
ssl = args[:ssl] || {}
|
210
|
-
tls_cert = ssl['tls_cert'] ||
|
211
|
-
tls_key = ssl['tls_key'] ||
|
212
|
-
tls_ca_certs =
|
215
|
+
tls_cert = ssl['tls_cert'] || nil
|
216
|
+
tls_key = ssl['tls_key'] || nil
|
217
|
+
tls_ca_certs = nil
|
213
218
|
|
219
|
+
if ssl['tls_cert']
|
220
|
+
tls_cert = ssl['tls_cert']
|
221
|
+
end
|
222
|
+
|
223
|
+
if ssl['tls_key']
|
224
|
+
tls_key = ssl['tls_key']
|
225
|
+
end
|
226
|
+
|
227
|
+
if ssl['tls_ca']
|
228
|
+
tls_ca_certs = [ssl['tls_ca']]
|
229
|
+
end
|
230
|
+
|
214
231
|
use_ssl = false
|
215
232
|
if ssl.size > 0 and ssl['enable'] == true
|
216
233
|
use_ssl = true
|
217
234
|
port = ssl['port'] || '5671'
|
218
235
|
end
|
219
236
|
|
237
|
+
if vhost == '/'
|
238
|
+
vhost = ''
|
239
|
+
end
|
240
|
+
|
220
241
|
if use_ssl == true
|
221
242
|
@cnx = Bunny.new( "amqps://#{user}:#{password}@#{host}:#{port}#{vhost}",
|
243
|
+
:log_file => '/dev/null',
|
222
244
|
:tls_cert => tls_cert,
|
223
245
|
:tls_key => tls_key,
|
224
246
|
:tls_ca_certificates => tls_ca_certs)
|
@@ -230,16 +252,18 @@ class Peer
|
|
230
252
|
|
231
253
|
@channel = @cnx.create_channel()
|
232
254
|
|
255
|
+
@channel.prefetch(@prefetch)
|
256
|
+
|
233
257
|
@queue = @channel.queue( '',
|
234
258
|
:auto_delete => true,
|
235
|
-
:exclusive
|
236
|
-
:arguments
|
259
|
+
:exclusive => exclusive,
|
260
|
+
:arguments => queue_props )
|
237
261
|
|
238
262
|
@exchange = @channel.default_exchange()
|
239
263
|
|
240
264
|
return true
|
241
265
|
end
|
242
|
-
|
266
|
+
|
243
267
|
# Disconnect from RabbitMQ
|
244
268
|
def disconnect()
|
245
269
|
|
@@ -407,27 +431,50 @@ class Peer
|
|
407
431
|
|
408
432
|
# Defined the queue this service will listen on. Assumes a single-instance
|
409
433
|
# service therefore declares queue as exclusive.
|
410
|
-
def createQueue()
|
411
|
-
|
434
|
+
def createQueue(args={})
|
435
|
+
|
436
|
+
queue_args = {
|
437
|
+
#'x-expires' => 30000
|
438
|
+
#'x-message-ttl' => 1000
|
439
|
+
}
|
440
|
+
|
441
|
+
queue_name = args[:queue]
|
442
|
+
queue_props = args[:properties] || queue_args
|
443
|
+
auto_delete = args[:auto_delete] || true
|
444
|
+
exclusive = true
|
445
|
+
|
446
|
+
if args.has_key?(:exclusive)
|
447
|
+
exclusive = args[:exclusive]
|
448
|
+
end
|
449
|
+
|
450
|
+
return @channel.queue( queue_name,
|
451
|
+
:auto_delete => true,
|
452
|
+
:exclusive => exclusive )
|
412
453
|
end
|
413
454
|
|
414
455
|
# Causes the service to listen for incoming messages.
|
415
456
|
#
|
416
457
|
# @param :blocking If this is set to true, will go into indefinite blocking
|
417
458
|
# loop processing incoming messages.
|
418
|
-
|
459
|
+
#
|
419
460
|
# @returns Returns nil if non-blocking. Never returns if blocking.
|
420
461
|
|
421
|
-
def listen(args)
|
422
|
-
listen_queue = createQueue()
|
462
|
+
def listen(args={})
|
423
463
|
|
424
|
-
|
464
|
+
queue = @queue
|
425
465
|
|
426
|
-
|
466
|
+
if args.has_key?(:queue)
|
467
|
+
listen_queue = createQueue(args)
|
468
|
+
@listen_queues << listen_queue
|
427
469
|
|
428
|
-
|
470
|
+
if args.has_key?(:exchange)
|
471
|
+
listen_queue.bind(args[:exchange])
|
472
|
+
end
|
429
473
|
|
430
|
-
|
474
|
+
queue = listen_queue
|
475
|
+
end
|
476
|
+
|
477
|
+
block = args[:blocking] || false
|
431
478
|
|
432
479
|
if $syslog.nil?
|
433
480
|
Syslog.open( "haredo #{@name}", Syslog::LOG_PID,
|
@@ -438,7 +485,7 @@ class Peer
|
|
438
485
|
|
439
486
|
Syslog.notice('listen()')
|
440
487
|
|
441
|
-
|
488
|
+
queue.subscribe(:block => block, :manual_ack => true) do |info, props, data|
|
442
489
|
@channel.acknowledge(info.delivery_tag, false)
|
443
490
|
if serve(RabbitMQ::Message.new(info, props, data)) == false
|
444
491
|
exit 0
|
data/src/lib/haredo/plugin.rb
CHANGED
@@ -14,7 +14,7 @@ module Config
|
|
14
14
|
# @return Returns PID of running daemon if it corresponds to a running
|
15
15
|
# process. Returns nil otherwise.
|
16
16
|
def daemonPid()
|
17
|
-
pid = File.open(@pid_file).read().strip.chomp
|
17
|
+
pid = File.open(@pid_file, 'a+').read().strip.chomp
|
18
18
|
|
19
19
|
return nil if pid.size == 0
|
20
20
|
|
@@ -1,18 +1,6 @@
|
|
1
1
|
require 'syslog'
|
2
2
|
require 'haredo/service/config'
|
3
3
|
|
4
|
-
def dump_message(msg)
|
5
|
-
if msg.properties != nil
|
6
|
-
puts ' Headers:'
|
7
|
-
msg.properties.each do |k,v|
|
8
|
-
puts " #{k}: #{v}"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
puts " Data: #{msg.data}"
|
13
|
-
puts
|
14
|
-
end
|
15
|
-
|
16
4
|
module HareDo
|
17
5
|
module Service
|
18
6
|
|
data/src/lib/haredo/version.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Version information. Auto-generated by CMake.
|
2
2
|
module HareDo
|
3
3
|
|
4
|
-
VERSION_MAJ = '
|
4
|
+
VERSION_MAJ = '3'
|
5
5
|
VERSION_MIN = '0'
|
6
6
|
VERSION_CL = ''
|
7
|
-
VERSION_PL = '
|
8
|
-
VERSION = '
|
9
|
-
RELEASE_DATE = 'Wed,
|
7
|
+
VERSION_PL = '2'
|
8
|
+
VERSION = '3.0.2-1'
|
9
|
+
RELEASE_DATE = 'Wed, 01 Aug 2018 17:30:02 -0500'
|
10
10
|
|
11
11
|
end # module HareDo
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haredo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Owens
|
8
8
|
autorequire:
|
9
9
|
bindir: src/bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -31,7 +31,9 @@ executables:
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files:
|
33
33
|
- README.md
|
34
|
+
- CHANGES.md
|
34
35
|
files:
|
36
|
+
- CHANGES.md
|
35
37
|
- README.md
|
36
38
|
- src/bin/haredo
|
37
39
|
- src/lib/haredo/admin/config.rb
|
@@ -65,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
67
|
version: '0'
|
66
68
|
requirements: []
|
67
69
|
rubyforge_project:
|
68
|
-
rubygems_version: 2.
|
70
|
+
rubygems_version: 2.5.2.1
|
69
71
|
signing_key:
|
70
72
|
specification_version: 4
|
71
73
|
summary: A simple client/server framework using RabbitMQ
|