Conversation
There was a problem hiding this comment.
Pull request overview
This PR reduces headless simulation failures caused by excessive child-process output by suppressing reb2sac progress-line printing in headless mode, while keeping GUI progress reporting unchanged. It also updates build/infra metadata so modules build more reliably and use secure repository URLs.
Changes:
- Suppress stdout printing of successfully parsed
Time=...progress lines when running headless (noparent), while still printing non-progress diagnostics. - Add explicit dependencies to
dataModels/pom.xmlto support standalone builds and update the osgeo repository URL to HTTPS. - Ignore
.sdkmanrcin.gitignore.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
analysis/src/main/java/edu/utah/ece/async/ibiosim/analysis/Run.java |
Avoids printing progress lines to stdout in headless mode to prevent buffer flooding. |
dataModels/pom.xml |
Adds explicit dependencies for standalone builds and switches osgeo repo URL to HTTPS. |
.gitignore |
Ignores .sdkmanrc. |
Comments suppressed due to low confidence (1)
analysis/src/main/java/edu/utah/ece/async/ibiosim/analysis/Run.java:901
- Progress detection uses
line.contains("Time")and then unconditionally attemptssubstring(line.indexOf('=') + 1, ...). If a non-progress diagnostic line contains the word "Time" but not the expectedTime=...format, this will throw ande.printStackTrace()will emit a stack trace per line, which can still flood stderr in headless runs. Tighten the condition (e.g., requireTime=prefix / regex with=present) and avoid printing full stack traces in this hot loop (log once or include the offending line in a concise message).
if (line.contains("Time")) {
time = Double.parseDouble(line.substring(line.indexOf('=') + 1, line.length()));
isProgress = true;
if (oldTime > time) {
runNum++;
}
oldTime = time;
time += (runNum * properties.getSimulationProperties().getTimeLimit());
double d = ((time * 100) / runTime);
String s = d + "";
double decimal = Double.parseDouble(s.substring(s.indexOf('.'), s.length()));
if (decimal >= 0.5) {
prog = (int) (Math.ceil(d));
} else {
prog = (int) (d);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <groupId>org.apache.httpcomponents</groupId> | ||
| <artifactId>httpcore</artifactId> | ||
| <version>4.4.6</version> | ||
| </dependency> | ||
| <dependency> |
There was a problem hiding this comment.
httpclient already brings in a compatible httpcore transitively. Declaring httpcore explicitly here is redundant unless you're intentionally overriding the transitive version; if you do need to pin it, it would help to add a brief comment explaining why. Otherwise consider removing the direct httpcore dependency to reduce version-locking and future maintenance overhead.
| <groupId>org.apache.httpcomponents</groupId> | |
| <artifactId>httpcore</artifactId> | |
| <version>4.4.6</version> | |
| </dependency> | |
| <dependency> |
| <version>2.7</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.google.guava</groupId> | ||
| <artifactId>guava</artifactId> | ||
| <version>18.0</version> |
There was a problem hiding this comment.
The newly added dependency versions (gson 2.7 and guava 18.0) are quite old and are commonly flagged by vulnerability scanners / have many fixes in newer releases. If there isn't a compatibility constraint forcing these versions, consider upgrading to more recent releases (or centralizing the versions in the parent POM) to reduce security and maintenance risk.
| <version>2.7</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>com.google.guava</groupId> | |
| <artifactId>guava</artifactId> | |
| <version>18.0</version> | |
| <version>2.10.1</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>com.google.guava</groupId> | |
| <artifactId>guava</artifactId> | |
| <version>32.1.3-jre</version> |
| message.setInteger(prog); | ||
| parent.send(RequestType.REQUEST_PROGRESS, message); |
There was a problem hiding this comment.
In the non-GUI path (parent == null), progress lines are now suppressed, but in the GUI path you still call parent.send(REQUEST_PROGRESS, ...) for every line read, even when the line wasn't parsed as a progress update (prog remains stale). This can create unnecessary IPC traffic and repeated identical progress events. Consider sending REQUEST_PROGRESS only when a progress update was successfully parsed (e.g., gate the send on isProgress).
| message.setInteger(prog); | |
| parent.send(RequestType.REQUEST_PROGRESS, message); | |
| if (isProgress) { | |
| message.setInteger(prog); | |
| parent.send(RequestType.REQUEST_PROGRESS, message); | |
| } |
Running simulations through SynBioSuite can fail with
ERR_CHILD_PROCESS_STDIO_MAXBUFFERwhen reb2sac progress output overflows Node.js's buffer in iBioSim-API. In headless mode,Run.javadumps every progress line (Time=X) to stdout, but nothing downstream uses them, they just accumulate until the buffer overflows.System.out.printlnfor lines successfully parsed as progress updates. Diagnostic output (warnings, errors) still prints.parent.send().dataModels/pom.xmlso the module builds standalone..sdkmanrcin.gitignore.