Skip to content

Commit

Permalink
Patch PostgreSQLAdapter in Rails 3.1.0 and 3.1.1 to fix a reconnectio…
Browse files Browse the repository at this point in the history
…n issue.
  • Loading branch information
ileitch committed Oct 9, 2011
1 parent c87e8a3 commit d2385fe
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 17 deletions.
30 changes: 16 additions & 14 deletions lib/rapns/daemon.rb
Expand Up @@ -2,17 +2,19 @@
require 'socket' require 'socket'
require 'pathname' require 'pathname'


require "rapns/daemon/configuration" require 'rapns/daemon/configuration'
require "rapns/daemon/certificate" require 'rapns/daemon/certificate'
require "rapns/daemon/delivery_error" require 'rapns/daemon/delivery_error'
require "rapns/daemon/pool" require 'rapns/daemon/pool'
require "rapns/daemon/connection_pool" require 'rapns/daemon/connection_pool'
require "rapns/daemon/connection" require 'rapns/daemon/connection'
require "rapns/daemon/delivery_queue" require 'rapns/daemon/delivery_queue'
require "rapns/daemon/delivery_handler" require 'rapns/daemon/delivery_handler'
require "rapns/daemon/delivery_handler_pool" require 'rapns/daemon/delivery_handler_pool'
require "rapns/daemon/feeder" require 'rapns/daemon/feeder'
require "rapns/daemon/logger" require 'rapns/daemon/logger'

require 'rapns/daemon/patches'


module Rapns module Rapns
module Daemon module Daemon
Expand All @@ -26,7 +28,7 @@ def self.start(environment, foreground)
@foreground = foreground @foreground = foreground
setup_signal_hooks setup_signal_hooks


self.configuration = Configuration.new(environment, File.join(Rails.root, "config", "rapns", "rapns.yml")) self.configuration = Configuration.new(environment, File.join(Rails.root, 'config', 'rapns', 'rapns.yml'))
configuration.load configuration.load


self.logger = Logger.new(:foreground => foreground, :airbrake_notify => configuration.airbrake_notify) self.logger = Logger.new(:foreground => foreground, :airbrake_notify => configuration.airbrake_notify)
Expand Down Expand Up @@ -57,7 +59,7 @@ def self.start(environment, foreground)
def self.setup_signal_hooks def self.setup_signal_hooks
@shutting_down = false @shutting_down = false


["SIGINT", "SIGTERM"].each do |signal| ['SIGINT', 'SIGTERM'].each do |signal|
Signal.trap(signal) do Signal.trap(signal) do
handle_shutdown_signal handle_shutdown_signal
end end
Expand Down Expand Up @@ -93,7 +95,7 @@ def self.daemonize


def self.write_pid_file def self.write_pid_file
if !configuration.pid_file.blank? if !configuration.pid_file.blank?
File.open(configuration.pid_file, "w") do |f| File.open(configuration.pid_file, 'w') do |f|
f.puts $$ f.puts $$
end end
end end
Expand Down
4 changes: 2 additions & 2 deletions lib/rapns/daemon/feeder.rb
Expand Up @@ -23,9 +23,7 @@ def self.enqueue_notifications
Rapns::Daemon.delivery_queue.wait_until_empty Rapns::Daemon.delivery_queue.wait_until_empty
rescue ActiveRecord::StatementInvalid, *ADAPTER_ERRORS => e rescue ActiveRecord::StatementInvalid, *ADAPTER_ERRORS => e
Rapns::Daemon.logger.error(e) Rapns::Daemon.logger.error(e)
Rapns::Daemon.logger.warn('Lost connection to database, reconnecting...')
reconnect reconnect
Rapns::Daemon.logger.warn('Database reconnected.')
rescue StandardError => e rescue StandardError => e
Rapns::Daemon.logger.error(e) Rapns::Daemon.logger.error(e)
end end
Expand All @@ -38,6 +36,7 @@ def self.stop
end end


def self.reconnect def self.reconnect
Rapns::Daemon.logger.warn('Lost connection to database, reconnecting...')
attempts = 0 attempts = 0
loop do loop do
begin begin
Expand All @@ -51,6 +50,7 @@ def self.reconnect
sleep 2 # Avoid thrashing. sleep 2 # Avoid thrashing.
end end
end end
Rapns::Daemon.logger.warn('Database reconnected.')
end end
end end
end end
Expand Down
6 changes: 6 additions & 0 deletions lib/rapns/daemon/patches.rb
@@ -0,0 +1,6 @@
if defined?(Rails) && ActiveRecord::Base.configurations[Rails.env]['adapter'] == 'postgresql'
if Rails::VERSION::STRING == '3.1.0' || Rails::VERSION::STRING == '3.1.1'
STDERR.puts '[WARNING] Patched PostgreSQLAdapter to fix reconnection bug: https://github.com/rails/rails/issues/3160.'
require "rapns/daemon/patches/rails/#{Rails::VERSION::STRING}/postgresql_adapter.rb"
end
end
12 changes: 12 additions & 0 deletions lib/rapns/daemon/patches/rails/3.1.0/postgresql_adapter.rb
@@ -0,0 +1,12 @@
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter < AbstractAdapter
def clear_cache!
@statements.each_value do |value|
@connection.query "DEALLOCATE #{value}" if active?
end
@statements.clear
end
end
end
end
17 changes: 17 additions & 0 deletions lib/rapns/daemon/patches/rails/3.1.1/postgresql_adapter.rb
@@ -0,0 +1,17 @@
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter < AbstractAdapter
class StatementPool < ConnectionAdapters::StatementPool
def dealloc(key)
@connection.query "DEALLOCATE #{key}" if connection_active?
end

def connection_active?
@connection.status == PGconn::CONNECTION_OK
rescue PGError
false
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Expand Up @@ -20,7 +20,7 @@


CreateRapnsNotifications.down rescue ActiveRecord::StatementInvalid CreateRapnsNotifications.down rescue ActiveRecord::StatementInvalid
CreateRapnsNotifications.up CreateRapnsNotifications.up
module Rails; end
Bundler.require(:default) Bundler.require(:default)


require 'shoulda' require 'shoulda'
Expand Down

0 comments on commit d2385fe

Please sign in to comment.