Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Remove host splitting from load balancer

  • Loading branch information...
commit dcffe445e246b96be1264485bb3d8a08668cd7e8 1 parent a8691ac
Will Fitzgerald authored
View
2  Gemfile.lock
@@ -41,6 +41,7 @@ GEM
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.8.0)
+ ruby-prof (0.11.2)
typhoeus (0.3.3)
mime-types
vcr (1.11.3)
@@ -56,6 +57,7 @@ DEPENDENCIES
autotest-rails-pure
rake
rspec (~> 2.8.0)
+ ruby-prof
vcr (~> 1.11.3)
webmock (>= 1.6.2)
wordnik!
View
4 lib/wordnik/configuration.rb
@@ -60,6 +60,10 @@ def base_url
)
end
+ def clear
+ initialize
+ end
+
def host
@load_balancer ? @load_balancer.host : @host
end
View
32 lib/wordnik/load_balancer.rb
@@ -16,41 +16,45 @@ class LoadBalancer
attr_reader :hosts
attr_accessor :all_hosts
attr_accessor :failed_hosts_table
+ attr_accessor :current_host
+
def initialize(hosts)
@all_hosts = hosts
@hosts = @all_hosts
@failed_hosts_table = {}
+ @current_host = nil
end
def host
- h = hosts.first
+ @current_host = hosts.first
@hosts.rotate!
restore_failed_hosts_maybe
- h
+ @current_host
end
- def inform_failure(host)
- #Wordnik.logger.debug "Informing failure about #{host}. table: #{@failed_hosts_table.inspect}"
- if @failed_hosts_table.include?(host)
- failures, failed_time = @failed_hosts_table[host]
- @failed_hosts_table[host] = [failures+1, failed_time]
+ def inform_failure
+ #Wordnik.logger.debug "Informing failure about #{@current_host}. table: #{@failed_hosts_table.inspect}"
+ if @failed_hosts_table.include?(@current_host)
+ failures, failed_time = @failed_hosts_table[@current_host]
+ @failed_hosts_table[@current_host] = [failures+1, failed_time]
else
- @failed_hosts_table[host] = [1, Time.now.to_f] # failure count, first failure time
+ @failed_hosts_table[@current_host] = [1, Time.now.to_f] # failure count, first failure time
end
- #Wordnik.logger.debug "Informed failure about #{host}. table now: #{@failed_hosts_table.inspect}"
- @hosts.delete(host)
- @hosts = [host] if @hosts.size == 0 # got to have something!
+ #Wordnik.logger.debug "Informed failure about #{@current_host}. table now: #{@failed_hosts_table.inspect}"
+ @hosts.delete(@current_host)
+ @hosts = [@current_host] if @hosts.size == 0 # got to have something!
end
# success here means just that a successful connection was made
# and the website didn't time out.
- def inform_success(host)
- @failed_hosts_table.delete(host)
- @hosts << host unless @hosts.include? host
+ def inform_success
+ @failed_hosts_table.delete(@current_host)
+ @hosts << @current_host unless @hosts.include? @current_host
@hosts
end
def restore_failed_hosts_maybe
+ return if @failed_hosts_table.size == 0
@failed_hosts_table.each do |host, pair|
failures, failed_time = pair
seconds_since_first_failure = (Time.now.to_f - failed_time)
View
10 lib/wordnik/request.rb
@@ -165,18 +165,16 @@ def make(attempt = 0)
resp = request.response
if Wordnik.configuration.load_balancer
- _,_,host,port,_ = URI::split(u)
- host = "#{host}:#{port}" if port
if (resp.timed_out? || resp.code == 0)
- # Wordnik.logger.debug "informing load balancer about failure at #{host}"
- Wordnik.configuration.load_balancer.inform_failure(host)
+ # Wordnik.logger.debug "informing load balancer about failure"
+ Wordnik.configuration.load_balancer.inform_failure
if (attempt <= 3)
# Wordnik.logger.debug "Trying again after failing #{attempt} times..."
return make(attempt + 1) if attempt <= 3 # try three times to get a result...
end
else
- # Wordnik.logger.debug "informing load balancer about success at #{host}"
- Wordnik.configuration.load_balancer.inform_success(host)
+ # Wordnik.logger.debug "informing load balancer about success"
+ Wordnik.configuration.load_balancer.inform_success
end
end
View
150 spec/performance.rb
@@ -1,18 +1,140 @@
require 'spec_helper'
+require 'ruby-prof'
-describe "Wordnik performance" do
- configure_wordnik
- words = File.open(File.dirname(__FILE__) + "/100words.txt").readlines.map{|w| w.strip}
- start_time = Time.now
- Wordnik.logger.debug "Starting at #{start_time}"
- found = 0
- defs = 0
- examples = 0
- words.each do |word|
- found += 1 if Wordnik.word.get_word(word)["id"]==0
- defs += Wordnik.word.get_definitions(word).size
- examples += Wordnik.word.get_examples(word).size
+describe "Load Balancer Performance" do
+
+ describe "With single host -- host performance" do
+ Wordnik.configuration.clear
+ Wordnik.configure do |config|
+ config.api_key = CREDENTIALS[:api_key]
+ config.username = CREDENTIALS[:username]
+ config.password = CREDENTIALS[:password]
+ config.logger = Logger.new('/dev/null')
+ config.host = CREDENTIALS[:host] = 'api.wordnik.com'
+ config.hosts = []
+ config.base_path = CREDENTIALS[:base_path] || '/v4'
+ end
+ start_time = Time.now
+ RubyProf.start
+ 100000.times {|i| host = Wordnik.configuration.host}
+ result = RubyProf.stop
+ printer = RubyProf::FlatPrinter.new(result)
+ printer.print(STDOUT)
+ end
+
+ describe "With multiple hosts -- host performance" do
+ Wordnik.configuration.clear
+ Wordnik.configure do |config|
+ config.api_key = CREDENTIALS[:api_key]
+ config.username = CREDENTIALS[:username]
+ config.password = CREDENTIALS[:password]
+ config.logger = Logger.new('/dev/null')
+ config.host = CREDENTIALS[:host] = 'api.wordnik.com'
+ config.hosts = CREDENTIALS[:hosts] || ['ec2-50-18-25-12.us-west-1.compute.amazonaws.com',' ec2-50-18-67-92.us-west-1.compute.amazonaws.com']
+ config.base_path = CREDENTIALS[:base_path] || '/v4'
+ end
+ start_time = Time.now
+ RubyProf.start
+ 100000.times {|i| host = Wordnik.configuration.host}
+ result = RubyProf.stop
+ printer = RubyProf::FlatPrinter.new(result)
+ printer.print(STDOUT)
end
- total = Time.now - start_time
- Wordnik.logger.debug "Found #{found} words out of #{words.size}; #{defs} definitions; #{examples} examples in #{total} milliseconds"
+
end
+
+ describe "Wordnik GET performance" do
+
+ describe "With single host" do
+ RubyProf.start
+ Wordnik.configuration.clear
+ Wordnik.configure do |config|
+ config.api_key = CREDENTIALS[:api_key]
+ config.username = CREDENTIALS[:username]
+ config.password = CREDENTIALS[:password]
+ config.logger = Logger.new('/dev/null')
+ config.host = CREDENTIALS[:host] = 'api.wordnik.com'
+ config.hosts = []
+ config.base_path = CREDENTIALS[:base_path] || '/v4'
+ end
+ words = File.open(File.dirname(__FILE__) + "/100words.txt").readlines.map{|w| w.strip}
+ start_time = Time.now
+ Wordnik.logger.debug "Starting at #{start_time}"
+ found = 0
+ defs = 0
+ examples = 0
+ words.each do |word|
+ found += 1 if Wordnik.word.get_word(word)["id"]==0
+ defs += Wordnik.word.get_definitions(word).size
+ examples += Wordnik.word.get_examples(word).size
+ end
+ total = Time.now - start_time
+ result = RubyProf.stop
+ STDOUT.puts "Found #{found} words out of #{words.size}; #{defs} definitions; #{examples} examples in #{total} seconds"
+ printer = RubyProf::FlatPrinter.new(result)
+ printer.print(STDOUT)
+ end
+
+ describe "With two hosts" do
+ RubyProf.start
+ Wordnik.configuration.clear
+ Wordnik.configure do |config|
+ config.api_key = CREDENTIALS[:api_key]
+ config.username = CREDENTIALS[:username]
+ config.password = CREDENTIALS[:password]
+ config.logger = Logger.new('/dev/null')
+ config.host = CREDENTIALS[:host] = 'api.wordnik.com'
+ config.hosts = CREDENTIALS[:hosts] || ['ec2-50-18-25-12.us-west-1.compute.amazonaws.com',' ec2-50-18-67-92.us-west-1.compute.amazonaws.com']
+ config.base_path = CREDENTIALS[:base_path] || '/v4'
+ end
+ words = File.open(File.dirname(__FILE__) + "/100words.txt").readlines.map{|w| w.strip}
+ start_time = Time.now
+ Wordnik.logger.debug "Starting at #{start_time}"
+ found = 0
+ defs = 0
+ examples = 0
+ words.each do |word|
+ found += 1 if Wordnik.word.get_word(word)["id"]==0
+ defs += Wordnik.word.get_definitions(word).size
+ examples += Wordnik.word.get_examples(word).size
+ end
+ total = Time.now - start_time
+ result = RubyProf.stop
+ STDOUT.puts "Found #{found} words out of #{words.size}; #{defs} definitions; #{examples} examples in #{total} seconds"
+ printer = RubyProf::FlatPrinter.new(result)
+ printer.print(STDOUT)
+ end
+
+describe "With three hosts -- one invalid" do
+ RubyProf.start
+ Wordnik.configuration.clear
+ Wordnik.configure do |config|
+ config.api_key = CREDENTIALS[:api_key]
+ config.username = CREDENTIALS[:username]
+ config.password = CREDENTIALS[:password]
+ config.logger = Logger.new('/dev/null')
+ config.host = CREDENTIALS[:host] = 'api.wordnik.com'
+ config.hosts = CREDENTIALS[:hosts] || ['ec2-50-18-25-12.us-west-1.compute.amazonaws.com',
+ 'ec2-50-18-67-92.us-west-1.compute.amazonaws.com',
+ 'localhost']
+ config.base_path = CREDENTIALS[:base_path] || '/v4'
+ end
+ words = File.open(File.dirname(__FILE__) + "/100words.txt").readlines.map{|w| w.strip}
+ start_time = Time.now
+ Wordnik.logger.debug "Starting at #{start_time}"
+ found = 0
+ defs = 0
+ examples = 0
+ words.each do |word|
+ found += 1 if Wordnik.word.get_word(word)["id"]==0
+ defs += Wordnik.word.get_definitions(word).size
+ examples += Wordnik.word.get_examples(word).size
+ end
+ total = Time.now - start_time
+ result = RubyProf.stop
+ STDOUT.puts "Found #{found} words out of #{words.size}; #{defs} definitions; #{examples} examples in #{total} seconds"
+ printer = RubyProf::FlatPrinter.new(result)
+ printer.print(STDOUT)
+ end
+
+ end
View
1  wordnik.gemspec
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'autotest'
s.add_development_dependency 'autotest-rails-pure'
s.add_development_dependency 'rake'
+ s.add_development_dependency 'ruby-prof'
s.files = [
`git ls-files`,
Please sign in to comment.
Something went wrong with that request. Please try again.