Skip to content
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

Rework cleanup process on shutdown #1449

Merged
merged 1 commit into from
Jul 11, 2020

Conversation

pdambrauskas
Copy link
Contributor

fixes #785

Due to this issue DeleteOnExit hook cannot be used on long-running applications.

This PR replaces usage of DeleteOnExitHook with custom shut down hook, which cleans up local storage directory.

@giner @HenryCaiHaiying does this makes sense :) ?

@pdambrauskas pdambrauskas force-pushed the rework_shutdown_hook branch 2 times, most recently from 4baeb11 to f828687 Compare July 10, 2020 11:06
@@ -54,6 +55,9 @@ public static void main(String[] args) {
}
try {
SecorConfig config = SecorConfig.load();
if (!config.getUploadOnShutdown()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only adding this hook, if uploadOnShutdown is disabled, otherwise we cannot be sure that deletion will happen after upload. Java does not provide strong order for shutdown hooks, they can be executed in any order & in parallel.

Other option would be implementing some kind of "shutdown hook registry" combining all hooks into one thread and registring all Runnables as one shutdown hook. But I think we do not need that, since files are deleted after upload anyways.

Copy link
Contributor

Choose a reason for hiding this comment

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

Take a look at DeleteOnExitHook.java, there seems a way to register your hook as the last one. If ordering cannot be done, I think you can modify the hook in uploadOnShutdown to have them call your hook's folder deletion methods. It's OK to have both hooks to call delete folders twice.

@HenryCaiHaiying
Copy link
Contributor

Left some comments, it's a good fix. I think we are using deleteOnExit() just in case the normal deletion didn't happen, by looking at FileRegistry.deletePath(), the local file would normally be deleted after upload, otherwise you would see millions of local files on disk during secor running (which would be a out of disk problem rather than out of memory problem).

Copy link
Contributor

@HenryCaiHaiying HenryCaiHaiying left a comment

Choose a reason for hiding this comment

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

Left some comments, it's a good fix. I think we are using deleteOnExit() just in case the normal deletion didn't happen, by looking at FileRegistry.deletePath(), the local file would normally be deleted after upload, otherwise you would see millions of local files on disk during secor running (which would be a out of disk problem rather than out of memory problem).

* @author Paulius Dambrauskas ([email protected])
*
*/
public class StagingCleaner implements Runnable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you rename the class name StagingCleaner to StagingDirectoryCleaner?


@Override
public void run() {
for (File file : mStagingDir.listFiles()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can just call FileUtils.deleteDirectory(stagingPath) instead of using a loop.

@@ -54,6 +55,9 @@ public static void main(String[] args) {
}
try {
SecorConfig config = SecorConfig.load();
if (!config.getUploadOnShutdown()) {
Runtime.getRuntime().addShutdownHook(new Thread(new StagingCleaner(config.getLocalPath())));
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use this path instead (Take a look at Upload.java): config.getLocalPath() is a shared folder with other processes/threads running on that host.

                    String localPrefix = mConfig.getLocalPath() + '/' +
                        IdUtil.getLocalMessageDir();

@@ -54,6 +55,9 @@ public static void main(String[] args) {
}
try {
SecorConfig config = SecorConfig.load();
if (!config.getUploadOnShutdown()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Take a look at DeleteOnExitHook.java, there seems a way to register your hook as the last one. If ordering cannot be done, I think you can modify the hook in uploadOnShutdown to have them call your hook's folder deletion methods. It's OK to have both hooks to call delete folders twice.

@pdambrauskas
Copy link
Contributor Author

@HenryCaiHaiying thanks for review!

I've updated shutdown hook logics.

  • Renamed delete hook file, as you suggested
  • Changed deletion path
  • Deleting whole path, instead of files inside
  • Created Shutdown hook registry, to make it easier to run hooks in specified order.

I decided not tou use DeleteOnExitHook approch, because documentation of registerShutdownHook method states that it is used only for DeleteOnExitHook. I'm afraid using it somewhere else might break something. I tried it on my first attemt, and integration tests failed in some strange way: https://travis-ci.org/github/pinterest/secor/jobs/706801339

Registers a shutdown hook.
It is expected that this method with registerShutdownInProgress=true
is only used to register DeleteOnExitHook since the first file
may be added to the delete on exit list by the application shutdown
hooks.

Also having single Shut down hook registry looks a bit nicer, as it makes usage of shutdown hooks more visible.

@HenryCaiHaiying
Copy link
Contributor

Looks good, this is a good fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Secor is leaking memory through DeleteOnExit
2 participants