Postgres: prepared statement already exists
I am using Devise to authenticate to a Rails API application. Sometimes I see the following error in the logs:
ActiveRecord :: StatementInvalid: PGError: ERROR: A prepared statement "a3926" already exists: UPDATE "users" SET "current_sign_in_at" = $ 1, "last_sign_in_at" = $ 2, "sign_in_count" = $ 3, "updated_at" = $ 4 WHERE "users". "id" = 12345
The error comes from Devise:
def update_tracked_fields!(request)
old_current, new_current = self.current_sign_in_at, Time.now.utc
self.last_sign_in_at = old_current || new_current
self.current_sign_in_at = new_current
old_current, new_current = self.current_sign_in_ip, request.remote_ip
self.last_sign_in_ip = old_current || new_current
self.current_sign_in_ip = new_current
self.sign_in_count ||= 0
self.sign_in_count += 1
# error happens below
save(validate: false) or raise "Devise trackable could not save #{inspect}." \
"Please make sure a model using trackable can be saved at sign in."
end
As I understand it, this error usually occurs when there is something wrong with the way the database connections are used. Is there something I should be looking for?
+3
source to share
1 answer
If you are using a server that deploys your process (like a unicorn), you need to create a connection for each forked process.
In the case of a unicorn, add this:
#config/unicorn.rb
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection(
Rails.application.config.database_configuration[Rails.env]
)
end
+1
source to share