From 232355a4aa6430ba6a40ab94ae135be3fad8573f Mon Sep 17 00:00:00 2001 From: Patrick Doyle Date: Tue, 2 Jan 2024 13:08:09 -0500 Subject: [PATCH] Fix: avoid nested transaction sessions --- .../vena/bosk/drivers/mongo/MainDriver.java | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/bosk-mongo/src/main/java/io/vena/bosk/drivers/mongo/MainDriver.java b/bosk-mongo/src/main/java/io/vena/bosk/drivers/mongo/MainDriver.java index c2dc2bcb..41037162 100644 --- a/bosk-mongo/src/main/java/io/vena/bosk/drivers/mongo/MainDriver.java +++ b/bosk-mongo/src/main/java/io/vena/bosk/drivers/mongo/MainDriver.java @@ -336,23 +336,26 @@ public void onConnectionSucceeded() throws LOGGER.debug("Loading database state to submit to downstream driver"); newDriver = detectFormat(); loadedState = newDriver.loadAllState(); - - // Update the FormatDriver before submitting the new state downstream in case - // a hook is triggered that calls more driver methods. - // Note: that there's no risk that another thread will submit a downstream update "out of order" - // before ours (below) because this code runs on the ChangeReceiver thread, which is - // the only thread that submits updates downstream. - - newDriver.onRevisionToSkip(loadedState.revision); - publishFormatDriver(newDriver); - - // TODO: It's not clear we actually want loadedState.diagnosticAttributes here. - // This causes downstream.submitReplacement to be associated with the last update to the state, - // which is of dubious relevance. We might just want to use the context from the current thread, - // which is probably empty because this runs on the ChangeReceiver thread. - try (var ___ = bosk.rootReference().diagnosticContext().withOnly(loadedState.diagnosticAttributes)) { - downstream.submitReplacement(bosk.rootReference(), loadedState.state); - } + } + // Note: can't call downstream methods with a session open, + // because that could run hooks, which could themselves submit + // new updates, and those updates need their own session. + + // Update the FormatDriver before submitting the new state downstream in case + // a hook is triggered that calls more driver methods. + // Note: that there's no risk that another thread will submit a downstream update "out of order" + // before ours (below) because this code runs on the ChangeReceiver thread, which is + // the only thread that submits updates downstream. + + newDriver.onRevisionToSkip(loadedState.revision); + publishFormatDriver(newDriver); + + // TODO: It's not clear we actually want loadedState.diagnosticAttributes here. + // This causes downstream.submitReplacement to be associated with the last update to the state, + // which is of dubious relevance. We might just want to use the context from the current thread, + // which is probably empty because this runs on the ChangeReceiver thread. + try (var ___ = bosk.rootReference().diagnosticContext().withOnly(loadedState.diagnosticAttributes)) { + downstream.submitReplacement(bosk.rootReference(), loadedState.state); } } else { LOGGER.debug("Running initialRoot action");