New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR related to #403 / Thread safety, actors #404

Closed
wants to merge 7 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@fwoeck
Copy link

fwoeck commented Apr 16, 2014

This contains the changes for #403 - particularly the use of celluloid to avoid concurrency problems. There remain some issues (3 failing specs under rbx/mri) - I spread FIXME-marks as reminders:

  • exception handling within the vcr actor and signaling to the caller is not always working as intended
  • the to_proc syntax in VCR.use_cassette(name, &req) is not yet supported
  • celluloid raises the ruby requirements to 1.9.2+ - I didn't test the other supported platforms yet (e.g. jruby)

@myronmarston We could discuss/resolve the open questions in a remote session or asynchronously, just as you prefer.

Celluloid.logger = nil
Celluloid.boot


This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Extra blank line detected.

# The main entry point for VCR.
# @note This module is extended onto itself; thus, the methods listed
# here as instance methods are available directly off of VCR.
# @note The main entry point for VCR. This serves as common interface to the singleton

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [86/80]

lib/vcr.rb Outdated
def turned_off(options = {})
turn_off!(options)
def_delegators :vcr_actor,
:current_cassette, :eject_cassette, :insert_cassette, :request_ignorer, :request_matchers,

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [94/80]

lib/vcr.rb Outdated
turn_off!(options)
def_delegators :vcr_actor,
:current_cassette, :eject_cassette, :insert_cassette, :request_ignorer, :request_matchers,
:cassette_persisters, :cassette_serializers, :configuration, :configure, :cucumber_tags,

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [92/80]

lib/vcr.rb Outdated
def_delegators :vcr_actor,
:current_cassette, :eject_cassette, :insert_cassette, :request_ignorer, :request_matchers,
:cassette_persisters, :cassette_serializers, :configuration, :configure, :cucumber_tags,
:use_cassette, :http_interactions, :library_hooks, :record_http_interaction, :turn_off!,

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [92/80]

:current_cassette, :eject_cassette, :insert_cassette, :request_ignorer, :request_matchers,
:cassette_persisters, :cassette_serializers, :configuration, :configure, :cucumber_tags,
:use_cassette, :http_interactions, :library_hooks, :record_http_interaction, :turn_off!,
:turn_on!, :turned_off, :turned_on?, :real_http_connections_allowed?, :cassettes,

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [85/80]

autoload :CucumberTags, 'vcr/test_frameworks/cucumber'
autoload :InternetConnection, 'vcr/util/internet_connection'

module RSpec
autoload :Metadata, 'vcr/test_frameworks/rspec'
autoload :Macros, 'vcr/deprecations'
autoload :Metadata, 'vcr/test_frameworks/rspec'

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Use snake_case for symbols.

autoload :Metadata, 'vcr/test_frameworks/rspec'
autoload :Macros, 'vcr/deprecations'
autoload :Metadata, 'vcr/test_frameworks/rspec'
autoload :Macros, 'vcr/deprecations'

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Use snake_case for symbols.

lib/vcr.rb Outdated
ensure
eject_cassette
end
autoload :Faraday, 'vcr/middleware/faraday'

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Use snake_case for symbols.

lib/vcr.rb Outdated
eject_cassette
end
autoload :Faraday, 'vcr/middleware/faraday'
autoload :Rack, 'vcr/middleware/rack'

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Use snake_case for symbols.


end


This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Extra blank line detected.

# @option options :erb [Boolean, Hash] Whether or not to evaluate the
# cassette as an ERB template. Defaults to false. A hash can be used
# to provide the ERB template with local variables.
# @option options :match_requests_on [Array<Symbol, #call>] List of request matchers

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [86/80]

# to provide the ERB template with local variables.
# @option options :match_requests_on [Array<Symbol, #call>] List of request matchers
# to use to determine what recorded HTTP interaction to replay. Defaults to
# [:method, :uri]. The built-in matchers are :method, :uri, :host, :path, :headers

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [85/80]

# @option options :match_requests_on [Array<Symbol, #call>] List of request matchers
# to use to determine what recorded HTTP interaction to replay. Defaults to
# [:method, :uri]. The built-in matchers are :method, :uri, :host, :path, :headers
# and :body. You can also pass the name of a registered custom request matcher or

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [84/80]

# custom persister.
# @option options :preserve_exact_body_bytes [Boolean] Whether or not
# to base64 encode the bytes of the requests and responses for this cassette
# when serializing it. See also `VCR::Configuration#preserve_exact_body_bytes`.

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [82/80]

def insert_cassette(name, options = {})
if turned_on?
if cassettes.any? { |c| c.name == name }
abort ArgumentError.new("There is already a cassette with the same name (#{name}). You cannot nest multiple cassettes with the same name.")

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [148/80]

cassettes.push(cassette)
cassette
elsif !ignore_cassettes?
message = "VCR is turned off. You must turn it on before you can insert a cassette. " +

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [95/80]
Prefer single-quoted strings when you don't need string interpolation or special symbols.

