super-poller 0.1.1 → 0.1.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.
@@ -0,0 +1,17 @@
1
+ require "super_poller"
2
+ queue = SuperPoller::QueueUrl.parse(ARGV.shift).to_queue
3
+
4
+ memo = {:memo => Time.now.to_f}
5
+ queue.push(memo)
6
+
7
+ SuperPoller::NoneBlockingPoller.new(queue, lambda{|msg|
8
+ skip = false
9
+ begin
10
+ exit if msg == memo
11
+ p msg
12
+ print "Kill? > "
13
+ skip = gets =~ /^[Yy]/
14
+ ensure
15
+ queue.push(msg) unless skip or msg == memo
16
+ end
17
+ }).start!
@@ -0,0 +1,4 @@
1
+ require "super_poller"
2
+ in_queue, out_queue = [nil,nil].map{|url| SuperPoller::QueueUrl.parse(ARGV.shift).to_queue }
3
+
4
+ SuperPoller::QueueItterator.new(in_queue).each(&out_queue.method(:push))
@@ -0,0 +1,3 @@
1
+ require "super_poller"
2
+ queue = SuperPoller::QueueUrl.parse(ARGV.shift).to_queue
3
+ SuperPoller::NoneBlockingPoller.new(queue, lambda{|msg| }).start!
@@ -0,0 +1,51 @@
1
+ require "super_poller"
2
+ require 'optparse'
3
+
4
+ options = {}
5
+ opts = OptionParser.new do |opts|
6
+ opts.banner = "Usage queue grep QUEUE_URL [options]"
7
+ opts.on("-f STRING", "--ruby-filter STRING", "Set ruby filter") do |v|
8
+ options[:ruby_filter] = v
9
+ end
10
+
11
+ opts.on("-a STRING", "--ruby-action STRING", "Set ruby action") do |v|
12
+ options[:ruby_action] = v
13
+ end
14
+
15
+ opts.on("-d", "--delete", "Delete all matches") do |v|
16
+ options[:ruby_action] = ":delete"
17
+ end
18
+
19
+ opts.on("-c QUEUE", "--copy QUEUE", "Copy all matches") do |v|
20
+ options[:ruby_action] = "SuperPoller::QueueUrl.parse(#{v.to_s.inspect}).to_queue.push(msg)"
21
+ end
22
+
23
+ opts.on("-m QUEUE", "--move QUEUE", "Move all matches") do |v|
24
+ options[:ruby_action] = "SuperPoller::QueueUrl.parse(#{v.to_s.inspect}).to_queue.push(msg); :delete"
25
+ end
26
+
27
+ opts.on("-t TYPE", "--message-type TYPE", "Select messages of a given type") do |v|
28
+ options[:ruby_filter] = "#{v.to_s.inspect} == msg[:name].to_s rescue false"
29
+ end
30
+
31
+ opts.on_tail("-h", "--help", "Show this message") do
32
+ puts opts
33
+ exit 1
34
+ end
35
+ end
36
+
37
+ opts.parse!
38
+
39
+ unless queue_url = ARGV.shift
40
+ puts opts
41
+ exit 1
42
+ end
43
+
44
+ queue = SuperPoller::QueueUrl.parse(queue_url).to_queue
45
+
46
+ eval "def matcher_matches?(msg); #{ options[:ruby_filter] || "true" }; end"
47
+ eval "def action(msg); #{ options[:ruby_action] || "p msg" }; end"
48
+
49
+ SuperPoller::QueueItterator.new(queue).each do |msg|
50
+ action(msg) if matcher_matches? msg
51
+ end
@@ -0,0 +1,13 @@
1
+ require "super_poller"
2
+ queue_one = SuperPoller::QueueUrl.parse(ARGV.shift).to_queue
3
+ queue_two = SuperPoller::QueueUrl.parse(ARGV.shift).to_queue
4
+
5
+ SuperPoller::QueueItterator.new(queue_one).each do |msg|
6
+ p msg
7
+ print "Move to #{queue_two}? > "
8
+
9
+ if gets =~ /^[Yy]/
10
+ queue_two.push(msg)
11
+ :delete
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require "super_poller"
2
+ in_queue, out_queue = [nil,nil].map{|url| SuperPoller::QueueUrl.parse(ARGV.shift).to_queue }
3
+
4
+ SuperPoller::NoneBlockingPoller.new(in_queue, out_queue.method(:push)).start!
@@ -0,0 +1,3 @@
1
+ require "super_poller"
2
+ queue = SuperPoller::QueueUrl.parse(ARGV.shift).to_queue
3
+ SuperPoller::QueueItterator.new(queue).each(&method(:p))
@@ -0,0 +1,33 @@
1
+ class SuperPoller::AggregatingErrorLogger
2
+ def initialize(stats_file, queue)
3
+ @stats_file, @queue = stats_file, queue
4
+ end
5
+
6
+ def call(error, failed_message)
7
+ update_error_queue(error, failed_message)
8
+ update_error_stats(error, failed_message[:name] || :unknown)
9
+ end
10
+
11
+ protected
12
+ def update_error_queue(error, failed_message)
13
+ error_class_name = error.class.name.to_sym
14
+ error_description = {:class => error_class_name, :message => error.message}
15
+ @queue.push(failed_message.merge(:error => error_description))
16
+ end
17
+
18
+ def update_error_stats(error, message_name)
19
+ stats = load_stats
20
+ error_class_name = error.class.name.to_sym
21
+ stats_for_name = (stats[message_name] ||= {})
22
+ stats_for_name[error_class_name] ||= 0
23
+ stats_for_name[error_class_name] += 1
24
+
25
+ File.open(@stats_file, "w") do |file|
26
+ file << YAML.dump(stats)
27
+ end
28
+ end
29
+
30
+ def load_stats
31
+ File.exists?(@stats_file) && YAML.load(File.read(@stats_file)) || {}
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ class SuperPoller::BufferedHandler < SuperPoller::Handler
2
+ class << self
3
+ def buffer_size(size)
4
+ @max_buffer_size = size
5
+ end
6
+
7
+ def max_buffer_size
8
+ @max_buffer_size || []
9
+ end
10
+ end
11
+
12
+ def initialize
13
+ @buffer = []
14
+ end
15
+
16
+ def call(msg)
17
+ @buffer.push msg
18
+ if @buffer.size >= self.class.max_buffer_size
19
+ handle_batch @buffer
20
+ @buffer = []
21
+ end
22
+ end
23
+
24
+ def handle_batch(batch)
25
+ raise NotImplementedError, "You must define a batch handler."
26
+ end
27
+
28
+ end
@@ -0,0 +1,12 @@
1
+ class SuperPoller::ErrorReporter
2
+ def initialize(message_handler, error_handler = nil, &block)
3
+ @message_handler = message_handler
4
+ @error_handler = error_handler || block
5
+ end
6
+
7
+ def call(*args)
8
+ @message_handler.call(*args)
9
+ rescue StandardError => e
10
+ @error_handler.call(e, *args)
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ class SuperPoller::Handler
2
+ autoload :TestCase, "super_poller/test_case"
3
+
4
+ class << self
5
+ def handles(*new_message_names)
6
+ @message_names = (message_names + new_message_names).uniq
7
+ end
8
+
9
+ def message_names
10
+ @message_names || []
11
+ end
12
+ end
13
+
14
+ def can_handle?(message)
15
+ self.class.message_names.include? message[:name].to_sym
16
+ end
17
+
18
+ def call(message)
19
+ raise NotImplementedError, "You must define a call handler."
20
+ end
21
+
22
+ end
@@ -0,0 +1,13 @@
1
+ class SuperPoller::NoneBlockingPoller < SuperPoller::Poller
2
+ EmptyQueue = Class.new(Exception)
3
+
4
+ def start!
5
+ super
6
+ rescue EmptyQueue
7
+ end
8
+
9
+ protected
10
+ def get_message
11
+ @queue.fetch or raise EmptyQueue
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ class SuperPoller::Poller
2
+ def initialize(queue, message_handler)
3
+ @message_handler, @queue = message_handler, queue
4
+ end
5
+
6
+ def poll
7
+ @message_handler.call(get_message)
8
+ end
9
+
10
+ def start!
11
+ poll while true
12
+ end
13
+
14
+ protected
15
+ def get_message
16
+ @queue.pop
17
+ rescue Interrupt
18
+ raise
19
+ rescue Object => e
20
+ STDERR.puts "Error while fetching from the queue: #{e.class}: #{e.message}"
21
+ sleep 10
22
+ retry
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ class SuperPoller::QueueItterator
2
+ def initialize(queue)
3
+ @queue = queue
4
+ end
5
+
6
+ def each(&block)
7
+ @memo = {:memo => Time.now.to_f}
8
+ @queue.push @memo
9
+ while @memo
10
+ begin
11
+ break unless msg = @queue.fetch
12
+ if msg == @memo
13
+ msg = @memo = nil
14
+ else
15
+ msg = nil if :delete == block.call(msg)
16
+ end
17
+ ensure
18
+ @queue.push msg if msg
19
+ end
20
+ end
21
+ ensure
22
+ destroy_the_memo
23
+ end
24
+
25
+ def destroy_the_memo
26
+ while @memo and msg = @queue.fetch and msg != @memo
27
+ @queue.push(msg)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require "uri"
2
+
3
+ class SuperPoller::QueueUrl < URI::Generic
4
+ def self.parse(url)
5
+ url = "starling://localhost:22122/#{url}" if url =~ /^[a-zA-Z0-9_-]+$/
6
+ new(*URI.parse(url).send(:component_ary))
7
+ end
8
+
9
+ def to_queue
10
+ raise URI::InvalidURIError unless respond_to? "to_#{scheme}_queue"
11
+ send("to_#{scheme}_queue")
12
+ end
13
+
14
+ protected
15
+ def to_starling_queue
16
+ SuperPoller::StarlingQueue.new(path, "#{host}:#{port}")
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ class SuperPoller::Router
2
+ RoutingError = Class.new(Exception)
3
+
4
+ def initialize()
5
+ @handlers = []
6
+ end
7
+
8
+ def add_handler(handler)
9
+ @handlers.push handler
10
+ @handlers.uniq!
11
+ self
12
+ end
13
+
14
+ alias << add_handler
15
+
16
+ def call(message)
17
+ handler = best_handler_for_message(message)
18
+ handler.call(message[:body])
19
+ end
20
+
21
+ protected
22
+
23
+ def best_handler_for_message(messsage)
24
+ @handlers.each do |handler|
25
+ return handler if handler.can_handle? messsage
26
+ end
27
+ raise RoutingError, "No handler found"
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require "starling"
2
+
3
+ class SuperPoller::StarlingQueue
4
+ def initialize(queue_name, *args)
5
+ @queue_name = queue_name.to_s
6
+ @queue = Starling.new(*args)
7
+ end
8
+
9
+ def pop
10
+ @queue.get(@queue_name)
11
+ end
12
+
13
+ def push(v)
14
+ @queue.set(@queue_name, v)
15
+ end
16
+
17
+ def fetch
18
+ @queue.fetch(@queue_name)
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ class SuperPoller::Handler::TestCase < (defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase)
2
+
3
+ def handler
4
+ @handler ||= self.class.name.gsub(/Test$/, "").constantize.new
5
+ end
6
+
7
+ def self.should_handle(name)
8
+ should "handle a #{name.inspect} message" do
9
+ assert handler.can_handle?(:name => name)
10
+ end
11
+ end
12
+
13
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 1
9
- version: 0.1.1
8
+ - 2
9
+ version: 0.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tom Lea
@@ -29,6 +29,24 @@ extra_rdoc_files: []
29
29
 
30
30
  files:
31
31
  - bin/queue
32
+ - bin/scripts/queue_choose
33
+ - bin/scripts/queue_copy
34
+ - bin/scripts/queue_flush
35
+ - bin/scripts/queue_grep
36
+ - bin/scripts/queue_interactive_move
37
+ - bin/scripts/queue_move
38
+ - bin/scripts/queue_scan
39
+ - lib/super_poller/aggregating_error_logger.rb
40
+ - lib/super_poller/buffered_handler.rb
41
+ - lib/super_poller/error_reporter.rb
42
+ - lib/super_poller/handler.rb
43
+ - lib/super_poller/none_blocking_poller.rb
44
+ - lib/super_poller/poller.rb
45
+ - lib/super_poller/queue_itterator.rb
46
+ - lib/super_poller/queue_url.rb
47
+ - lib/super_poller/router.rb
48
+ - lib/super_poller/starling_queue.rb
49
+ - lib/super_poller/test_case.rb
32
50
  - lib/super_poller.rb
33
51
  - test/aggregating_error_logger_test.rb
34
52
  - test/buffered_handler_test.rb