Skip to content

Conversation

@tisonkun
Copy link
Contributor

@tisonkun tisonkun commented Oct 3, 2025

Avoid global static IS_TEARING_DOWN trick.

Comment on lines 473 to 480
pub(crate) fn flush_sinks_atexit(&self) {
self.sinks.iter().for_each(|sink| {
if let Err(err) = sink.flush_atexit() {
self.handle_error(err);
}
});
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This may be even pub if users set their own global static LOGGER. But given that is not quite possible it's OK to leave pub(crate) until real use cases occur.

Copy link
Owner

@SpriteOvO SpriteOvO left a comment

Choose a reason for hiding this comment

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

I like this idea! In fact, previously we still couldn't guarantee that users wouldn't use thread-local (or anything else that might conflict with atexit()) in their own sinks, because the global atomic bool variable IS_TEARING_DOWN is not public. This PR enables users to be aware that the program is in an atexit() callback and customize the flush implementation for this case.

Perhaps one minor nitpick is that I'm not sure if there might be a better choice for the naming. flush_atexit implies that it will be called in the atexit() callback, which is good, on the other hand the naming style is not so Rusty... I'll think about it some more, anyway it's not a big issue.

@tisonkun
Copy link
Contributor Author

tisonkun commented Oct 3, 2025

on the other hand the naming style is not so Rusty

Yeah. I'm struggling with naming this method also. Let's give it some days for potential new ideas :D

Signed-off-by: tison <[email protected]>
Signed-off-by: tison <[email protected]>
@tisonkun
Copy link
Contributor Author

tisonkun commented Oct 5, 2025

What about flush_on_exit?

@tisonkun
Copy link
Contributor Author

tisonkun commented Oct 6, 2025

Or even we call the public method simply exit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We currently set atexit and only hook_panic if atexit fails.

However, it seems that atexit is only called when the process is normally terminated. Not sure if a panic causes a normal exit, or an abnormal exit.

At least when panic = "abort", the atexit glue may not be called.

Copy link
Owner

Choose a reason for hiding this comment

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

I'm not at home these days, will take a look at it days later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're not in a rush. Enjoy your days :D

Copy link
Owner

@SpriteOvO SpriteOvO Oct 16, 2025

Choose a reason for hiding this comment

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

We currently set atexit and only hook_panic if atexit fails.

However, it seems that atexit is only called when the process is normally terminated. Not sure if a panic causes a normal exit, or an abnormal exit.

At least when panic = "abort", the atexit glue may not be called.

For "unwind" panic, atexit callbacks will be called. But I didn't realize "abort" panic before, and indeed as you said, atexit doesn't work for it.

I'm not sure yet what the best solution for it is, maybe always hook panic if #[cfg(panic = "abort")]? Because we don't need the callback to be called twice (once from atexit and once from the panic handler). Anyway, I think this should be implemented in a new PR, not in this one. But it's valuable that you mentioned it, so flush_atexit is really not a good name, if the panic handler is actually calling it.

I think flush_on_exit is fine. Also, I've been thinking about the need to add an exit reason parameter:

pub enum ExitReason {
    AtExit,
    Panic,
    // Maybe added in future
    Signal(...)
}

fn flush_on_exit(&self, reason: ExitReason) { ... }

One reason is that it may be possible in the future, we call flush when a crash signal occurs (we had an attempt in PR #18), and there are stricter safety requirements (signal-safety) for exception signals, in short, many APIs can't be used in some signal handlers.

Not sure if such a parameter is necessary to add, and to add it now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your update. I'll give this PR another round early next month.

@tisonkun
Copy link
Contributor Author

tisonkun commented Nov 3, 2025

@SpriteOvO push the rename at fb89450

Not sure if such a parameter is necessary to add, and to add it now.

I think this can be a good idea. But we may do it in a separate PR since this PR already contains much context.

@SpriteOvO SpriteOvO changed the title refactor: call flush_atexit at exit Flush sinks on program exit with a special method Sink::flush_on_exit Nov 3, 2025
Copy link
Owner

@SpriteOvO SpriteOvO left a comment

Choose a reason for hiding this comment

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

Thanks!

@SpriteOvO SpriteOvO merged commit 204c2ef into SpriteOvO:main-dev Nov 3, 2025
46 checks passed
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.

2 participants