cassette
elsif !ignore_cassettes?
message = "VCR is turned off. You must turn it on before you can insert a cassette. " +
"Or you can use the `:ignore_cassettes => true` option to completely ignore cassette insertions."

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [113/80]
Prefer single-quoted strings when you don't need string interpolation or special symbols.

unless block
abort ArgumentError.new "`VCR.use_cassette` requires a block. " +
"If you cannot wrap your code in a block, use " +
"`VCR.insert_cassette` / `VCR.eject_cassette` instead."

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [85/80]
Prefer single-quoted strings when you don't need string interpolation or special symbols.

# Turns VCR off, so that it no longer handles every HTTP request.
#
# @param options [Hash] hash of options
# @option options :ignore_cassettes [Boolean] controls what happens when a cassette is

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [88/80]

#
# @param options [Hash] hash of options
# @option options :ignore_cassettes [Boolean] controls what happens when a cassette is
# inserted while VCR is turned off. If `true` is passed, the cassette insertion

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [82/80]

# will be ignored; otherwise a {VCR::Errors::TurnedOffError} will be raised.
#
# @return [void]
# @raise [VCR::Errors::CassetteInUseError] if there is currently a cassette in use

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [84/80]

# @raise [ArgumentError] if you pass an invalid option
def turn_off!(options = {})
if VCR.current_cassette
abort VCR::CassetteInUseError.new "A VCR cassette is currently in use (#{VCR.current_cassette.name}). " +

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [111/80]

def turn_off!(options = {})
if VCR.current_cassette
abort VCR::CassetteInUseError.new "A VCR cassette is currently in use (#{VCR.current_cassette.name}). " +
"You must eject it before you can turn VCR off."

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [88/80]
Prefer single-quoted strings when you don't need string interpolation or special symbols.

@ignore_cassettes = options[:ignore_cassettes]
invalid_options = options.keys - [:ignore_cassettes]
if invalid_options.any?
abort ArgumentError.new("You passed some invalid options: #{invalid_options.inspect}")

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [92/80]

# @see #eject_cassette
def use_cassette(name, options = {}, &block)
unless block
abort ArgumentError.new "`VCR.use_cassette` requires a block. " +

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Prefer single-quoted strings when you don't need string interpolation or special symbols.

def use_cassette(name, options = {}, &block)
unless block
abort ArgumentError.new "`VCR.use_cassette` requires a block. " +
"If you cannot wrap your code in a block, use " +

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Prefer single-quoted strings when you don't need string interpolation or special symbols.

@@ -1,5 +1,19 @@
require 'rubygems'


This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Extra blank line detected.

end
end


This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Extra blank line detected.

@@ -51,6 +71,7 @@ def reset!(hook = :fakeweb)
end
end


This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Extra blank line detected.

@@ -41,6 +41,10 @@ def make_request

it 'records and plays back properly' do
expect { make_request }.to raise_error(Excon::Errors::NotFound)

# FIXME This fails with "There is already a cassette with the same name (with_errors)"

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [92/80]

@@ -41,6 +41,10 @@ def make_request

it 'records and plays back properly' do
expect { make_request }.to raise_error(Excon::Errors::NotFound)

# FIXME This fails with "There is already a cassette with the same name (with_errors)"
# The current cassette is not ejected, because "raise" is used instead of "abort"?

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [94/80]

# FIXME Was it intended to have this line within
# the VCR.use_cassette-block?
#
return body_for(response_1), body_for(response_2)

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Redundant return detected.


VCR.use_cassette("nested") do

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Prefer single-quoted strings when you don't need string interpolation or special symbols.

@@ -38,7 +38,7 @@ def run_after_request_callback
expect(webmock_request.instance_variables.map(&:to_sym)).not_to include(:@__typed_vcr_request)
end

context "when there'ss a bug and the request does not have the @__typed_vcr_request in the after_request callbacks" do
context "when there's a bug and the request does not have the @__typed_vcr_request in the after_request callbacks" do

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [121/80]

@@ -41,7 +41,7 @@ module VCR
end

it 'restores all hooks to being enabled when the block completes, even if there is an error' do
subject.exclusively_enabled(:faraday) { raise "boom" } rescue
subject.exclusively_enabled(:faraday) { raise StandardError.new('boom') } rescue

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [88/80]

@@ -335,7 +348,7 @@ def insert_cassette(name = :cassette_test)
end

it 'passes options through to .turn_off!' do
expect(VCR).to receive(:turn_off!).with(:ignore_cassettes => true)
expect(VCR.wrapped_object).to receive(:turn_off!).with(:ignore_cassettes => true)

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Use the new Ruby 1.9 hash syntax.
Line is too long. [87/80]

@@ -70,13 +75,17 @@ def insert_cassette(name = :cassette_test)
describe '.use_cassette' do
it 'inserts a new cassette' do
new_cassette = VCR::Cassette.new(:use_cassette_test)
expect(VCR).to receive(:insert_cassette).and_return(new_cassette)
expect(VCR.wrapped_object).to receive(:insert_cassette).and_return(new_cassette)

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [86/80]

