Skip to content

Commit

Permalink
Delay memoization, stubbing, before to run.
Browse files Browse the repository at this point in the history
  • Loading branch information
hanshasselberg committed Nov 18, 2012
1 parent 6515503 commit d78ed2a
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 70 deletions.
4 changes: 3 additions & 1 deletion lib/typhoeus/hydra.rb
@@ -1,3 +1,4 @@
require 'typhoeus/hydra/addable'
require 'typhoeus/hydra/before'
require 'typhoeus/hydra/block_connection'
require 'typhoeus/hydra/easy_factory'
Expand Down Expand Up @@ -40,12 +41,13 @@ module Typhoeus
# execution.
class Hydra
include Hydra::EasyPool
include Hydra::Queueable
include Hydra::Addable
include Hydra::Runnable
include Hydra::Memoizable
include Hydra::BlockConnection
include Hydra::Stubbable
include Hydra::Before
include Hydra::Queueable

# @example Set max_concurrency.
# Typhoeus::Hydra.new(max_concurrency: 20)
Expand Down
23 changes: 23 additions & 0 deletions lib/typhoeus/hydra/addable.rb
@@ -0,0 +1,23 @@
module Typhoeus
class Hydra

# This module handles the request adding on
# hydra.
#
# @api private
module Addable

# Adds request to multi.
#
# @example Add request.
# hydra.add(request)
#
# @param [ Typhoeus::Request ] request to add.
#
# @return [ void ]
def add(request)
multi.add(Hydra::EasyFactory.new(request, self).get)
end
end
end
end
8 changes: 4 additions & 4 deletions lib/typhoeus/hydra/before.rb
Expand Up @@ -9,14 +9,14 @@ class Hydra
# @api private
module Before

# Overrride queue in order to execute callbacks in
# Overrride add in order to execute callbacks in
# Typhoeus.before. Will break and return when a
# callback returns nil or false. Calls super
# otherwise.
#
# @example Queue the request.
# hydra.queue(request)
def queue(request)
# @example Add the request.
# hydra.add(request)
def add(request)
Typhoeus.before.each do |callback|
value = callback.call(request)
if value.nil? || value == false || value.is_a?(Response)
Expand Down
8 changes: 4 additions & 4 deletions lib/typhoeus/hydra/block_connection.rb
Expand Up @@ -15,15 +15,15 @@ class Hydra
# @api private
module BlockConnection

# Overrides queue in order to check before if block connection
# Overrides add in order to check before if block connection
# is turned on. If thats the case a NoStub error is
# raised.
#
# @example Queue the request.
# hydra.queue(request)
# @example Add the request.
# hydra.add(request)
#
# @param [ Request ] request The request to enqueue.
def queue(request)
def add(request)
if request.blocked?
raise Typhoeus::Errors::NoStub.new(request)
else
Expand Down
2 changes: 1 addition & 1 deletion lib/typhoeus/hydra/easy_factory.rb
Expand Up @@ -70,7 +70,7 @@ def set_callback
easy.on_complete do |easy|
request.finish(Response.new(easy.to_hash))
hydra.release_easy(easy)
hydra.queue(hydra.queued_requests.shift) unless hydra.queued_requests.empty?
hydra.add(hydra.queued_requests.shift) unless hydra.queued_requests.empty?
end
end
end
Expand Down
12 changes: 6 additions & 6 deletions lib/typhoeus/hydra/memoizable.rb
Expand Up @@ -21,18 +21,18 @@ def memory
@memory ||= {}
end

