Skip to content
Open
27 changes: 13 additions & 14 deletions api/src/org/labkey/api/data/DbScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import org.labkey.api.util.GUID;
import org.labkey.api.util.LoggerWriter;
import org.labkey.api.util.MemTracker;
import org.labkey.api.util.Pair;
import org.labkey.api.util.ResultSetUtil;
import org.labkey.api.util.SimpleLoggerWriter;
import org.labkey.api.util.SkipMothershipLogging;
Expand Down Expand Up @@ -3271,9 +3270,8 @@ public void testLockTimeout()
{
ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();
Pair<Throwable, Throwable> throwables = attemptToDeadlock(lock1, lock2, (x) -> ((TransactionImpl)x).setLockTimeout(5, TimeUnit.SECONDS));
attemptToDeadlock(lock1, lock2, (x) -> ((TransactionImpl)x).setLockTimeout(5, TimeUnit.SECONDS), DeadlockPreventingException.class);

assertTrue(throwables.first instanceof DeadlockPreventingException || throwables.second instanceof DeadlockPreventingException);
assertFalse("Lock 1 is still locked", lock1.isLocked());
assertFalse("Lock 2 is still locked", lock2.isLocked());
}
Expand Down Expand Up @@ -3394,18 +3392,13 @@ public void testServerRowLock()
Lock lockUser = new ServerPrimaryKeyLock(true, CoreSchema.getInstance().getTableInfoUsersData(), user.getUserId());
Lock lockHome = new ServerPrimaryKeyLock(true, CoreSchema.getInstance().getTableInfoContainers(), ContainerManager.getHomeContainer().getId());

Pair<Throwable, Throwable> throwables = attemptToDeadlock(lockUser, lockHome, (x) -> {});

assertTrue("Unexpected exceptions: " + throwables.first + "\n" + throwables.second, throwables.first instanceof PessimisticLockingFailureException || throwables.second instanceof PessimisticLockingFailureException );
attemptToDeadlock(lockUser, lockHome, (x) -> {}, PessimisticLockingFailureException.class);
}

/**
* @return foreground and background thread exceptions
*/
private Pair<Throwable, Throwable> attemptToDeadlock(Lock lock1, Lock lock2, @NotNull Consumer<Transaction> transactionModifier)
private void attemptToDeadlock(Lock lock1, Lock lock2, @NotNull Consumer<Transaction> transactionModifier, Class<? extends Throwable> expectedException)
{
final Object notifier = new Object();
final Pair<Throwable, Throwable> result = new Pair<>(null, null);
final List<Throwable> result = new ArrayList<>();

// let's try to intentionally cause a deadlock
Thread bkg = new Thread(() -> {
Expand All @@ -3431,7 +3424,7 @@ private Pair<Throwable, Throwable> attemptToDeadlock(Lock lock1, Lock lock2, @No
}
catch (Throwable x)
{
result.second = x;
result.add(x);
}
}
});
Expand Down Expand Up @@ -3465,7 +3458,7 @@ private Pair<Throwable, Throwable> attemptToDeadlock(Lock lock1, Lock lock2, @No
}
catch (Throwable x)
{
result.first = x;
result.add(x);
}
finally
{
Expand All @@ -3479,7 +3472,13 @@ private Pair<Throwable, Throwable> attemptToDeadlock(Lock lock1, Lock lock2, @No
}
}
}
return result;

assertFalse("No exceptions from attempted deadlock.", result.isEmpty());
result.stream().filter(t -> !expectedException.isAssignableFrom(t.getClass()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment on the intent here would be helpful - I believe it's choosing between reusing an existing exception in the list or throwing a new one?

.findAny().ifPresent(t -> {
throw new AssertionError("Wrong error from deadlock. expected: <" +
expectedException.getSimpleName() + ">, but was <" + t.getClass().getSimpleName() + ">", t);
});
}

@Test
Expand Down
20 changes: 17 additions & 3 deletions api/src/org/labkey/api/util/DebugInfoDumper.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,22 @@ public static synchronized void dumpThreads(LoggerWriter logWriter)
// Schema won't exist on SQLServer
if (schema != null)
{
writeTable(logWriter, schema, BasePostgreSqlDialect.POSTGRES_STAT_ACTIVITY_TABLE_NAME, "Postgres activity");
writeTable(logWriter, schema, BasePostgreSqlDialect.POSTGRES_LOCKS_TABLE_NAME, "Postgres locks");
try
{
writeTable(logWriter, schema, BasePostgreSqlDialect.POSTGRES_LOCKS_TABLE_NAME, "Postgres locks");
}
catch (RuntimeException e)
{
logWriter.debug("Failed to write Postgres locks table:" + e);
}
try
{
writeTable(logWriter, schema, BasePostgreSqlDialect.POSTGRES_STAT_ACTIVITY_TABLE_NAME, "Postgres activity");
}
catch (RuntimeException e)
{
logWriter.debug("Failed to write Postgres activity table:" + e);
}
}
}

Expand All @@ -434,7 +448,7 @@ private static void writeTable(LoggerWriter logWriter, UserSchema schema, String
PrintWriter printWriter = new PrintWriter(stringWriter);
writer.write(printWriter);
printWriter.flush();
logWriter.debug("\n" + stringWriter.toString());
logWriter.debug("\n" + stringWriter);
}
catch (IOException e)
{
Expand Down