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

Should mioco catch panics by default? #90

Closed
dpc opened this issue Feb 13, 2016 · 12 comments
Closed

Should mioco catch panics by default? #90

dpc opened this issue Feb 13, 2016 · 12 comments

Comments

@dpc
Copy link
Owner

dpc commented Feb 13, 2016

Right now mioco catches all panics from coroutines and converts them into ExitStatus::Panicked notification.

In #85 a config option was added to allow not-catching, and we're wondering if catching panic is justified at all.

The reasoning is:

  • coroutines should work just like native threads, and on native panic causes whole process to exit
  • user can easily add the panic catching manually

Looking for opinions about it.

Myself, ATM, I think removing catching panics is a way to go.

@dpc
Copy link
Owner Author

dpc commented Feb 13, 2016

@jeremyjh @Drakulix @polyfractal , would you like to add your opinion?

@jeremyjh
Copy link
Contributor

I think by default it should let panic unwind through the scheduler's thread, but there should be a mechanism to catch panic before it crashes the whole scheduler - just as you can in native threads.

@Drakulix
Copy link
Collaborator

That this library provides panic handling at all is not really idiomatic Rust. A panic implies a critical point of failure, which cannot be recovered in a meaningful way, most of the time related to unsafe code or knowingly invalidating a simple invariant.

That recover and propagate is in place is mostly only related to the fact, that it causes undefined behavior (most of the time causing a crash) to unwind into or through foreign (non-rust) code.

However I do understand, that in server and production related code, (which is what mioco is somewhat aiming for with evented IO,) you need to protect your whole program against crashing. Even if a panic should never happen.
BUT there is nothing stopping the library user to insert a recover statement in their coroutine themselves. Especially since this does not seem to be very costly at the moment.

I would say toss all of that panic related logic out of the code (except for the necessary propagate into the scheduler thread) and let the user handle it. This would clean up a good amount of code and gives us the opportunity to do something more useful with the exit_notificator. Maybe it is even possible to send the actual return value of the coroutine through it, which I would find a lot more useful.

I would even say the current API does encourage you to throw a panic in case of an error, because it is easier to get that information through the exit_notificator, then creating and passing a newly created mailbox into the coroutine just to send a completion or error message.
And this is not Java, we do not want panics all over the place.

Anyway I am also in favor of changing the default behavior.

@jeremyjh
Copy link
Contributor

Panic has always been intended to be handled at the Task level in Rust; I think that is more idiomatic than using recover statements in the thread that may raise a panic.

@Drakulix
Copy link
Collaborator

I am not sure, if I understand your last comment @jeremyjh . It seems to be contradictory to your last one.
Handling at task level would mean, let the user wrap their tasks, if they may panic. Handling at a thread level would be closer to the current behavior. So whats your preference?

@jeremyjh
Copy link
Contributor

Sorry, I'm using old terminology - I should just say thread. We used to have task::try in the standard library, which was the only way to catch a panic - it spawned a new thread and would catch a panic in that thread if it happened - there was no way to recover in the same thread.

I think this was removed because it encouraged people to use heavy-weight OS threads just to be able to catch a panic. In mioco, the older model makes more sense to me because cos are lightweight. So all I am asking for is an equivalent of the old task::try, that would spawn a new coroutine and let it contain a panic result and handle it how they wished.

See http://smallcultfollowing.com/rust-int-variations/imem-umem/guide-tasks.html for the old behavior.

@Drakulix
Copy link
Collaborator

Alright that makes sense.

You have a point, it is clearly easier to handle the panic through a try-like interface, then through a very verbose recover statement.

Also my argument seems to be invalid, I forgot, that coroutines already return a Result.

@dpc Do you think it might be possible to make ExitStatus generic over the Results Ok-Variant? Maybe even over the Err Variant.

e.g.

pub enum ExitStatus<R: Sized + Send>
{
    Exit(Arc<Result<R>>,
    Panic,
    Killed,
}

@dpc
Copy link
Owner Author

dpc commented Feb 15, 2016

@jeremyjh : You made a good point. Thanks.

I think there's technically no drawback from keeping panic handling, and it seems it has it's own advantages.

@Drakulix : It would be possible, but it seems it would require whole mioco instance to be parametrized over R, so that all coroutines return same type. Which is maybe OK... . Maybe it wouldn't even affect a lot of types. And even if it does, it shouldn't hurt.

Or maybe some Into / From / Any into the mix would allow more flexible approach, where any coroutine could return anything (at least type wise), and if it's not something expected ExitStatus::Unkown result would be returned...

@Drakulix
Copy link
Collaborator

I think we should just stick to the current implementation then. Result already is the right type to encode Success and Failure, I do not think parametric mioco instances add much more flexibility to the overall API, but make the code base much more verbose and complex.

We should just decide, if we catch panics by default or not.

@jeremyjh
Copy link
Contributor

My vote would be not catch them by default.

On Thursday, February 25, 2016, Victor Brekenfeld notifications@github.com
wrote:

I think we should just stick to the current implementation then. Result
already is the right type to encode Success and Failure, I do not think
parametric mioco instances add much more flexibility to the overall API,
but make the code base much more verbose and complex.

We should just decide, if we catch panics by default or not.


Reply to this email directly or view it on GitHub
https://github.com/dpc/mioco/issues/90#issuecomment-188859086.

@Drakulix
Copy link
Collaborator

+1

@dpc
Copy link
Owner Author

dpc commented Feb 25, 2016

All right then. Default is to catch them, there's an option to disable that. I guess we can close.

@dpc dpc closed this as completed Feb 25, 2016
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

No branches or pull requests

3 participants