# Overrides queue in order to check before if request
# Overrides add in order to check before if request
# is memoizable and already in memory. If thats the case,
# super is not called, instead the response is set and
# the on_complete callback called.
#
# @example Queue the request.
# hydra.queue(request)
# @example Add the request.
# hydra.add(request)
#
# @param [ Request ] request The request to enqueue.
# @param [ Request ] request The request to add.
#
# @return [ Request ] The queued request.
def queue(request)
# @return [ Request ] The added request.
def add(request)
if request.memoizable? && memory.has_key?(request)
response = memory[request]
request.finish(response, true)
Expand Down
6 changes: 1 addition & 5 deletions lib/typhoeus/hydra/queueable.rb
Expand Up @@ -37,11 +37,7 @@ def abort
# hydra.queue(request)
def queue(request)
request.hydra = self
if multi.easy_handles.size < max_concurrency
multi.add(Hydra::EasyFactory.new(request, self).get)
else
queued_requests << request
end
queued_requests << request
end
end
end
Expand Down
5 changes: 3 additions & 2 deletions lib/typhoeus/hydra/runnable.rb
Expand Up @@ -2,8 +2,6 @@ module Typhoeus
class Hydra

# This module contains logic to run a hydra.
#
# @api private
module Runnable

# Start the hydra run.
Expand All @@ -13,6 +11,9 @@ module Runnable
#
# @return [ Symbol ] Return value from multi.perform.
def run
queued_requests.pop(max_concurrency).map do |request|
add(request)
end
multi.perform
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/typhoeus/hydra/stubbable.rb
Expand Up @@ -8,13 +8,13 @@ class Hydra
# @api private
module Stubbable

# Override queue in order to check for matching expecations.
# Override add in order to check for matching expecations.
# When an expecation is found, super is not called. Instead a
# canned response is assigned to the request.
#
# @example Queue the request.
# hydra.queue(request)
def queue(request)
# @example Add the request.
# hydra.add(request)
def add(request)
if expectation = Expectation.find_by(request)
request.finish(expectation.response)
else
Expand Down
22 changes: 22 additions & 0 deletions spec/typhoeus/hydra/addable_spec.rb
@@ -0,0 +1,22 @@
require 'spec_helper'

describe Typhoeus::Hydra::Addable do
let(:hydra) { Typhoeus::Hydra.new() }
let(:request) { Typhoeus::Request.new("localhost:3001", {:method => :get}) }

it "asks easy factory for an easy" do
multi = stub
Typhoeus::Hydra::EasyFactory.should_receive(:new).with(request, hydra).and_return(stub(:get => 1))
hydra.should_receive(:multi).and_return(multi)
multi.should_receive(:add).with(1)
hydra.add(request)
end

it "adds easy to multi" do
multi = stub
Typhoeus::Hydra::EasyFactory.should_receive(:new).with(request, hydra).and_return(stub(:get => 1))
hydra.should_receive(:multi).and_return(multi)
multi.should_receive(:add).with(1)
hydra.add(request)
end
end
20 changes: 10 additions & 10 deletions spec/typhoeus/hydra/before_spec.rb
Expand Up @@ -6,36 +6,36 @@

after { Typhoeus.before.clear }

describe "#queue" do
describe "#add" do
context "when before" do
context "when one" do
it "executes" do
Typhoeus.before { |r| String.new(r.url) }
String.should_receive(:new).and_return("")
hydra.queue(request)
hydra.add(request)
end

context "when true" do
it "calls super" do
Typhoeus.before { true }
Typhoeus::Expectation.should_receive(:find_by)
hydra.queue(request)
hydra.add(request)
end
end

context "when false" do
it "doesn't call super" do
Typhoeus.before { false }
Typhoeus::Expectation.should_receive(:find_by).never
hydra.queue(request)
hydra.add(request)
end
end

context "when response" do
it "doesn't call super" do
Typhoeus.before { Typhoeus::Response.new }
Typhoeus::Expectation.should_receive(:find_by).never
hydra.queue(request)
hydra.add(request)
end
end
end
Expand All @@ -46,12 +46,12 @@

it "calls super" do
Typhoeus::Expectation.should_receive(:find_by)
hydra.queue(request)
hydra.add(request)
end

it "executes all" do
String.should_receive(:new).exactly(3).times.and_return("")
hydra.queue(request)
hydra.add(request)
end
end

Expand All @@ -64,12 +64,12 @@

it "doesn't call super" do
Typhoeus::Expectation.should_receive(:find_by).never
hydra.queue(request)
hydra.add(request)
end

