Skip to content

Commit 87ac46a

Browse files
committed
Log stuck MCS pairs with matcher flags for SMSD debugging
When a MCS poll() times out, the WARN now includes: reaction ID, algorithm, atom counts, matcher flags (atomType, bondMatch, ringMatch, ringSizeMatch), and molecule IDs. Stuck futures are cancelled to free the executor pool.
1 parent b472f67 commit 87ac46a

1 file changed

Lines changed: 26 additions & 1 deletion

File tree

src/main/java/com/bioinceptionlabs/reactionblast/mapping/GraphMatcher.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,10 @@ public static Collection<MCSSolution> matcher(Holder mh) throws Exception {
446446
if (listOfJobs.size() > LARGE_JOB_THRESHOLD) {
447447
LOGGER.warn("Large job: " + listOfJobs.size() + " MCS pairs to compute");
448448
}
449+
java.util.List<java.util.concurrent.Future<MCSSolution>> mcsJobFutures = new java.util.ArrayList<>();
449450
if (!listOfJobs.isEmpty()) {
450451
for (MCSThread mcsThreadJob : listOfJobs) {
451-
callablesQueue.submit(mcsThreadJob);
452+
mcsJobFutures.add(callablesQueue.submit(mcsThreadJob));
452453
taskCounter++;
453454
}
454455
}
@@ -486,6 +487,30 @@ public static Collection<MCSSolution> matcher(Holder mh) throws Exception {
486487
LOGGER.error(SEVERE, "MCS worker failed", cause);
487488
}
488489
}
490+
// Cancel and log stuck MCS pairs for SMSD debugging
491+
for (int ji = 0; ji < mcsJobFutures.size(); ji++) {
492+
java.util.concurrent.Future<MCSSolution> f = mcsJobFutures.get(ji);
493+
if (!f.isDone()) {
494+
f.cancel(true);
495+
MCSThread stuck = listOfJobs.get(ji);
496+
PairJob stuckJob = jobsToRun.size() > ji ? jobsToRun.get(ji) : null;
497+
String flags = stuckJob != null
498+
? " atomType=" + stuckJob.settings.atomType
499+
+ " bondMatch=" + stuckJob.settings.bondMatch
500+
+ " ringMatch=" + stuckJob.settings.ringMatch
501+
+ " ringSizeMatch=" + stuckJob.settings.ringSizeMatch
502+
: "";
503+
LOGGER.warn("STUCK MCS pair in " + reactionId + " [" + algorithmName
504+
+ "] educt(" + stuck.queryPosition + ")="
505+
+ stuck.compound1.getAtomCount() + " atoms"
506+
+ " product(" + stuck.targetPosition + ")="
507+
+ stuck.compound2.getAtomCount() + " atoms"
508+
+ flags
509+
+ " eductID=" + stuck.compound1.getID()
510+
+ " productID=" + stuck.compound2.getID()
511+
+ " — cancelled after timeout");
512+
}
513+
}
489514
// Add directly-constructed identity mappings (bypassed MCSThread)
490515
threadedUniqueMCSSolutions.addAll(directMCSSolutions);
491516
// Shut down the local executor; interrupt any stuck threads

0 commit comments

Comments
 (0)