Skip to content

Instantly share code, notes, and snippets.

@sbull
Created February 26, 2015 03:40
Show Gist options
  • Save sbull/e83defaa7c6a93950866 to your computer and use it in GitHub Desktop.
Save sbull/e83defaa7c6a93950866 to your computer and use it in GitHub Desktop.
Rails Mounted Engine url_helpers workaround for thread bug undefined method `url_options' for #<Module:0x007fb64b864d50>
$ rails runner route_helpers_debug.rb
Threads: 10, Iterations per thread: 10
Running Mounted Engine dummy_path...
4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/4/-/2/-/3/-/8/-/6/-/1/-/9/-/7/-/0/-/2/-/3/-/4/-/8/-/1/-/9/-/7/-/0/-/
Finished thread 0.
Finished thread 1.
Finished thread 2.
Finished thread 3.
Finished thread 4.
6/-/
Finished thread 6.
Finished thread 7.
Finished thread 8.
Finished thread 9.
-------
ERRORS: 1
Exception in thread 5, iteration 0: undefined method `url_options' for #<Module:0x007fb64b864d50>
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:271:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:222:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:334:in `block (2 levels) in define_url_helper'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/mapper.rb:637:in `block (2 levels) in define_generate_prefix'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:775:in `url_for'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:279:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:222:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/routing/route_set.rb:334:in `block (2 levels) in define_url_helper'
route_helpers_debug.rb:77:in `block in method_missing'
route_helpers_debug.rb:76:in `synchronize'
route_helpers_debug.rb:76:in `method_missing'
route_helpers_debug.rb:48:in `engine_test'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/abstract_controller/base.rb:198:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/rendering.rb:10:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:234:in `block in halting'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `block in halting'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `block in halting'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:234:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:234:in `block in halting'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `call'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `_run_callbacks'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:734:in `_run_process_action_callbacks'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:81:in `run_callbacks'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/abstract_controller/callbacks.rb:19:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/rescue.rb:29:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `block in instrument'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/notifications.rb:164:in `instrument'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/abstract_controller/base.rb:137:in `process'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionview-4.2.0/lib/action_view/rendering.rb:30:in `process'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal.rb:195:in `dispatch'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
/home/steven/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_controller/metal.rb:236:in `block in action'
route_helpers_debug.rb:93:in `call'
route_helpers_debug.rb:93:in `block in <top (required)>'
route_helpers_debug.rb:15:in `call'
route_helpers_debug.rb:15:in `block (3 levels) in run_threads'
route_helpers_debug.rb:13:in `times'
route_helpers_debug.rb:13:in `block (2 levels) in run_threads'
-------
ERRORS: 1
# via "rails runner"
NUM_THREADS = (ARGV[0] || 10).to_i
NUM_ITERATIONS = (ARGV[1] || NUM_THREADS).to_i
puts "Threads: #{NUM_THREADS}, Iterations per thread: #{NUM_ITERATIONS}"
def run_threads(&block)
threads = []
NUM_THREADS.times do |thread_num|
threads << Thread.new(thread_num) do |num|
Thread.current.thread_variable_set('num', num)
NUM_ITERATIONS.times do |i|
Thread.current.thread_variable_set('iter', i)
print num.to_s + block.call.to_s
end
end
end
errors = []
threads.each do |thr|
begin
thr.join
print "\nFinished thread #{thr.thread_variable_get('num')}.\n"
rescue => e
errors << "\nException in thread #{thr.thread_variable_get('num')}, iteration #{thr.thread_variable_get('iter')}: #{e.message}\n"+e.backtrace.map{|bt| "\t#{bt}\n" }.join
end
end
puts "\n-------\nERRORS: #{errors.length}"
puts errors
puts "\n-------\nERRORS: #{errors.length}"
end
class TestEngine < Rails::Engine; end
TestEngine.routes.draw do
get '/' => 'dummy#index', as: :dummy
end
Rails.application.routes.draw do
mount TestEngine, at: '-', as: 'test_routes'
end
class TestController < ActionController::Base
def engine_test
render plain: RouteHelper.one.dummy_path
end
end
ROUTES_MUTEX = Mutex.new
class RouteHelper
class UrlHelpers
include TestEngine.routes.url_helpers
end
def self.one
@@one
end
def self.one=(one)
@@one = one
end
def self.url_helpers=(url_helpers)
@@url_helpers = url_helpers
end
def method_missing(symbol, *args)
ROUTES_MUTEX.synchronize {
@@url_helpers.send(symbol, *args)
}
end
end
RouteHelper.one = RouteHelper.new
RouteHelper.url_helpers = RouteHelper::UrlHelpers.new
Rails.logger.level = 2
puts "Running Mounted Engine dummy_path..."
run_threads do
env = { 'REQUEST_METHOD' => 'GET', 'rack.input' => StringIO.new }
status, headers, rack_body = TestController.action('engine_test').call(env)
rack_body.body
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment