From 2665f2a5b8db14b472dec070c1d94f78c44fa499 Mon Sep 17 00:00:00 2001 From: denniskuczynski Date: Sun, 4 Nov 2012 14:21:04 -0500 Subject: [PATCH] Final cleanups/refactorings for the 1.1.0 Release --- Gemfile | 2 + Gemfile.lock | 2 +- README.md | 10 +-- Rakefile | 10 +-- beanstalkd_view.gemspec | 2 +- config.ru | 2 +- lib/beanstalkd_view/Gemfile | 4 -- lib/beanstalkd_view/Rakefile | 1 - lib/beanstalkd_view/beanstalkd_utils.rb | 66 +++++++++++++++++- lib/beanstalkd_view/server.rb | 91 +++++-------------------- lib/beanstalkd_view/views/index.erb | 21 +++++- spec/spec_helper.rb | 14 +++- 12 files changed, 126 insertions(+), 99 deletions(-) delete mode 100644 lib/beanstalkd_view/Gemfile delete mode 100644 lib/beanstalkd_view/Rakefile diff --git a/Gemfile b/Gemfile index 0f0779a..b57420f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,7 @@ source "http://rubygems.org" +#gem 'beaneater', :git => 'https://github.com/beanstalkd/beaneater.git' + # Specify your gem's dependencies in beanstalkd_view.gemspec gemspec diff --git a/Gemfile.lock b/Gemfile.lock index bc491d8..e6efa84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: beanstalkd_view (1.1.0) - beaneater (>= 0.1.0) + beaneater (~> 0.1.0) json sinatra (>= 1.3.0) sinatra-assetpack (>= 0.0.11) diff --git a/README.md b/README.md index 7a4d551..d2672d1 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Use the following environment variable to specify the location of the beanstalk ENV['BEANSTALK_URL'] = 'beanstalk://localhost/' ``` -(This can be a comma separated list.) +This can be a comma separated list, e.g. 'beanstalk://localhost:11300,beanstalk://localhost:11400' Embedding in a Rails app ------------------------ @@ -62,7 +62,10 @@ bundle exec beanstalkd_view (This will use the vegas gem to launch the Sinatra app on an available port.) -Alternatively, a Rackup file is provided. To use: cd into the beanstalkd_view directory and execute the rackup command. +Alternatively, a Rackup file is provided. To use: cd into the beanstalkd_view directory and execute: + +rackup + Screenshot ------------------------ @@ -73,8 +76,7 @@ Running the tests There are 3 variants of RSpec tests. * Without beanstalkd running, just execute: rspec spec * Without 1 instance of beanstalkd running (default port), execute: rspec spec --tag requires_beanstalkd -* Without 2 instances of beanstalkd running (ports 12300 and 12400), execute: rspec spec --tag requires_two_beanstalkd - (Also, you must uncomment the modified BEANSTALK_URL setting in spec_helper.rb for requires_two_beanstalk tests.) +* Without 2 instances of beanstalkd running (ports 11300 and 11400), execute: rspec spec --tag requires_two_beanstalkd License ------------------------ diff --git a/Rakefile b/Rakefile index 6a1cc3f..adb3b4e 100644 --- a/Rakefile +++ b/Rakefile @@ -44,10 +44,12 @@ namespace :beanstalkd_view do while true tube_name = TEST_QUEUES.sample begin - tube = beanstalk.tubes[tube_name] - job = tube.reserve - puts "Pulled Job #{job} from #{tube_name}" - job.delete + beanstalk.tubes.watch!(tube_name) + job = beanstalk.tubes.reserve(1) + if job + puts "Pulled Job #{job} from #{tube_name}" + job.delete + end rescue Exception => ex puts "Exception while pulling job from #{tube_name}: #{ex}" end diff --git a/beanstalkd_view.gemspec b/beanstalkd_view.gemspec index 53f0dc4..655ff46 100644 --- a/beanstalkd_view.gemspec +++ b/beanstalkd_view.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.add_dependency "sinatra", ">= 1.3.0" s.add_dependency "sinatra-contrib", ">= 1.3.0" s.add_dependency "sinatra-assetpack", ">= 0.0.11" - s.add_dependency "beaneater", ">= 0.1.0" + s.add_dependency "beaneater", "~> 0.1.0" s.add_dependency "vegas", "~> 0.1.2" s.add_dependency "json" diff --git a/config.ru b/config.ru index 0d31b64..1930c2f 100644 --- a/config.ru +++ b/config.ru @@ -1,7 +1,7 @@ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') ENV['BEANSTALK_URL'] ||= 'beanstalk://localhost/' -#ENV['BEANSTALK_URL'] = 'beanstalk://localhost:12300,beanstalk://localhost:12400' +#ENV['BEANSTALK_URL'] ||= 'beanstalk://localhost:11300,beanstalk://localhost:11400' # config.ru require 'beanstalkd_view' diff --git a/lib/beanstalkd_view/Gemfile b/lib/beanstalkd_view/Gemfile deleted file mode 100644 index 2111dff..0000000 --- a/lib/beanstalkd_view/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "http://rubygems.org" - -# Specify your gem's dependencies in beanstalkd_view.gemspec -gemspec diff --git a/lib/beanstalkd_view/Rakefile b/lib/beanstalkd_view/Rakefile deleted file mode 100644 index 13a79ed..0000000 --- a/lib/beanstalkd_view/Rakefile +++ /dev/null @@ -1 +0,0 @@ -require "bundler/gem_tasks" \ No newline at end of file diff --git a/lib/beanstalkd_view/beanstalkd_utils.rb b/lib/beanstalkd_view/beanstalkd_utils.rb index e4e96f2..3826f4c 100644 --- a/lib/beanstalkd_view/beanstalkd_utils.rb +++ b/lib/beanstalkd_view/beanstalkd_utils.rb @@ -2,6 +2,8 @@ module BeanstalkdView module BeanstalkdUtils + GUESS_PEEK_RANGE = 100 # Default number of elements to use in peek-range guesses + class BadURL < RuntimeError; end def beanstalk @@ -13,8 +15,6 @@ def beanstalk_url ENV['BEANSTALK_URL'] || 'beanstalk://localhost/' end - class BadURL < RuntimeError; end - def beanstalk_addresses uris = beanstalk_url.split(/[\s,]+/) uris.map {|uri| beanstalk_host_and_port(uri)} @@ -25,5 +25,67 @@ def beanstalk_host_and_port(uri_string) raise(BadURL, uri_string) if uri.scheme != 'beanstalk' "#{uri.host}:#{uri.port || 11300}" end + + # Convert Beaneater::Job to hash + def job_to_hash(job) + ret_value = {} + job_stats = job.stats + job_stats.keys.each { |key| ret_value[key] = job_stats[key] } + ret_value['body'] = job.body.inspect + ret_value + end + + # Return the stats data in a format for the Bluff JS UI Charts + def get_chart_data_hash(tubes) + chart_data = {} + chart_data["total_jobs_data"] = Hash.new + chart_data["buried_jobs_data"] = Hash.new + chart_data["total_jobs_data"]["items"] = Array.new + chart_data["buried_jobs_data"]["items"] = Array.new + tubes.each do |tube| + stats = tube.stats + #total_jobs + total_jobs = stats[:total_jobs] + if total_jobs > 0 + total_datum = {} + total_datum["label"] = tube.name + total_datum["data"] = total_jobs + chart_data["total_jobs_data"]["items"] << total_datum + end + #buried_jobs + buried_jobs = stats[:current_jobs_buried] + if buried_jobs > 0 + buried_datum = {} + buried_datum["label"] = tube.name + buried_datum["data"] = buried_jobs + chart_data["buried_jobs_data"]["items"] << buried_datum + end + end + chart_data + end + + # Pick a Minimum Peek Range Based on minumum ready jobs on all tubes + def guess_min_peek_range(tubes) + min = 0 + tubes.each do |tube| + response = tube.peek('ready') + if response + if min == 0 + min = response.id.to_i + else + min = [min, response.id.to_i].min + end + end + end + # Add some jitter in the opposite direction of 1/4 range + jitter_min = (min-(GUESS_PEEK_RANGE*0.25)).to_i + [1, jitter_min].max + end + + # Pick a Minimum Peek Range Based on the minimum + def guess_max_peek_range(min) + (min+GUESS_PEEK_RANGE)-1 + end + end end \ No newline at end of file diff --git a/lib/beanstalkd_view/server.rb b/lib/beanstalkd_view/server.rb index 10d4882..24a98d6 100644 --- a/lib/beanstalkd_view/server.rb +++ b/lib/beanstalkd_view/server.rb @@ -30,18 +30,17 @@ class Server < Sinatra::Base '/css/vendor/bootstrap.min.css', '/css/app.css'] end - - GUESS_PEEK_RANGE = 100 # Default number of elements to use in peek-range guesses - + get "/" do begin + @connections = beanstalk.connections @tubes = beanstalk.tubes.all @stats = beanstalk.stats chart_data = get_chart_data_hash(@tubes) @total_jobs_data = chart_data["total_jobs_data"] @buried_jobs_data = chart_data["buried_jobs_data"] if chart_data["buried_jobs_data"]["items"].size > 0 erb :index - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -59,7 +58,7 @@ class Server < Sinatra::Base cookies[:beanstalkd_view_notice] = "Error adding job" redirect url("/") end - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -69,7 +68,7 @@ class Server < Sinatra::Base @tube = beanstalk.tubes[params[:tube]] @stats = @tube.stats erb :tube_stats - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -84,7 +83,7 @@ class Server < Sinatra::Base else { :error => "No job was found, or an error occurred while trying to peek at the next job."}.to_json end - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error { :error => @error.to_s }.to_json end end @@ -111,14 +110,16 @@ class Server < Sinatra::Base @jobs = [] for i in min..max begin - job = beanstalk.jobs.find(i) - @jobs << job_to_hash(job) if job + jobs = beanstalk.jobs.find_all(i) + jobs.each do |job| + @jobs << job_to_hash(job) + end rescue Beaneater::NotFoundError => e # Since we're looping over potentially non-existant jobs, ignore end end erb :peek_range - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -135,7 +136,7 @@ class Server < Sinatra::Base cookies[:beanstalkd_view_notice] = "Error deleting Job #{params[:job_id]}" redirect url("/tube/#{params[:tube]}") end - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -151,7 +152,7 @@ class Server < Sinatra::Base cookies[:beanstalkd_view_notice] = "Error pausing #{params[:tube]}." redirect url("/tube/#{params[:tube]}") end - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -168,7 +169,7 @@ class Server < Sinatra::Base cookies[:beanstalkd_view_notice] = "Error kicking #{params[:tube]}." redirect url("/tube/#{params[:tube]}") end - rescue Beaneater::NotConnected => @error + rescue Beaneater::NotConnected, Beaneater::NotFoundError => @error erb :error end end @@ -178,6 +179,8 @@ def url_path(*path_parts) end alias_method :u, :url_path + private + def path_prefix request.env['SCRIPT_NAME'] end @@ -187,68 +190,6 @@ def notice_message cookies[:beanstalkd_view_notice] = '' message end - - private - - def job_to_hash(job) - ret_value = {} - job_stats = job.stats - job_stats.keys.each { |key| ret_value[key] = job_stats[key] } - ret_value['body'] = job.body.inspect - ret_value - end - - # Return the stats data in a format for the Bluff JS UI Charts - def get_chart_data_hash(tubes) - chart_data = {} - chart_data["total_jobs_data"] = Hash.new - chart_data["buried_jobs_data"] = Hash.new - chart_data["total_jobs_data"]["items"] = Array.new - chart_data["buried_jobs_data"]["items"] = Array.new - tubes.each do |tube| - stats = tube.stats - #total_jobs - total_jobs = stats[:total_jobs] - if total_jobs > 0 - total_datum = {} - total_datum["label"] = tube.name - total_datum["data"] = total_jobs - chart_data["total_jobs_data"]["items"] << total_datum - end - #buried_jobs - buried_jobs = stats[:current_jobs_buried] - if buried_jobs > 0 - buried_datum = {} - buried_datum["label"] = tube.name - buried_datum["data"] = buried_jobs - chart_data["buried_jobs_data"]["items"] << buried_datum - end - end - chart_data - end - - # Pick a Minimum Peek Range Based on calls to peek_ready - def guess_min_peek_range(tubes) - min = 0 - tubes.each do |tube| - response = tube.peek('ready') - if response - if min == 0 - min = response.id.to_i - else - min = [min, response.id.to_i].min - end - end - end - # Add some jitter in the opposite direction of 1/4 range - jitter_min = (min-(GUESS_PEEK_RANGE*0.25)).to_i - [1, jitter_min].max - end - # Pick a Minimum Peek Range Based on the minimum - def guess_max_peek_range(min) - (min+GUESS_PEEK_RANGE)-1 - end - end end \ No newline at end of file diff --git a/lib/beanstalkd_view/views/index.erb b/lib/beanstalkd_view/views/index.erb index b905e6f..4ecc643 100644 --- a/lib/beanstalkd_view/views/index.erb +++ b/lib/beanstalkd_view/views/index.erb @@ -2,6 +2,21 @@

Overview

+ + + + + + + + <% @connections.each do |connection| %> + + + + <% end %> + +
Connections
<%= connection.address %>
+ @@ -9,12 +24,12 @@ - <% @tubes.each do |tube| %> + <% @tubes.each do |tube| %> - <% end %> - + <% end %> +
"><%= tube.name %>
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e5d41d7..ff88378 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,9 +7,6 @@ require "rails_helper" -# Uncomment for requires_two_beanstalkd test -#ENV['BEANSTALK_URL'] = 'beanstalk://localhost:12300,beanstalk://localhost:12400' - # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[File.dirname(__FILE__)+"/support/**/*.rb"].each do |f| @@ -21,5 +18,16 @@ RSpec.configure do |config| config.treat_symbols_as_metadata_keys_with_true_values = true config.filter_run_excluding :requires_beanstalkd, :requires_two_beanstalkd + + config.before(:each) do + requires_two_beanstalkd = example.options[:requires_two_beanstalkd] + if requires_two_beanstalkd + ENV['BEANSTALK_URL'] = 'beanstalk://localhost:11300,beanstalk://localhost:11400' + else + ENV['BEANSTALK_URL'] = 'beanstalk://localhost:11300' + end + end end + +