# https://github.com/celluloid/celluloid/wiki/Blocks
#
expect(VCR.wrapped_object).to receive(:eject_cassette)
expect { VCR.use_cassette(:cassette_test) { raise StandardError.new('Boom!') } }.to raise_error

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [101/80]

end

it 'does not eject a cassette if there was an error inserting it' do
expect(VCR).to receive(:insert_cassette).and_raise(StandardError.new('Boom!'))
expect(VCR).not_to receive(:eject_cassette)
expect(VCR.wrapped_object).to receive(:insert_cassette).and_raise(StandardError.new('Boom!'))

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [99/80]

@@ -234,7 +247,7 @@ def insert_cassette(name = :cassette_test)
end

describe '.record_http_interaction' do
before(:each) { allow(VCR).to receive(:current_cassette).and_return(current_cassette) }
before(:each) { allow(VCR.wrapped_object).to receive(:current_cassette).and_return(current_cassette) }

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [106/80]

@@ -251,13 +264,13 @@ def insert_cassette(name = :cassette_test)
let(:current_cassette) { double('current cassette') }

it 'records the request when it should not be ignored' do
allow(VCR.request_ignorer).to receive(:ignore?).with(interaction.request).and_return(false)
allow(VCR.vcr_actor.request_ignorer).to receive(:ignore?).with(interaction.request).and_return(false)

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [109/80]

expect(current_cassette).to receive(:record_http_interaction).with(interaction)
VCR.record_http_interaction(interaction)
end

it 'does not record the request when it should be ignored' do
allow(VCR.request_ignorer).to receive(:ignore?).with(interaction.request).and_return(true)
allow(VCR.vcr_actor.request_ignorer).to receive(:ignore?).with(interaction.request).and_return(true)

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Line is too long. [108/80]


# FIXME The VcrSupervisor restarts the crashed actor, but this takes
# a while - without sleeping, this spec occasionally fails.
#

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Trailing whitespace detected.


# FIXME The to_proc syntax needs to be re-enabled:
# VCR.use_cassette(:cassette_test, &lambda { yielded = true })
#

This comment has been minimized.

@houndci-bot

houndci-bot Apr 16, 2014

Trailing whitespace detected.

@myronmarston

This comment has been minimized.

Copy link
Member

myronmarston commented Apr 18, 2014

Thanks for opening this...and sorry for the radio silence. Finding time to maintain VCR is hard for me with my responsibilities to RSpec :(.

BTW, ignore the houndci comments. I don't remember enabling that but apparently I did. I just disabled it. It's noise at this point.

celluloid raises the ruby requirements to 1.9.2+ - I didn't test the other supported platforms yet (e.g. jruby)

This is definitely a problem...at least, if we want to release this in a 2.x release. VCR follows SemVer, which means we can't cut a 2.x release that breaks compatibility with 1.8.7. I see two basic paths we can take here:

  • We can decide to bump the major version and call the release that includes this 3.0. I've planned to drop 1.8.7 for 3.0, anyway. There's some other stuff to drop in 3.0 (e.g. fakeweb support, support for typhoeus, 0.4, etc). Beyond the stuff to drop I had never really given much thought to what VCR 3.0 might be, and I'm not sure I'm ready to go there just yet.
  • We can find a way to make celluloid an optional dependency (and maybe even make this entire threadsafety approach an opt-in feature). There are some other reasons why having this opt-in could be beneficial. For example, if your test suite has any places where it kills all non-main threads in order to perform cleanup, that could kill the VCR actor thread, right? I've got some test suites like that where I spin up some threads in some tests and to make sure there's no thread leaks (e.g. if a test fails in mid-stream before joining or whatever) I've got some cleanup code that kills all threads but the main one, and I worry that this celluloid approach may not be compatible with that kind of thing.

I'm kind leaning towards door number 2 personally...what do you think?

I don't have time to look more into this at the moment, sadly...but I do plan to at a later time.

BTW, if you want to discuss this stuff in real time, ping me on IRC. I hang out in the RSpec room on freenode most days.

@fwoeck

This comment has been minimized.

Copy link

fwoeck commented Apr 24, 2014

I think making the celluloid-support optional is perfectly doable. Concerning the thread-cleanup: right, celluloid spawns some household-threads (i.e. for supervision) - so killing threads in between will cause havoc. I'll push some commits that make the celluloid dependency an opt-in during the next days.

@myronmarston

This comment has been minimized.

Copy link
Member

myronmarston commented Apr 24, 2014

Sounds great! Can you close this PR and open a new one with your further changes? The hound comments add so much noise...it'll be easier for me to review on a fresh PR. I've turned off hound so it shouldn't comment again.

@fwoeck

This comment has been minimized.

Copy link

fwoeck commented Apr 24, 2014

Yup, I'll do that!

@fwoeck

This comment has been minimized.

Copy link

fwoeck commented May 7, 2014

Closed in favor of new PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment