pipeline_toolkit 1.2.16 → 1.2.17
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.
- data/README.markdown +21 -8
- data/lib/pipeline_toolkit/amqp/abstract.rb +9 -5
- data/lib/pipeline_toolkit/amqp/reader.rb +3 -1
- data/lib/pipeline_toolkit/cucumber/amqp.rb +8 -0
- data/lib/pipeline_toolkit/cucumber/amqp_steps.rb +5 -0
- data/lib/pipeline_toolkit/cucumber/io_process.rb +4 -0
- data/lib/pipeline_toolkit/cucumber/machine_steps.rb +5 -1
- data/lib/pipeline_toolkit/message_command.rb +14 -6
- data/lib/pipeline_toolkit/message_pusher.rb +10 -1
- data/lib/pipeline_toolkit/message_sink.rb +1 -0
- data/lib/pipeline_toolkit/message_subscriber.rb +14 -3
- data/lib/pipeline_toolkit/monitoring/monitor.erb +1 -1
- metadata +3 -3
data/README.markdown
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
# Pipeline Toolkit #
|
2
2
|
by VisFleet
|
3
3
|
|
4
|
+
|
5
|
+
===============
|
6
|
+
|^^:^^^^:Mw^^^| Pipeline Toolkit
|
7
|
+
| : .:Mw; | By VisFleet
|
8
|
+
\-------------/ (c) 2009
|
9
|
+
|^:^^^^:Mw^^|
|
10
|
+
| : :Mw; |
|
11
|
+
| : :Mw; |
|
12
|
+
| : :Mw; |
|
13
|
+
| : .:Mw; |
|
14
|
+
-------------
|
15
|
+
|
16
|
+
|
4
17
|
Command line tools for processing messages by constructing a pipeline of machines. [AMQP](http://amqp.rubyforge.org/ "AMQP") and Unix pipes are used to construct the pipeline. Messages are simple Hashes (serialized as JSON) so they can hold any values and change throughout the processing.
|
5
18
|
|
6
19
|
Provides:
|
@@ -60,17 +73,17 @@ All gem dependancies are installed automatically, but if you're curious checkout
|
|
60
73
|
|
61
74
|
You can learn more about the command line tools and what options are available by using their help command.
|
62
75
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
76
|
+
> msg_subscriber --help
|
77
|
+
> msg_push --help
|
78
|
+
> msg_sink --help
|
79
|
+
> msg_probe --help
|
67
80
|
|
68
81
|
## Examples ##
|
69
82
|
|
70
83
|
In the example, open two terminal windows and then execute the following commands in each:
|
71
84
|
|
72
|
-
|
73
|
-
|
85
|
+
> msg_generator | msg_push -x test-exchange
|
86
|
+
> msg_subscribe -a false --http-port 9090 -x test-exchange -q test_queue > /dev/null
|
74
87
|
|
75
88
|
The example does the following:
|
76
89
|
|
@@ -83,8 +96,8 @@ The example does the following:
|
|
83
96
|
|
84
97
|
Now lets switch on acknowledgements:
|
85
98
|
|
86
|
-
|
87
|
-
|
99
|
+
> msg_generator | msg_push -x test-exchange
|
100
|
+
> msg_subscribe -x test-exchange -q test_queue | msg_sink
|
88
101
|
|
89
102
|
This example does the same as above, but this time with acknowledgements switched on.
|
90
103
|
This guarantees that a message isn't removed from the message server until handled.
|
@@ -43,13 +43,17 @@ module PipelineToolkit
|
|
43
43
|
def initialize_connection
|
44
44
|
DefaultLogger.debug("Amqp::Abstract#initialize_connection") if options[:env] == "development"
|
45
45
|
@connection = AMQP.connect(options.select_keys(:host, :port, :user, :pass, :vhost))
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
##
|
49
|
+
# Gracefully shuts down the AMQP connection. Calls the given block if provided
|
50
|
+
#
|
51
|
+
def stop_connection
|
52
|
+
# NB: Next tick seems to give it enough time to receieve and send outstanding acks. But I don't
|
53
|
+
# really understand timing, so keep an eye on it.
|
54
|
+
EM.next_tick { @connection.close { yield if block_given? } }
|
51
55
|
end
|
52
|
-
|
56
|
+
|
53
57
|
##
|
54
58
|
# Returns a new channel. A channel is a bidirectional virtual connection between the client
|
55
59
|
# and the AMQP server.
|
@@ -19,7 +19,9 @@ module PipelineToolkit
|
|
19
19
|
@ack_headers ||= {}
|
20
20
|
initialize_connection
|
21
21
|
initialize_channel
|
22
|
-
|
22
|
+
# NB: Used to be 1 to prevent deadlocks. Think deadlocks won't happen anymore (because doing asyn
|
23
|
+
# reads now), but keep an eye on this parameter.
|
24
|
+
@channel.prefetch(25)
|
23
25
|
initialize_exchange
|
24
26
|
initialize_queue
|
25
27
|
bind_queue
|
@@ -3,6 +3,11 @@ Given /^an amqp server running on "(\w+)" at port (\d+)$/ do |host, port|
|
|
3
3
|
@amqp.start(host, port)
|
4
4
|
end
|
5
5
|
|
6
|
+
# Clean up connection after each scenario
|
7
|
+
After do
|
8
|
+
@amqp.close if @amqp && @amqp.connected?
|
9
|
+
end
|
10
|
+
|
6
11
|
Given /^amqp queue "(\w+)" is empty$/ do |queue|
|
7
12
|
@amqp.purge_queue(queue)
|
8
13
|
end
|
@@ -6,7 +6,11 @@ end
|
|
6
6
|
|
7
7
|
# Clean up backround processes after each scenario
|
8
8
|
After do
|
9
|
-
@process.kill
|
9
|
+
@process.kill if @process && @process.running?
|
10
|
+
end
|
11
|
+
|
12
|
+
When /^I kill the machine$/ do
|
13
|
+
@process.kill
|
10
14
|
end
|
11
15
|
|
12
16
|
# Lets you use JSON to express a complex message
|
@@ -61,9 +61,9 @@ module PipelineToolkit
|
|
61
61
|
def start
|
62
62
|
DefaultLogger.debug("MessageCommand#start") if @options[:env] == "development"
|
63
63
|
|
64
|
-
Signal.trap('INT') {
|
65
|
-
Signal.trap('TERM') {
|
66
|
-
Signal.trap('PIPE') {
|
64
|
+
Signal.trap('INT') { self.stop }
|
65
|
+
Signal.trap('TERM') { self.stop }
|
66
|
+
Signal.trap('PIPE') { self.stop }
|
67
67
|
|
68
68
|
begin
|
69
69
|
EM.run do
|
@@ -77,16 +77,23 @@ module PipelineToolkit
|
|
77
77
|
DefaultLogger.error("#{e.class.name}: #{e.message}\n" << e.backtrace.join("\n"))
|
78
78
|
raise e
|
79
79
|
ensure
|
80
|
-
|
80
|
+
cleanup
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
##
|
85
|
-
# Stops the
|
85
|
+
# Stops the command. This stops the event loop, giving it enough time to clear its buffers
|
86
86
|
#
|
87
|
-
def
|
87
|
+
def stop
|
88
88
|
DefaultLogger.info("Shutting down #{self.class.name}")
|
89
89
|
DefaultLogger.info "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
90
|
+
EM.next_tick { EM.stop }
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Cleans up any used resource, such as pipes and files.
|
95
|
+
#
|
96
|
+
def cleanup
|
90
97
|
@ack_pipe.close if @ack_pipe
|
91
98
|
end
|
92
99
|
|
@@ -110,6 +117,7 @@ module PipelineToolkit
|
|
110
117
|
# @param message<Hash> The message to acknowledge
|
111
118
|
#
|
112
119
|
def acknowledge(message)
|
120
|
+
return if message[:ack_id].nil?
|
113
121
|
DefaultLogger.debug("MessageCommand#acknowledge(message)") if options[:env] == "development"
|
114
122
|
ack_message = {:msg_type => "ack", :ack_id => message[:ack_id]}
|
115
123
|
write_to_pipe(ack_message, @ack_pipe)
|
@@ -34,7 +34,16 @@ module PipelineToolkit
|
|
34
34
|
def initialize_machine
|
35
35
|
DefaultLogger.debug("MessagePusher#initialize_machine") if options[:env] == "development"
|
36
36
|
initialize_writer
|
37
|
-
initialize_queues
|
37
|
+
initialize_queues
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Override stop, so that we can close AMQP connection gracefully.
|
42
|
+
#
|
43
|
+
def stop
|
44
|
+
DefaultLogger.info("Shutting down #{self.class.name}")
|
45
|
+
DefaultLogger.info "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
46
|
+
stop_connection { EM.stop }
|
38
47
|
end
|
39
48
|
|
40
49
|
def description
|
@@ -54,6 +54,10 @@ module PipelineToolkit
|
|
54
54
|
begin
|
55
55
|
create_sys_pipe
|
56
56
|
|
57
|
+
Signal.trap('INT') { self.stop }
|
58
|
+
Signal.trap('TERM') { self.stop }
|
59
|
+
Signal.trap('PIPE') { self.stop }
|
60
|
+
|
57
61
|
EM.run do
|
58
62
|
@start_time = Time.now
|
59
63
|
|
@@ -73,16 +77,23 @@ module PipelineToolkit
|
|
73
77
|
DefaultLogger.error "#{e.class.name}: #{e.message}\n" << e.backtrace.join("\n")
|
74
78
|
raise e
|
75
79
|
ensure
|
76
|
-
|
80
|
+
cleanup
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
80
84
|
##
|
81
|
-
#
|
85
|
+
# Stops the command. This stops the event loop, giving it enough time to clear its buffers
|
82
86
|
#
|
83
|
-
def
|
87
|
+
def stop
|
84
88
|
DefaultLogger.info("Shutting down #{self.class.name}")
|
85
89
|
DefaultLogger.info "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
90
|
+
stop_connection { EM.stop }
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Cleans up any used resource, such as pipes and files.
|
95
|
+
#
|
96
|
+
def cleanup
|
86
97
|
destroy_sys_pipe
|
87
98
|
end
|
88
99
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 1.2.
|
8
|
+
- 17
|
9
|
+
version: 1.2.17
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Aisha Fenton
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-31 00:00:00 +12:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|