pipeline_toolkit 1.0.4 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/LICENSE.markdown +20 -0
  2. data/README.markdown +98 -0
  3. data/bin/msg_generator +13 -0
  4. data/bin/msg_probe +13 -0
  5. data/bin/msg_push +13 -0
  6. data/bin/msg_sink +14 -0
  7. data/bin/msg_subscribe +13 -0
  8. data/lib/pipeline_toolkit.rb +17 -0
  9. data/lib/pipeline_toolkit/amqp/abstract.rb +95 -0
  10. data/lib/pipeline_toolkit/amqp/reader.rb +64 -0
  11. data/lib/pipeline_toolkit/amqp/writer.rb +54 -0
  12. data/lib/pipeline_toolkit/commands/msg_generator/cli.rb +45 -0
  13. data/lib/pipeline_toolkit/commands/msg_probe/cli.rb +46 -0
  14. data/lib/pipeline_toolkit/commands/msg_push/cli.rb +58 -0
  15. data/lib/pipeline_toolkit/commands/msg_sink/cli.rb +41 -0
  16. data/lib/pipeline_toolkit/commands/msg_subscribe/cli.rb +58 -0
  17. data/lib/pipeline_toolkit/default_logger.rb +126 -11
  18. data/lib/pipeline_toolkit/handlers/message_handler.rb +38 -0
  19. data/lib/pipeline_toolkit/message_coder.rb +18 -8
  20. data/lib/pipeline_toolkit/message_command.rb +138 -61
  21. data/lib/pipeline_toolkit/message_generator.rb +21 -0
  22. data/lib/pipeline_toolkit/message_probe.rb +6 -6
  23. data/lib/pipeline_toolkit/message_pusher.rb +51 -54
  24. data/lib/pipeline_toolkit/message_sink.rb +1 -1
  25. data/lib/pipeline_toolkit/message_subscriber.rb +182 -201
  26. data/lib/pipeline_toolkit/monitoring/monitor_server.rb +124 -0
  27. data/spec/eventmachine_helper.rb +44 -0
  28. data/spec/message_subscriber_spec.rb +64 -0
  29. data/spec/spec_helper.rb +15 -0
  30. metadata +202 -47
  31. data/.gitignore +0 -5
  32. data/README.rdoc +0 -70
  33. data/Rakefile +0 -40
  34. data/VERSION +0 -1
  35. data/bin/msg_generator.rb +0 -0
  36. data/bin/msg_probe.rb +0 -15
  37. data/bin/msg_push.rb +0 -25
  38. data/bin/msg_sink.rb +0 -11
  39. data/bin/msg_subscribe.rb +0 -27
  40. data/monitor/munin.rb +0 -91
  41. data/pipeline_toolkit.gemspec +0 -72
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.sw?
2
- .DS_Store
3
- coverage
4
- rdoc
5
- pkg
data/README.rdoc DELETED
@@ -1,70 +0,0 @@
1
- = Pipeline Toolkit
2
- by VisFleet
3
-
4
- Command line tools for processing messages by constructing a pipeline of workers. AMQP and Unix pipes are used to construct the pipeline. Messages are simple Hashes (serialized as YAML) so they can hold any values and change throughout the processing.
5
-
6
- Provides:
7
- - Processing acknowledgments, ensuring the a message is only disposed of once it has been successful processed
8
- - Performance. Messages are moved through the pipeline fast
9
- - Command line tools for:
10
- - Subscribing to messages from an AMQP queue
11
- - Pushing messages back onto an AMQP exchange
12
- - Monitoring performance (see msg_probe)
13
- - A base module (MessageCommand) to include into your own classes to quickly make workers.
14
-
15
- == Install
16
-
17
- > sudo gem install pipeline_toolkit
18
-
19
- === Dependancies
20
-
21
- It is assumed that you have:
22
- - An AMQP msg server to pop and push messages to (e.g. http://www.rabbitmq.com/)
23
- - A *nix system, such as Linux or Mac OS X.
24
-
25
- == Usage
26
-
27
- 1. Create your worker
28
-
29
- class MyWorker
30
- include MessageCommand
31
-
32
- def process_message(msg)
33
- # do stuff here
34
- msg
35
- end
36
- end
37
- MyWorker.new.start
38
-
39
- 2. Hook it up to a AMQP message source
40
-
41
- > msg_subscribe.rb -q source | my_worker.rb | msg_push.rb -x dest
42
-
43
- You can learn more about the command line tools and what options are available by using their help command.
44
-
45
- > msg_subscriber --help
46
- > msg_push --help
47
- > msg_sink --help
48
- > msg_probe --help
49
-
50
- == Examples
51
-
52
- Generate a bunch of sample messages and push them to an AMQP exchange 'test-exchange'. Hook up a pipe to consume and push results to /dev/null. Goto http://localhost:9090 to see message throughput.
53
-
54
- > msg_generator.rb | msg_push.rb -x test-exchange
55
- > msg_subscribe.rb --http-port 9090 -x test-exchange -q test_queue > /dev/null
56
-
57
- Same as above, but this time with acknowledgements switched on. This guarantees that a message isn't removed from the message server until handled. msg_sink.rb acknowledges all messages.
58
-
59
- > msg_generator.rb | msg_push.rb -x test-exchange
60
- > msg_subscribe.rb -a -x test-exchange -q test_queue | msg_sink.rb
61
-
62
- == Todo
63
-
64
- - Logging. For the moment we're using SysLogLogger (which requires Syslog). This needs to be switched to the default ruby logging, and we need to find out a way to plug in alternatives if required.
65
-
66
- - DNS-SD is broken. See http://github.com/tenderlove/dnssd/issues#issue/3
67
-
68
- - Decide if we want to support other exchange, queue and binding configurations. For example, exchanges are always fanout and durable at the moment.
69
-
70
-
data/Rakefile DELETED
@@ -1,40 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "pipeline_toolkit"
8
- gem.summary = %Q{Toolkit for building processing pipelines using Unix Pipes and AMQP messages}
9
- gem.email = "labs@visfleet.com"
10
- gem.homepage = "http://github.com/visfleet/pipeline_toolkit"
11
- gem.authors = ["Aisha Fenton"]
12
- gem.executables = ["msg_probe.rb", "msg_subscribe.rb", "msg_push.rb", "msg_sink.rb", "msg_generator.rb"]
13
- gem.add_runtime_dependency('amqp', ">=0.6.5")
14
- gem.add_runtime_dependency('trollop', ">=1.14")
15
- gem.add_runtime_dependency('eventmachine', ">=0.12.10")
16
- gem.add_runtime_dependency('eventmachine_httpserver', ">=0.2.0")
17
- gem.add_runtime_dependency('SyslogLogger', ">=1.4.0")
18
- end
19
- Jeweler::GemcutterTasks.new
20
-
21
- rescue LoadError
22
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
- end
24
-
25
- task :default => :build
26
-
27
- require 'rake/rdoctask'
28
- Rake::RDocTask.new do |rdoc|
29
- if File.exist?('VERSION.yml')
30
- config = YAML.load(File.read('VERSION.yml'))
31
- version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
32
- else
33
- version = ""
34
- end
35
-
36
- rdoc.rdoc_dir = 'rdoc'
37
- rdoc.title = "pipeline_toolkit #{version}"
38
- rdoc.rdoc_files.include('README*')
39
- rdoc.rdoc_files.include('lib/**/*.rb')
40
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.4
data/bin/msg_generator.rb DELETED
File without changes
data/bin/msg_probe.rb DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'trollop'
5
- require 'pipeline_toolkit'
6
-
7
- opts = Trollop::options do
8
- opt :interval, "Time in seconds between updates", :short => "i", :default => 2
9
- opt :http_port, "The port the HTTP server runs on. Default is a random port between 10000-11000", :type => :integer
10
- opt :name, "The name of the probe. Used in monitoring", :type => :string, :short => 'n'
11
- opt :dnssd, "Switches on DNSSD (i.e. Bonjour) for the monitoring interface", :short => 'd'
12
- end
13
-
14
- MessageProbe.new(opts).start
15
-
data/bin/msg_push.rb DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'trollop'
5
- require 'pipeline_toolkit'
6
-
7
- opts = Trollop::options do
8
- opt :exchanges, "The destination exchange(s)", :short => "x", :type => :strings
9
- opt :key_eval, "A string of ruby code that is evaluated to produce a routing key for a given message.
10
- By default each message has no routing key", :short => "e", :type => :string
11
- opt :key_file, "A ruby file that gets included which contains a custom route_key method", :short => "f", :type => :string
12
-
13
- # Msg server
14
- opt :host, "The AMQP message server host", :default => "localhost"
15
- opt :port, "The AMQP message server port", :default => "5672"
16
- opt :user, "The AMQP message server username", :default => "guest"
17
- opt :pass, "The AMQP message server username", :default => "guest"
18
- opt :vhost, "The AMQP message server vhost", :default => "/"
19
- end
20
-
21
- mp = MessagePusher.new(opts)
22
- # FIXME. Should be in MessageCommand class
23
- Signal.trap('INT') { mp.stop }
24
- Signal.trap('TERM'){ mp.stop }
25
- mp.start
data/bin/msg_sink.rb DELETED
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'trollop'
5
- require 'pipeline_toolkit'
6
-
7
- # opts = Trollop::options do
8
- # opt :interval, "Interval", :short => "i", :default => 100
9
- # end
10
-
11
- MessageSink.new.start
data/bin/msg_subscribe.rb DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'trollop'
4
- require 'pipeline_toolkit'
5
-
6
- opts = Trollop::options do
7
- # Monitoring
8
- opt :name, "The name used to describe the entire process chain", :short => "n", :type => :string
9
- opt :http_port, "The port the HTTP monitoring server runs on. Default is a random port between 10000-11000", :type => :integer
10
- opt :dnssd, "Switches on DNSSD (i.e. Bonjour) for the monitoring interface", :short => 'd'
11
-
12
- # Messages
13
- opt :queue, "The source queue", :short => "q", :type => :string, :required => true
14
- opt :ack, "Switch that requires that messages are successfully processed before continuing with the next message", :short => "a"
15
- opt :topic, "The queue topic to subscribe to", :short => "t", :type => :string
16
- opt :max_unackd, "The maximum number of unaknowledged messages to buffer before waiting for them to be acknowledged. Defaults to 100", :default => 100
17
- opt :exchange_bind, "Binds the the queue to the specified exchange. The created exchange is (for now) fanout, durable, and not passive", :short => "x", :type => :string
18
-
19
- # Msg server
20
- opt :host, "The AMQP message server host", :default => "localhost"
21
- opt :port, "The AMQP message server port", :default => "5672"
22
- opt :user, "The AMQP message server username", :default => "guest"
23
- opt :pass, "The AMQP message server username", :default => "guest", :short => "w"
24
- opt :vhost, "The AMQP message server vhost", :default => "/"
25
- end
26
-
27
- ms = MessageSubscriber.new(opts).start
data/monitor/munin.rb DELETED
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'open-uri'
4
- require 'trollop'
5
- require 'nokogiri'
6
-
7
- class MuninPlugin
8
-
9
- def initialize(is_config, opts)
10
- @probe_urls = opts.probe_urls
11
-
12
- self.get_probes
13
-
14
- if is_config
15
- self.config
16
- else
17
- self.data
18
- end
19
- end
20
-
21
- def get_probes
22
- @probes = []
23
- @probe_urls.each_with_index do |url, idx|
24
- @probes << get_probe(url)
25
- end
26
- @probes
27
- end
28
-
29
- def get_probe(url)
30
- probe = Probe.new
31
- doc = Nokogiri::HTML(open(url))
32
- probe.name = extract_mf_value(doc, "name")
33
- probe.mps = extract_mf_value(doc, "mps")
34
- probe.uptime = extract_mf_value(doc, "uptime")
35
- probe
36
- end
37
-
38
- # Extracts the microformat value from the HTML doc
39
- def extract_mf_value(doc, key)
40
- doc.css(".#{key}").first.content
41
- end
42
-
43
- def config
44
- config=<<-EOL
45
- graph_title Message Probe Throughput
46
- graph_vlabel messages per second
47
- graph_category Message Probe
48
- EOL
49
-
50
- @probes.each do |probe|
51
- config << "probe_#{probe.name}.label #{probe.name}\n"
52
- end
53
-
54
- puts config
55
- end
56
-
57
- def data
58
- data = ""
59
- @probes.each do |probe|
60
- data << "#{probe.name}.value #{probe.mps}\n"
61
- end
62
-
63
- puts data
64
- end
65
-
66
- end
67
-
68
- class Probe
69
- attr_accessor :name, :mps, :uptime
70
- end
71
-
72
- SUB_COMMANDS = %w{run config}
73
-
74
- global_opts = Trollop::options do
75
- banner <<-EOS
76
- Munin plugin
77
- Usage:
78
- munin.rb [run|config] [options]
79
-
80
- For more help run
81
- munin.rb [command] --help
82
- EOS
83
- stop_on SUB_COMMANDS
84
- end
85
-
86
- is_config = (ARGV.shift == "config")
87
- opts = Trollop::options do
88
- opt :probe_urls, "The probe's URL", :short => "p", :type => :strings, :default => ["http://127.0.0.1:9070"]
89
- end
90
-
91
- MuninPlugin.new(is_config, opts)
@@ -1,72 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{pipeline_toolkit}
8
- s.version = "1.0.4"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Aisha Fenton"]
12
- s.date = %q{2010-01-15}
13
- s.email = %q{labs@visfleet.com}
14
- s.executables = ["msg_probe.rb", "msg_subscribe.rb", "msg_push.rb", "msg_sink.rb", "msg_generator.rb"]
15
- s.extra_rdoc_files = [
16
- "README.rdoc"
17
- ]
18
- s.files = [
19
- ".gitignore",
20
- "README.rdoc",
21
- "Rakefile",
22
- "VERSION",
23
- "bin/msg_generator.rb",
24
- "bin/msg_probe.rb",
25
- "bin/msg_push.rb",
26
- "bin/msg_sink.rb",
27
- "bin/msg_subscribe.rb",
28
- "lib/pipeline_toolkit.rb",
29
- "lib/pipeline_toolkit/default_logger.rb",
30
- "lib/pipeline_toolkit/message_coder.rb",
31
- "lib/pipeline_toolkit/message_command.rb",
32
- "lib/pipeline_toolkit/message_probe.rb",
33
- "lib/pipeline_toolkit/message_pusher.rb",
34
- "lib/pipeline_toolkit/message_sink.rb",
35
- "lib/pipeline_toolkit/message_subscriber.rb",
36
- "lib/pipeline_toolkit/open_hash.rb",
37
- "lib/pipeline_toolkit/socket_util.rb",
38
- "monitor/munin.rb",
39
- "pipeline_toolkit.gemspec"
40
- ]
41
- s.homepage = %q{http://github.com/visfleet/pipeline_toolkit}
42
- s.rdoc_options = ["--charset=UTF-8"]
43
- s.require_paths = ["lib"]
44
- s.rubygems_version = %q{1.3.5}
45
- s.summary = %q{Toolkit for building processing pipelines using Unix Pipes and AMQP messages}
46
-
47
- if s.respond_to? :specification_version then
48
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
- s.specification_version = 3
50
-
51
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
- s.add_runtime_dependency(%q<amqp>, [">= 0.6.5"])
53
- s.add_runtime_dependency(%q<trollop>, [">= 1.14"])
54
- s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
55
- s.add_runtime_dependency(%q<eventmachine_httpserver>, [">= 0.2.0"])
56
- s.add_runtime_dependency(%q<SyslogLogger>, [">= 1.4.0"])
57
- else
58
- s.add_dependency(%q<amqp>, [">= 0.6.5"])
59
- s.add_dependency(%q<trollop>, [">= 1.14"])
60
- s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
61
- s.add_dependency(%q<eventmachine_httpserver>, [">= 0.2.0"])
62
- s.add_dependency(%q<SyslogLogger>, [">= 1.4.0"])
63
- end
64
- else
65
- s.add_dependency(%q<amqp>, [">= 0.6.5"])
66
- s.add_dependency(%q<trollop>, [">= 1.14"])
67
- s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
68
- s.add_dependency(%q<eventmachine_httpserver>, [">= 0.2.0"])
69
- s.add_dependency(%q<SyslogLogger>, [">= 1.4.0"])
70
- end
71
- end
72
-