[Rt-commit] rt branch, 4.2/shared-db-connections, created. rt-4.2.14-8-gaf28651
Alex Vandiver
alexmv at bestpractical.com
Mon Nov 13 00:01:53 EST 2017
The branch, 4.2/shared-db-connections has been created
at af286514cd68b0485dc7611ba848269195cb1da1 (commit)
- Log -----------------------------------------------------------------
commit af286514cd68b0485dc7611ba848269195cb1da1
Author: Alex Vandiver <alex at chmrr.net>
Date: Tue Nov 7 21:30:14 2017 -0500
Add a critical error if DB connections are shared across the fork
rt-server takes pains to close down the database connection before
handing off control to the PSGI server, such that the database
connection is not preserved across the `fork`. DB connections which
are so shared result in undefined behavior -- postgres, for instance,
will reuse the same statement ids on the handle in different
processes, resulting in errors of the form:
DBD::Pg::st execute failed: ERROR: prepared statement "dbdpg_p4068_1" already exists
However, nothing prevents extensions from recreating the DB connection
during their `to_app` methods -- RT::Extension::REST2-1.00 erroneously
does so, for instance.
While we could force-unset the connections, this would serve as a
continuation of the mostly-silent error. Instead, add an explicit
error which causes server startup to fail, encouraging users to check
for updated versions of plugins which will right the error.
diff --git a/lib/RT/PlackRunner.pm b/lib/RT/PlackRunner.pm
index 16eed5c..df52292 100644
--- a/lib/RT/PlackRunner.pm
+++ b/lib/RT/PlackRunner.pm
@@ -122,6 +122,20 @@ sub app {
$app = Plack::Middleware::Test::StashWarnings->wrap($app);
}
+ # Yell if we have reconnected to the database -- if we have, it
+ # will be shared across all children processes.
+ if ($RT::Handle and $RT::Handle->dbh) {
+ $RT::Logger->critical(<<EOT);
+
+An extension has reconnected to the database too late into
+initialization. This will cause the connection to be shared across
+processes, which will result in undefined behavior. Plugins must
+perform database-requiring initialization in `init`, not `to_app`;
+check for upgraded versions of your plugins which resolve this.
+
+EOT
+ }
+
return $app;
}
diff --git a/sbin/rt-server.in b/sbin/rt-server.in
index 5b9fecd..e82e43a 100644
--- a/sbin/rt-server.in
+++ b/sbin/rt-server.in
@@ -132,7 +132,7 @@ EOF
}
}
-# we must disconnect DB before fork
+# Disconnect from the database, having done all of the setup.
if ($RT::Handle) {
$RT::Handle->dbh->disconnect if $RT::Handle->dbh;
$RT::Handle->dbh(undef);
-----------------------------------------------------------------------
More information about the rt-commit
mailing list