-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Fix for postgres instance process closing #12927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ination (Fix JabRef#12844) * Added logic to detect and clean up stale embedded PostgreSQL instances left behind by previous JabRef sessions. * Introduced PostgresProcessCleaner to safely shut down any orphaned PostgreSQL processes using PID-based detection. * Registered a shutdown hook in Launcher to ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdown.
…ination (Fix JabRef#12844) * Added logic to detect and clean up stale embedded PostgreSQL instances left behind by previous JabRef sessions. * Introduced PostgresProcessCleaner to safely shut down any orphaned PostgreSQL processes using PID-based detection. * Registered a shutdown hook in Launcher to ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdown. * Updated CHANGELOG.md
…ination (Fix JabRef#12844) * Added logic to detect and clean up stale embedded PostgreSQL instances left behind by previous JabRef sessions. * Introduced PostgresProcessCleaner to safely shut down any orphaned PostgreSQL processes using PID-based detection. * Registered a shutdown hook in Launcher to ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdown.
…ination (Fix JabRef#12844) * Added logic to detect and clean up stale embedded PostgreSQL instances left behind by previous JabRef sessions. * Introduced PostgresProcessCleaner to safely shut down any orphaned PostgreSQL processes using PID-based detection. * Registered a shutdown hook in Launcher to ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdown. * Updated CHANGELOG.md
…ination (Fix JabRef#12844) * Added logic to detect and clean up stale embedded PostgreSQL instances left behind by previous JabRef sessions. * Introduced PostgresProcessCleaner to safely shut down any orphaned PostgreSQL processes using PID-based detection. * Registered a shutdown hook in Launcher to ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdown. * Updated CHANGELOG.md
…ination (Fix JabRef#12844) * style changes in PostgreProcessCleaner, Launcher
|
|
||
| private void destroyPreviousJavaProcess(Map<String, Object> meta) throws InterruptedException { | ||
| long javaPid = ((Number) meta.get("javaPid")).longValue(); | ||
| destroyProcessByPID(javaPid, 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does one know whether this stores JabRef data? Shouldn't a connection attempt be made?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In writeMetadataToFile method, I am using ProcessHandle.current().pid(), so that the current running process id will be stored in the json file.
|
This is AI generated, isn't it? |
|
Have you tested this by observing the processes? If so, on which OS? |
nope. |
|
|
||
| public class PostgreServer { | ||
| private static final Logger LOGGER = LoggerFactory.getLogger(PostgreServer.class); | ||
| public static final Path POSTGRES_METADATA_FILE = Path.of("/tmp/jabref-postgres-info.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will not work in Windows. Will not work if multiple JabRef instances run.
For the former, AppDirs can be used (can't it?) - for the latter, the whole flow needs to be thought through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, I need to check about AppDirs once & get back on this.
yes, I have tested on macOS Sequoia 15.4. I will check on windows and update here. |
Interesting - this seems to be going in a positive direction, if we can fix it for Windows. |
…ination (Fix JabRef#12844) * style changes in PostgreServer imports
…ination (Fix JabRef#12844) * Updated CHANGELOG.md
…ination (Fix JabRef#12844) * Modified PostgreProcessCleaner logic to fix windows os issue.
checked on windows as well, can you please check from your end as well? screen-capture-windows.mp4 |
…ination (Fix JabRef#12844) * Used Path.of() instead of Paths.get() in PostgreProcessCleaner.
src/main/java/org/jabref/logic/search/PostgreProcessCleaner.java
Outdated
Show resolved
Hide resolved
src/main/java/org/jabref/logic/search/PostgreProcessCleaner.java
Outdated
Show resolved
Hide resolved
|
Embedded Postgres Cleanup Flow 2.Write Metadata File 3.Check for Metadata Files on Startup 4.Verify Java Process Liveness 5.Handle Stale Java Processes 6.Lookup Postgres Processes 7.Kill Stale Postgres 8.Delete Metadata Files 9.Proceed with Fresh Initialization 10. Multiple Instance Safety |
…ination (Fix JabRef#12844) * Fix for trag-bot comments.
…ination (Fix JabRef#12844) * Fix for trag-bot comments.
…ination (Fix JabRef#12844) * Fix for trag-bot comments.
| Map<String, Object> meta = new HashMap<>(); | ||
| meta.put("javaPid", ProcessHandle.current().pid()); | ||
| meta.put("postgresPort", port); | ||
| meta.put("startedBy", "jabref"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some sense, trag-bot is right.
Is it possible to, maybe, make a serializable class?
|
I did not see any progress since weeks. I will close this PR. @UdayHE If you intend to continue here; feel free to ping us. |
| } | ||
|
|
||
| private void destroyProcessByPID(long pid) throws InterruptedException { | ||
| Optional<ProcessHandle> aliveProcess = ProcessHandle.of(pid).filter(ProcessHandle::isAlive); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method destroyProcessByPID should use ifPresent on Optional instead of checking isPresent and then calling get.
| if (aliveProcess.isPresent()) { | ||
| aliveProcess.get().destroy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code should use ifPresent to handle the Optional instead of checking isPresent and then calling get.
|
Below is the flow and classes involved. Few doubts I have, please find below
|
| meta.put("javaPid", ProcessHandle.current().pid()); | ||
| meta.put("postgresPort", port); | ||
| meta.put("startedBy", "jabref"); | ||
| meta.put("startedAt", DateTimeFormatter.ISO_INSTANT.format(Instant.now())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string literal key "startedAt" should be declared as a private static final constant to improve maintainability and readability, following best practices for handling literals.
|
|
||
| private static Map<String, Object> createMetadata(int port) { | ||
| Map<String, Object> meta = new HashMap<>(); | ||
| meta.put("javaPid", ProcessHandle.current().pid()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string literal key "javaPid" should be declared as a private static final constant to improve maintainability and readability, following best practices for handling literals.
| private static Map<String, Object> createMetadata(int port) { | ||
| Map<String, Object> meta = new HashMap<>(); | ||
| meta.put("javaPid", ProcessHandle.current().pid()); | ||
| meta.put("postgresPort", port); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string literal key "postgresPort" should be declared as a private static final constant to improve maintainability and readability, following best practices for handling literals.
I see two options:
The postgres notification system is not too hard; maybe a better way to habdle things.
oshi sounds promising |
* Modified getPidUsingPort() to use OSHI. * Fix for review comments.
| CSLStyleLoader.loadInternalStyles(); | ||
|
|
||
| // Register shutdown hook | ||
| Runtime.getRuntime().addShutdownHook(new Thread(postgreServer::shutdown)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 'new Thread()' is discouraged. Instead, 'org.jabref.logic.util.BackgroundTask' and its 'executeWith' method should be used for better resource management and consistency with the rest of the codebase.
| requires mslinks; | ||
| requires org.antlr.antlr4.runtime; | ||
| requires org.libreoffice.uno; | ||
| requires com.github.oshi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pull request title should contain a short title of the issue fixed or what the PR addresses, not just 'Fix issue xyz'. This is important for clarity and tracking purposes.
| } | ||
|
|
||
| public void checkAndCleanupOldInstances() { | ||
| try (Stream<Path> files = Files.list(TEMP_DIR)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try block covers too many statements, which can make it harder to identify where an exception occurs. It should cover as few statements as possible.
| try { | ||
| Path path = getMetadataFilePath(); | ||
| OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValue(path.toFile(), createMetadata(port)); | ||
| LOGGER.info("Postgres metadata file path: {}", path); | ||
| } catch (IOException e) { | ||
| LOGGER.warn("Failed to write Postgres metadata file.", e); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try block covers multiple statements. It is recommended to minimize the scope of try blocks to only the statements that might throw exceptions.
| OS.APP_DIR_APP_AUTHOR)); | ||
| } | ||
|
|
||
| public static Path getTmpDirectory() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method getTmpDirectory() is newly added and should not return null. It should use java.util.Optional to handle potential null values, ensuring better null safety and adherence to modern Java practices.
|
@trag-bot didn't find any issues in the code! ✅✨ |
|
I think, the issue needs to be adressed in another way. |
Fixes #12844
Summary
PostgreProcessCleanerto safely shut down any orphaned PostgreSQL processes using port-based detection and Java PID tracking.Launcherto ensure embedded PostgreSQL is properly terminated during normal or abrupt shutdowns (excluding SIGKILL).Mandatory checks
CHANGELOG.mddescribed in a way that is understandable for the average user (if change is visible to the user)macOS Sequoia 15.4.
https://www.loom.com/share/9ed0da7815714797b4f0568c33f6df03?sid=34114b6c-ca32-43ff-9896-bfae39b36c81
Windows
https://github.com/user-attachments/assets/aa7a7da4-661e-464e-a08f-f6befba66363