Skip to content

Instantly share code, notes, and snippets.

@mfazekas
Last active April 19, 2016 15:33
Show Gist options
  • Save mfazekas/ccf9bee10dc4fe23f39d1da1b914993b to your computer and use it in GitHub Desktop.
Save mfazekas/ccf9bee10dc4fe23f39d1da1b914993b to your computer and use it in GitHub Desktop.
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', github: 'rails/rails'
gem 'pg'
gem 'byebug'
end
require 'action_controller/railtie'
require 'active_record/railtie'
require 'active_record'
ActiveRecord::Base.logger = Logger.new(STDOUT)
class TestApp < Rails::Application
config.root = File.dirname(__FILE__)
config.session_store :cookie_store, key: 'cookie_store_key'
secrets.secret_token = 'secret_token'
secrets.secret_key_base = 'secret_key_base'
config.logger = Logger.new($stdout)
Rails.logger = config.logger
end
class Post < ActiveRecord::Base
has_many :comments
end
class PostsController < ActionController::Base
include Rails.application.routes.url_helpers
def index
conn = ActiveRecord::Base.connection
puts "[main] PID in req: #{conn.instance_variable_get("@connection").backend_pid}"
Post.create!
render plain: 'Home'
end
end
TestApp.configure do
config.eager_load = true
def config.database_configuration
{'development' => {'adapter' => 'postgresql', 'pool' => 4, 'host' => 'localhost', 'username' => ENV["USER"], 'database' => "test_tran_deadlock"}}
end
end
TestApp.initialize!
TestApp.routes.draw do
resources :posts
end
ActiveRecord::Tasks::DatabaseTasks.create_current
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
end
end
require 'minitest/autorun'
require 'rack/test'
class BugTest < Minitest::Test
include Rack::Test::Methods
def test_deadlock
q,r = Queue.new,Queue.new
Post.create!
ActiveRecord::Base.transaction do
Post.destroy_all
puts "[main] pid: #{ActiveRecord::Base.connection.instance_variable_get("@connection").backend_pid}"
get '/posts'
# db connection placed back to pool with open transaction
assert last_response.ok?
# start a new thread grabing connection
th = Thread.new do
conn = ActiveRecord::Base.connection
q.push true
puts "[thread] PID: #{conn.instance_variable_get("@connection").backend_pid}"
r.pop
end
q.pop
# grab connection again
puts "[main] PID: #{ActiveRecord::Base.connection.instance_variable_get("@connection").backend_pid}"
r.push true
Post.destroy_all
th.join
end
end
private
def app
Rails.application
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment