Skip to content

Commit d1003ee

Browse files
Merge 26.7 to 26.9
2 parents b6545a7 + ed7fcf8 commit d1003ee

4 files changed

Lines changed: 75 additions & 23 deletions

File tree

‎api/src/org/labkey/api/data/DbScope.java‎

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,29 +1473,38 @@ public ConnectionWrapper getPooledConnection(ConnectionType type, @Nullable Logg
14731473
throw new ConfigurationException("Can't create a database connection for data source " + getDbScopeLoader().getDsName(), e);
14741474
}
14751475

1476-
if (!conn.getAutoCommit())
1477-
throw new ConfigurationException("A database connection is in an unexpected state: auto-commit is false. This indicates a configuration problem with the datasource definition or the database connection pool.");
1476+
try
1477+
{
1478+
if (!conn.getAutoCommit())
1479+
throw new ConfigurationException("A database connection is in an unexpected state: auto-commit is false. This indicates a configuration problem with the datasource definition or the database connection pool.");
14781480

1479-
//
1480-
// Handle one time per-connection setup
1481-
// relies on pool implementation reusing same connection/wrapper instances
1482-
//
1481+
//
1482+
// Handle one time per-connection setup
1483+
// relies on pool implementation reusing same connection/wrapper instances
1484+
//
14831485

1484-
Connection delegate = getDelegate(conn);
1485-
Integer spid = _initializedConnections.get(delegate);
1486+
Connection delegate = getDelegate(conn);
1487+
Integer spid = _initializedConnections.get(delegate);
14861488

1487-
if (null == spid)
1488-
{
1489-
if (null != _dialect)
1489+
if (null == spid)
14901490
{
1491-
_dialect.prepareConnection(conn);
1492-
spid = _dialect.getSPID(delegate);
1491+
if (null != _dialect)
1492+
{
1493+
_dialect.prepareConnection(conn);
1494+
spid = _dialect.getSPID(delegate);
1495+
}
1496+
1497+
_initializedConnections.put(delegate, spid == null ? spidUnknown : spid);
14931498
}
14941499

1495-
_initializedConnections.put(delegate, spid == null ? spidUnknown : spid);
1500+
return new ConnectionWrapper(conn, this, spid, type, log);
1501+
}
1502+
catch (Throwable t)
1503+
{
1504+
// If the ConnectionWrapper didn't get created and returned, nothing else can close the connection
1505+
closeQuietly(conn, t);
1506+
throw t;
14961507
}
1497-
1498-
return new ConnectionWrapper(conn, this, spid, type, log);
14991508
}
15001509

15011510
/**
@@ -1513,6 +1522,22 @@ public void releaseConnection(Connection conn)
15131522
}
15141523
}
15151524

1525+
/**
1526+
* Release a connection while an exception is already propagating. Pool implementations can throw unchecked from
1527+
* close(), which would otherwise replace the failure we're unwinding from.
1528+
**/
1529+
public void closeQuietly(Connection conn, Throwable propagating)
1530+
{
1531+
try
1532+
{
1533+
releaseConnection(conn);
1534+
}
1535+
catch (Throwable t)
1536+
{
1537+
propagating.addSuppressed(t);
1538+
}
1539+
}
1540+
15161541
@JsonIgnore
15171542
public SqlDialect getSqlDialect()
15181543
{

‎api/src/org/labkey/api/data/dialect/StandardJdbcMetaDataLocator.java‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,22 @@ public StandardJdbcMetaDataLocator(DbScope scope, String schemaName, String sche
3737
{
3838
_scope = scope;
3939
_connection = getConnection();
40-
_dbmd = _connection.getMetaData();
4140

42-
_schemaName = schemaName;
43-
_schemaNamePattern = schemaNamePattern;
44-
_tableName = tableName;
45-
_tableNamePattern = tableNamePattern;
41+
try
42+
{
43+
_dbmd = _connection.getMetaData();
44+
45+
_schemaName = schemaName;
46+
_schemaNamePattern = schemaNamePattern;
47+
_tableName = tableName;
48+
_tableNamePattern = tableNamePattern;
49+
}
50+
catch (Throwable t)
51+
{
52+
// Nobody else can close the connection for us if we throw from the constructor
53+
scope.closeQuietly(_connection, t);
54+
throw t;
55+
}
4656
}
4757

4858
protected Connection getConnection() throws SQLException

‎core/src/org/labkey/core/CoreModule.java‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import org.labkey.api.data.dialect.BasePostgreSqlDialect;
8080
import org.labkey.api.data.dialect.PostgreSqlService;
8181
import org.labkey.api.data.dialect.SqlDialect;
82+
import org.labkey.api.data.dialect.SqlDialect.DataSourcePropertyReader;
8283
import org.labkey.api.data.dialect.SqlDialectManager;
8384
import org.labkey.api.data.dialect.SqlDialectRegistry;
8485
import org.labkey.api.data.statistics.StatsService;
@@ -349,7 +350,6 @@
349350
import java.lang.reflect.InvocationTargetException;
350351
import java.lang.reflect.Method;
351352
import java.sql.Connection;
352-
import java.sql.SQLException;
353353
import java.time.ZonedDateTime;
354354
import java.util.ArrayList;
355355
import java.util.Calendar;
@@ -365,6 +365,7 @@
365365
import java.util.Objects;
366366
import java.util.Properties;
367367
import java.util.Set;
368+
import java.util.concurrent.ConcurrentHashMap;
368369
import java.util.function.Supplier;
369370
import java.util.stream.Collectors;
370371
import java.util.stream.Stream;
@@ -584,6 +585,9 @@ private void deleteTempFiles()
584585

585586
private void registerHealthChecks()
586587
{
588+
// Data sources that were unreachable on the previous check, so we can log transitions instead of every poll
589+
Set<String> failedDataSources = ConcurrentHashMap.newKeySet();
590+
587591
HealthCheckRegistry.get().registerHealthCheck("database", HealthCheckRegistry.DEFAULT_CATEGORY, () ->
588592
{
589593
Map<String, Object> healthValues = new HashMap<>();
@@ -595,11 +599,18 @@ private void registerHealthChecks()
595599
{
596600
dbConnected = conn != null;
597601
}
598-
catch (SQLException e)
602+
// Some failures come as ConfigurationException, not SQLException. Cast a wide net to ensure
603+
// we return a 200 saying we're not healthy instead of a 500
604+
catch (Exception e)
599605
{
606+
if (failedDataSources.add(dbScope.getDataSourceName()))
607+
LOG.warn("Failed to get connection for data source {}", dbScope.getDataSourceName(), e);
600608
dbConnected = false;
601609
}
602610

611+
if (dbConnected && failedDataSources.remove(dbScope.getDataSourceName()))
612+
LOG.info("Reconnected to data source {}", dbScope.getDataSourceName());
613+
603614
healthValues.put(dbScope.getDatabaseName(), dbConnected);
604615
allConnected &= dbConnected;
605616
}

‎experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,13 @@ public static void fixContainerForMovedSampleFiles(ModuleContext context)
515515
LimitedUser admin = new LimitedUser(context.getUpgradeUser(), SiteAdminRole.class);
516516
int numDuplicates = service.fixContainerForExpDataFiles(admin);
517517
LOG.info("Fixed {} duplicate data files.", numDuplicates);
518+
tx.commit();
519+
}
520+
catch (Exception e) // Issue 55026
521+
{
522+
LOG.error("Error while fixing container for moved sample files.", e);
518523
}
524+
519525
}
520526

521527
/**

0 commit comments

Comments
 (0)