it "executes only two" do
String.should_receive(:new).exactly(2).times.and_return("")
hydra.queue(request)
hydra.add(request)
end
end
end
Expand All @@ -78,7 +78,7 @@
context "when no before" do
it "calls super" do
Typhoeus::Expectation.should_receive(:find_by)
hydra.queue(request)
hydra.add(request)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/typhoeus/hydra/block_connection_spec.rb
Expand Up @@ -5,13 +5,13 @@
let(:hydra) { Typhoeus::Hydra.new() }
let(:request) { Typhoeus::Request.new(url, {:method => :get}) }

describe "queue" do
describe "add" do
context "when block_connection activated" do
before { Typhoeus::Config.block_connection = true }
after { Typhoeus::Config.block_connection = false }

it "raises" do
expect{ hydra.queue(request) }.to raise_error(Typhoeus::Errors::NoStub)
expect{ hydra.add(request) }.to raise_error(Typhoeus::Errors::NoStub)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/typhoeus/hydra/easy_factory_spec.rb
Expand Up @@ -32,11 +32,11 @@
expect(easy_factory.hydra.easy_pool).to include(easy_factory.easy)
end

it "queues next request" do
it "adds next request" do
easy_factory.hydra.instance_variable_set(:@queued_requests, [request])
easy_factory.hydra.should_receive(:add).with(request)
easy_factory.send(:set_callback)
easy_factory.easy.complete
expect(easy_factory.hydra.queued_requests).to include(request)
end
end
end
8 changes: 4 additions & 4 deletions spec/typhoeus/hydra/memoizable_spec.rb
Expand Up @@ -5,20 +5,20 @@
let(:hydra) { Typhoeus::Hydra.new() }
let(:request) { Typhoeus::Request.new(url, {:method => :get}) }

describe "queue" do
describe "add" do
context "when memoization activated" do
before { Typhoeus::Config.memoize = true }
after { Typhoeus::Config.memoize = false }

context "when request new" do
it "sets no response" do
hydra.queue(request)
hydra.add(request)
expect(request.response).to be_nil
end

it "doesn't call complete" do
request.should_receive(:complete).never
hydra.queue(request)
hydra.add(request)
end
end

Expand All @@ -28,7 +28,7 @@

it "finishes request" do
request.should_receive(:finish).with(response, true)
hydra.queue(request)
hydra.add(request)
end
end
end
Expand Down
24 changes: 3 additions & 21 deletions spec/typhoeus/hydra/queueable_spec.rb
Expand Up @@ -17,27 +17,9 @@
expect(request.hydra).to eq(hydra)
end

context "when max concurrency limit not reached" do
let(:options) { { :max_concurrency => 10 } }

it "adds to multi" do
hydra.multi.should_receive(:add)
hydra.queue(request)
end
end

context "when max concurrency limit reached" do
let(:options) { { :max_concurrency => 0 } }

it "doesn't add to multi" do
hydra.multi.should_receive(:add).never
hydra.queue(request)
end

it "adds to queued requests" do
hydra.queue(request)
expect(hydra.queued_requests).to include(request)
end
it "adds to queued requests" do
hydra.queue(request)
expect(hydra.queued_requests).to include(request)
end
end

Expand Down
12 changes: 12 additions & 0 deletions spec/typhoeus/hydra/runnable_spec.rb
Expand Up @@ -23,6 +23,11 @@
let(:first) { Typhoeus::Request.new("localhost:3001/first") }
let(:requests) { [first] }

it "adds request from queue to multi" do
hydra.should_receive(:add).with(first)
hydra.run
end

it "runs multi#perform" do
hydra.multi.should_receive(:perform)
hydra.run
Expand All @@ -40,6 +45,13 @@
let(:third) { Typhoeus::Request.new("localhost:3001/third") }
let(:requests) { [first, second, third] }

it "adds requests from queue to multi" do
hydra.should_receive(:add).with(first)
hydra.should_receive(:add).with(second)
hydra.should_receive(:add).with(third)
hydra.run
end

it "runs multi#perform" do
hydra.multi.should_receive(:perform)
hydra.run
Expand Down

0 comments on commit d78ed2a

Please sign in to comment.