Re: [go-nuts] Re: Recover considered harmful

2017-04-27 Thread Dave Cheney
The take away for me is; prefer returning an error to to caller wherever 
possible. Overuse of panic begats overuse of recover and that just leads to 
more problems [1].

1. https://github.com/golang/go/issues/13879

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-27 Thread mhhcbon

>
> Most languages, who stick with Exceptions, usually has two kind of 
> exceptions:
> - "exception for regular error", i.e. wrong input, wrong system state, or 
> for "control flow"
> - and "fatal exceptions",
>

agree to that. 
Current error management is not satisfying and pushes the community to find 
a convention**, 
unfortunately it seems impossible to reach, 
the only one who made things goes forward is Dave Cheney with pkg/errors.

** One might say, by now all errors must implement IsFatal so that the 
consumer can determine the severity of error it is dealing with.
It is not impossible to do today, but two packages not written together 
with this rule in mind won t match.
And consensus has not come, so we are left with a broken leg.

PS: panic is just another capability provided, there s no need to fell into 
some dogma like `never use it`,
like everything else in go, use it with care, or panic and fix it.

On Wednesday, April 26, 2017 at 7:30:36 AM UTC+2, Sokolov Yura wrote:
>
> It looks like there is two point of view:
>
> - optimists who never used to build mutable shared state by them self, and 
> they hope libraries they use also don't use mutable shared state,
> - and those who know that mutable shared state usually exists.
>
> In absence of mutable shared state it is perfectly valid to recover to 
> immitate what PHP or Erlang does. But PHP and Erlang has real "process" 
> isolation, and they tend to not recover cause conurrent requests are really 
> "not affected".
>
> Erlang's philosophy is "let it crash" cause there is always "superwiser" 
> in a separate isolated "process" who will respawn "worker process".
>
> PHP will let whole process to crash if it meets C-level "assert" cause 
> process doesn't serve more than one request at time, and there is also 
> always a superwiser who will spawn new process to serve requests.
>
> But in Go you have no such support from runtime. So, you have to inspect 
> all third-party libraries to check they doesn't have mutable shared state, 
> if you want to `recover`. But if you did inspect them, then why didn't you 
> prevent them from 'panic'? Why did you pass input that leads to panic you 
> "allowed to recover"? You didn't test your program enough?
>
> Most languages, who stick with Exceptions, usually has two kind of 
> exceptions:
> - "exception for regular error", i.e. wrong input, wrong system state, or 
> for "control flow"
> - and "fatal exceptions",
> First kind of exceptions are safe to catch and recover from.
> Second kind is always documented as "you'd better crash, but don't recover 
> from it". They usually have separate inheritance root, so regular 'catch' 
> doesn't catch them (some exceptions even checked by runtime to not be 
> catched). And everyone in safe mind will not catch those exceptions.
>
> Go says:
> - first kind is just an error. Return error, analyze error, rereturn 
> error, and you will be happy, and your hair will shine.
> - Second kind is... yeah, it should be panic. You'd better not recover. 
> But you know what... I'm sometimes use it for control flow... and I do 
> recover in 'net/http' cause I pretend to be new PHP... So, you have no 
> "blessed way" to "fatal error". Go ahead, and do your own "super-panic" 
> with "debug.PrintStack(); os.Exit(1)".
>
> I'm sad falcon.
>
> PS. To be fair, "fatal exceptions" usually allows to eval `finally` 
> statements, so my point for "optimize defer in absence of recover" is not 
> perfectly valid.
>
> 26 апр. 2017 г. 7:24 AM пользователь "Chris G"  > написал:
>
>>
>>
>> On Tuesday, April 25, 2017 at 7:52:25 PM UTC-7, Dave Cheney wrote:
>>>
>>> > Yes, and then crashes the program. In the scenario I described, with 
>>> thousands of other requests in flight that meet an abrubt end.  That could 
>>> be incredibly costly, even if it's been planned for
>>>
>>> There are a host of other reasons that can take a server offline 
>>> abruptly. It seems like a odd misallocation of resources to try to prevent 
>>> one specific case - a goroutine panics due to a programming error or input 
>>> validation failure -- both which are far better addressed with testing.
>>>
>> There's a cost benefit analysis to be done, for sure, but I don't always 
>> believe it to be a misallocation of resources.  I don't believe it's costly 
>> for every program, and for programs where it's important, I don't believe 
>> it to always be a hard problem to accomplish.  To your point, for a great 
>> many programs, the effort probably isn't worth the reward.
>>  
>>
>>> To try to postpone the exit of a program after a critical error to me 
>>> implies a much more complex testing and validation process that has 
>>> identified all the shared state in the program and verified that it is 
>>> correct in the case that a panic is caught.
>>>
>> Not always applicable, but there are some relatively easy ways of coping 
>> with that:
>> - Don't have shared state to begin with (for a large number of 

Re: [go-nuts] Re: Recover considered harmful

2017-04-27 Thread Jesper Louis Andersen
On Wed, Apr 26, 2017 at 10:55 AM Peter Herth  wrote:

>
> No, panic certainly does not do that. It prints the stack trace. A proper
> logger could add additional information about the program state at the
> point of the panic, which is not visible from the stack trace. It also
> might at least be reasonable to perform an auto-save before quitting.
>
>
Additional comments in a haphazard order:

It makes sense to accept a panic() in a Go program will have some
collateral requests being taken down as a consequence. This argument can be
extended however. Since the operating system kernel might be wrong, it is
better to halt the operating system whenever a Goroutine panics. After all,
the logic seems, who can be sure the operating system forget to release a
Mutex lock? And why stop there? The hardware on which you are running may
have a failure. Better replace that whenever a goroutine panics!

In practice---I think this is due to work by Peter J. Denning
originally---we use process isolation at the OS level to guard against such
failure. We ought to use a layered model, where each layer guards the
layers below it. There is a 7 year old blogpost I wrote on the subject, in
which I used an onion as a metaphor for the model[0], and it is one of the
blog posts which have had more readers than other posts.

In general, failure is something you ought to capture for post-mortem
analysis. Get the core-dump, push it into your blob store, restart the
process and then attach a debugger to the blob to figure out what is wrong.
In my experience, it is also important to have access to the memory state
of the program in addition to the backtrace if the problem is complex.

What Erlang people acutely understands is that the granularity of failure
matter. A single request failing in a system is, usually, localized to that
single request. If, however, we have a situation as Roger Pepper mentions
where a mutex is locked, the failure of single requests should at some
point escalate to larger parts of the system. This is where the concept of
a "restart strategy" in Erlang systems are necessary: more than K failures
in a time-frame window of W increases the granularity and resets larger
parts of the system. Eventually, the whole node() resets, which is akin to
a Go panic() which isn't getting caught. The advantage is that the size of
the failure determines its impact: small errors have small impact. Large
errors have large impact.

Dave Cheney touches on another important point: if you care about requests
and a panic in one Go process can make other requests running collaterally
fail, then you should build your load balancer such that it retries the
requests on another worker[1].

Yet another point worth mentioning is that a panic() can have a large
recovery time for a process. If you have a large heap of several hundred
gigabytes of data, reestablishing such heap after a failure might take a
long time. Thus, it can be beneficial to restart parts of the system at a
finer granularity first, before resorting to rebooting the full process.
Likewise, if a system knows it is in a bad state, it is often faster to
report said state to the load-balancer rather than relying on it eventually
figuring it out. Depending on your SLA, you may fail many requests in the
mean time and this may affect your reliability measure. This is especially
true if your system has a high processing rate of requests, which makes it
far more sensitive to latency fluctuations.

So what is a Go programmer to do? The solution, at least from my view, is
to use the 'context' package to establish a tree of work-areas for
different parts of the Go program. Failure in one tree can then be handled
by failing a given context, and if the system can clean up, you can
continue operating. The question is, then, what to do with cross-cutting
concerns where one context talks to the goroutines of another context in
the tree. My guess is you signal that by closing channels appropriately,
but I'm not sure. Erlang systems provide a monitor-concept for this very
situation, in which you can subscribe to the lifetime of another part of
the system. If it fails, a message is sent to you about its failure so you
can take action.

[0]
http://jlouisramblings.blogspot.dk/2010/11/on-erlang-state-and-crashes.html

[1] Beware of a "poisonous" request however! A single bad request that
panics a system and then getting retried in the load balancer can easily
take down all of your backend worker pool.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-27 Thread roger peppe
On 26 April 2017 at 11:03, Jan Mercl <0xj...@gmail.com> wrote:
> On Wed, Apr 26, 2017 at 11:58 AM roger peppe  wrote:
>
>> FWIW I have seen real problems in production where long-running worker
> goroutines stopped working. We looked into it and found that certain rare
> requests were panicking, not releasing a mutex
> and thus preventing the long-running goroutine from acquiring that mutex.
>
> Code bug: Don't Lock without defer Unlock(). (I'm a sinner, just telling
> what I learned.)

Just for the record, there are *many* occurrences of Unlock without defer,
even in the standard library.

 $ cd $GOROOT
 $ find . -name '*.go' | grep -v test | xargs grep '\.Unlock(' |
grep -v defer | wc
 242 489   11123

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Sam Whited
On Wed, Apr 26, 2017 at 10:47 AM, Юрий Соколов  wrote:
> You are not quite right. Sometimes there is scope dependency between Lock
> and Unlock, ie Unlock happens not at function exit, but is triggered
> asynchronously by some condition.

If you can stomach the overhead of yet another stack frame allocation
you can always wrap your lock/unlock (or file close or whatever) and
logic in an anonymous closure. This of course may not be appropriate
for all situations, and isn't especially nice looking; anytime I find
myself doing this my general reaction is that I need to refactor so
that it's not necessary.

>   func() {
> m.Lock()
> defer m.Unlock()
>
> // Do some stuff
>   }()
>   // …
>   // outer function end
> }


—Sam

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Юрий Соколов
s/there is scope dependency/there is no scope dependency/

2017-04-26 18:47 GMT+03:00 Юрий Соколов :

> > Don't Lock without defer Unlock(). (I'm a sinner, just telling what I
> learned.)
>
> You are not quite right. Sometimes there is scope dependency between Lock
> and Unlock, ie Unlock happens not at function exit, but is triggered
> asynchronously
> by some condition.
> More: if you panic cause you already found state inconsistent, then there
> is
> no way to fix it, cause most likely you don't know how it became
> inconsistent.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Юрий Соколов
> Don't Lock without defer Unlock(). (I'm a sinner, just telling what I
learned.)

You are not quite right. Sometimes there is scope dependency between Lock
and Unlock, ie Unlock happens not at function exit, but is triggered
asynchronously
by some condition.
More: if you panic cause you already found state inconsistent, then there is
no way to fix it, cause most likely you don't know how it became
inconsistent.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Jan Mercl
On Wed, Apr 26, 2017 at 11:58 AM roger peppe  wrote:

> FWIW I have seen real problems in production where long-running worker
goroutines stopped working. We looked into it and found that certain rare
requests were panicking, not releasing a mutex
and thus preventing the long-running goroutine from acquiring that mutex.

Code bug: Don't Lock without defer Unlock(). (I'm a sinner, just telling
what I learned.)

-- 

-j

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread roger peppe
FWIW I have seen real problems in production where long-running worker
goroutines stopped working. We looked into it and found that certain rare
requests were panicking, not releasing a mutex
and thus preventing the long-running goroutine from acquiring that mutex.

This took ages to work out - made worse because I'd forgotten that
the stdlib recovers from panics in HTTP requests by default...

This is the kind of subtle problem that makes me think that recovering
from panics as a way of making the system more reliable can actually lead
to nastier problems further down the line.


On 26 April 2017 at 10:38, 'Axel Wagner' via golang-nuts
 wrote:
> On Wed, Apr 26, 2017 at 10:55 AM, Peter Herth  wrote:
>>
>>
>>
>> On Wed, Apr 26, 2017 at 3:07 AM, Dave Cheney  wrote:
>>>
>>>
>>>
>>> On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:

 I think those are all excellent things to do. They do not preclude the
 use of recovering from a panic to assist (emphasis on assist - it is
 certainly no silver bullet) in achieving fault tolerance.

 Assuming a web service that needs to be highly available, crashing the
 entire process due to one misbehaved goroutine is irresponsible.  There can
 be thousands of other active requests in flight that could fail gracefully
 as well, or succeed at their task.

 In this scenario, I believe a well behaved program should

 clearly log all information about the fault
>>>
>>> panic does that
>>
>>
>> No, panic certainly does not do that. It prints the stack trace. A proper
>> logger could add additional information about the program state at the point
>> of the panic, which is not visible from the stack trace. It also might at
>> least be reasonable to perform an auto-save before quitting.
>>
>>> Same; relying on a malfunctioning program to report its failure is like
>>> asking a sick human to perform their own surgery.
>>
>>
>> What makes you think that a panic implies that the whole program is
>> malfunctioning?
>
>
> But that is not the claim. The claim is, that if you discover a condition
> which can uniquely be attributed to a code bug, you should always err on the
> side of safety and prefer bailing out to continuing with a known-bad
> program. It's not "as I see this bug, I know the rest of the program is
> broken too", it's "as I see this bug, I can not pretend that it can't be".
>
>>
>> A panic should certainly taken seriously, and the computation in which it
>> happened should be aborted. But if you think of a functional programming
>> style
>
>
> If you are thinking of that, then you are not thinking about go. Go has
> shared state and mutable data. One of the major arguments here is, that
> there is a level of isolation of state, which is very good, from all we
> know, and that's the process; if the process dies, all locks are being
> released, file descriptors closed and memory freed, so it gives a known-good
> re-starting point. And that, in the presence of mutable state, potential
> data races and code bugs, that is the correct layer of isolation to fall
> back to. And I am also aware, that it's also not a perfect layer; you might
> have already corrupted on-disk state or abused a protocol to corrupt some
> state on the network. Those also need to be defended against, but process
> isolation still gives a good tradeoff between efficiency, convenience and
> safety.
>
>
> FWIW, I don't believe there is any convincing to be done here on either
> side. There are no technical arguments anymore; it is just that one set of
> people are holding one belief and another set of people are holding another
> belief. Both certainly do that based on technical arguments, but in the end,
> they are simply weighing them differently.
>
> I mean, I definitely agree that it would be great for a program to never
> crash. Or to have only panics which definitely can't be recovered from. Or
> to have all state isolated and safely expungeable. I agree, that the process
> being up for a larger timeslice is valuable and that other requests
> shouldn't fail because one of them misbehaved.
>
> I also assume you agree that errors should be noticed, caught and fixed. I
> assume you agree that crashing a binary will make the bug more noticeable.
> That crashing would allow you to recover from a safer and better-known
> state. And that being able to recover from any crash swiftly and
> architecting a service so that processes dying doesn't take it down is
> valuable and bugs shouldn't make it to production.
>
> The facts are straight, this is just a question of opinion and different
> experiences; and I don't see any way out of it than saying "agree to
> disagree; if you don't think you can tolerate panic's, you just can't use my
> stuff and I won't use yours, if I consider it to hide failures or be
> unergonomic".
> This argument becomes much more difficult, when I'm having it 

Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread 'Axel Wagner' via golang-nuts
On Wed, Apr 26, 2017 at 10:55 AM, Peter Herth  wrote:

>
>
> On Wed, Apr 26, 2017 at 3:07 AM, Dave Cheney  wrote:
>
>>
>>
>> On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:
>>>
>>> I think those are all excellent things to do. They do not preclude the
>>> use of recovering from a panic to assist (emphasis on assist - it is
>>> certainly no silver bullet) in achieving fault tolerance.
>>>
>>> Assuming a web service that needs to be highly available, crashing the
>>> entire process due to one misbehaved goroutine is irresponsible.  There can
>>> be thousands of other active requests in flight that could fail gracefully
>>> as well, or succeed at their task.
>>>
>>> In this scenario, I believe a well behaved program should
>>>
>>>- clearly log all information about the fault
>>>
>>> panic does that
>>
>
> No, panic certainly does not do that. It prints the stack trace. A proper
> logger could add additional information about the program state at the
> point of the panic, which is not visible from the stack trace. It also
> might at least be reasonable to perform an auto-save before quitting.
>
> Same; relying on a malfunctioning program to report its failure is like
>> asking a sick human to perform their own surgery.
>>
>
> What makes you think that a panic implies that the whole program is
> malfunctioning?
>

But *that is not the claim*. The claim is, that if you discover a condition
which can uniquely be attributed to a code bug, you should always err on
the side of safety and prefer bailing out to continuing with a known-bad
program. It's not "as I see this bug, I know the rest of the program is
broken too", it's "as I see this bug, I can not pretend that it can't be".


> A panic should certainly taken seriously, and the computation in which it
> happened should be aborted. But if you think of a functional programming
> style
>

If you are thinking of that, then you are not thinking about go. Go has
shared state and mutable data. One of the major arguments here is, that
there is a level of isolation of state, which is very good, from all we
know, and that's the process; if the process dies, all locks are being
released, file descriptors closed and memory freed, so it gives a
known-good re-starting point. And that, in the presence of mutable state,
potential data races and code bugs, that is the correct layer of isolation
to fall back to. And I am also aware, that it's also not a perfect layer;
you might have already corrupted on-disk state or abused a protocol to
corrupt some state on the network. Those also need to be defended against,
but process isolation still gives a good tradeoff between efficiency,
convenience and safety.


FWIW, I don't believe there is any convincing to be done here on either
side. There are no technical arguments anymore; it is just that one set of
people are holding one belief and another set of people are holding another
belief. Both certainly do that based on technical arguments, but in the
end, they are simply weighing them differently.

I mean, I definitely agree that it would be great for a program to never
crash. Or to have only panics which definitely can't be recovered from. Or
to have all state isolated and safely expungeable. I agree, that the
process being up for a larger timeslice is valuable and that other requests
shouldn't fail because one of them misbehaved.

I also assume you agree that errors should be noticed, caught and fixed. I
assume you agree that crashing a binary will make the bug more noticeable.
That crashing would allow you to recover from a safer and better-known
state. And that being able to recover from any crash swiftly and
architecting a service so that processes dying doesn't take it down is
valuable and bugs shouldn't make it to production.

The facts are straight, this is just a question of opinion and different
experiences; and I don't see any way out of it than saying "agree to
disagree; if you don't think you can tolerate panic's, you just can't use
my stuff and I won't use yours, if I consider it to hide failures or be
unergonomic".
This argument becomes much more difficult, when I'm having it with my
coworkers, as it *does* depend on how the service is run, which needs to be
decided by the team; in regards to this thread, at least we all have the
luxury that we can agree to disagree and move on :)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Peter Herth
On Wed, Apr 26, 2017 at 3:07 AM, Dave Cheney  wrote:

>
>
> On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:
>>
>> I think those are all excellent things to do. They do not preclude the
>> use of recovering from a panic to assist (emphasis on assist - it is
>> certainly no silver bullet) in achieving fault tolerance.
>>
>> Assuming a web service that needs to be highly available, crashing the
>> entire process due to one misbehaved goroutine is irresponsible.  There can
>> be thousands of other active requests in flight that could fail gracefully
>> as well, or succeed at their task.
>>
>> In this scenario, I believe a well behaved program should
>>
>>- clearly log all information about the fault
>>
>> panic does that
>

No, panic certainly does not do that. It prints the stack trace. A proper
logger could add additional information about the program state at the
point of the panic, which is not visible from the stack trace. It also
might at least be reasonable to perform an auto-save before quitting.

Same; relying on a malfunctioning program to report its failure is like
> asking a sick human to perform their own surgery.
>

What makes you think that a panic implies that the whole program is
malfunctioning? A panic should certainly taken seriously, and the
computation in which it happened should be aborted. But if you think of a
functional programming style, there are clear points in the call tree, at
which the recover could happen and the the computation can safely aborted
without impacting the rest of the program. If you think of any multi-user
software, at worst you can kill the session for a user, but do not
necessarily have to impact the other users.

Best regards,
Peter

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-26 Thread Юрий Соколов
`panic/recover` are really bad names for setjmp/longjmp. `throw/catch` are
much closer.

And C has `assert`. You may set handler for SIGABRT, but then you have to
know what are you doing. Usually it is set for backtrace printing only.

I mean: usual languages has clean separation between "wrong state or
input", "fast control flow" and "fatal" errors.
C has "return code + errno" for first, "setjmp/longjmp" for second and
"assert" for third.
Languages with exceptions have exceptions hierarhy with documented support
from runtime for "fatal exceptions".

Some languages choose process isolation for recovering from fatal error
(php, erlang... .Net has domains, but looks like .Ney Core doesn't).

Go has "return error" for first, abuses "panic/recover" for second, and in
absence of true process isolation, simply has no choice for "fatal error".

Go should have choice for "fatal error". Since many people want to recover
from "fatal error" (and this thread shows it clearly), Go should have true
"process isolation".

But it is just a dream.

26 апр. 2017 г. 8:35 AM пользователь "Bakul Shah" 
написал:

> Recover/panic need not be used *only* in case of a “critical” error. Just
> as in the case of setjmp/longjmp, there are other useful patterns. For
> example, a user may ask an interpreter to abandon its current computation
> by typing  ^C. This would be handled by a longjmp/panic() to *regain*
> control at the REPL level.
>
> There are actually at least three use cases:
> 1. Reduce the "semantic clutter" of having to check error return at every
> level just because a very deeply nested function may fail
> 2. Regain control as above in case of cancellation.
> 3. Indicate a critical error.
>
> For 1. (IMHO) the best mechanism was Pascal’s non-local goto. It *only*
> returned control higher up in the stack and to a lexically enclosing
> function - this could be checked at compile time. In Go panic/recover are
> analogs of longjmp/setjump and compile time checking is not possible to
> ensure that panic doen’t escape a package scope. Also, Go allows lexical
> nesting of unnamed functions but not named ones so one would not write,
> e.g. a parse() function as one giant function with multiple sub functions,
> one each for a parse rule. And concurrency complicates things.
>
> On Apr 25, 2017, at 7:52 PM, Dave Cheney  wrote:
>
> Yes, and then crashes the program. In the scenario I described, with
> thousands of other requests in flight that meet an abrubt end.  That could
> be incredibly costly, even if it's been planned for
>
>
> There are a host of other reasons that can take a server offline abruptly.
> It seems like a odd misallocation of resources to try to prevent one
> specific case - a goroutine panics due to a programming error or input
> validation failure -- both which are far better addressed with testing.
>
> To try to postpone the exit of a program after a critical error to me
> implies a much more complex testing and validation process that has
> identified all the shared state in the program and verified that it is
> correct in the case that a panic is caught.
>
> To me it seems simpler and more likely to have the root cause of the panic
> addressed to just let the program crash. The alternative, somehow
> firewalling the crash, and its effects on the internal state of your
> program, sounds unworkably optimistic.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/golang-nuts/rW6LB-9N37I/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Recover considered harmful

2017-04-25 Thread Kevin Conway
> To try to postpone the exit of a program after a critical error to me
implies a much more complex testing and validation process that has
identified all the shared state in the program and verified that it is
correct in the case that a panic is caught

There's an implicit argument here that the panic is, in fact, the result of
a critical error. This is my primary contention with the general use of
panic(). There is no guarantee for me as the consumer of a panicking
library that the panic in question is truly related to an unrecoverable
exception state that can only be resolved by a process exit

I posit the question one last time: How can the author of shared code
understand, in sufficient detail, all the possible ways that the code could
be leverage such that she or he could determine, objectively, that any
given process must stop when a particular error state is encountered?

> There are a host of other reasons that can take a server offline
abruptly. It seems like a odd misallocation of resources to try to prevent
one specific case.

This, generally, is the argument that "if you can't stop all exceptions
then why bother to stop any?". Contrary to exception states such as my
cloud provider has terminated my instance abruptly or my data center has
lost power, panic() uses are entirely defined by developers and not
strictly related to unrecoverable exception states. The process exit in the
case of a panic is entirely preventable unlike a true, systemic failure. To
say that panic leads to process termination and, therefore, panic is
equivalent to all process termination events is fallacious. I stand firm
that only the process developer knows when the process should exit.

To put it more succinctly: The idea that your exception state should stop
my process is, well, that's just, like, your opinion, man.

On Tue, Apr 25, 2017, 21:52 Dave Cheney  wrote:

> > Yes, and then crashes the program. In the scenario I described, with
> thousands of other requests in flight that meet an abrubt end.  That could
> be incredibly costly, even if it's been planned for
>
> There are a host of other reasons that can take a server offline abruptly.
> It seems like a odd misallocation of resources to try to prevent one
> specific case - a goroutine panics due to a programming error or input
> validation failure -- both which are far better addressed with testing.
>
> To try to postpone the exit of a program after a critical error to me
> implies a much more complex testing and validation process that has
> identified all the shared state in the program and verified that it is
> correct in the case that a panic is caught.
>
> To me it seems simpler and more likely to have the root cause of the panic
> addressed to just let the program crash. The alternative, somehow
> firewalling the crash, and its effects on the internal state of your
> program, sounds unworkably optimistic.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Recover considered harmful

2017-04-25 Thread Dave Cheney


On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:
>
> I think those are all excellent things to do. They do not preclude the use 
> of recovering from a panic to assist (emphasis on assist - it is certainly 
> no silver bullet) in achieving fault tolerance.
>
> Assuming a web service that needs to be highly available, crashing the 
> entire process due to one misbehaved goroutine is irresponsible.  There can 
> be thousands of other active requests in flight that could fail gracefully 
> as well, or succeed at their task.
>
> In this scenario, I believe a well behaved program should 
>
>- clearly log all information about the fault
>
> panic does that
 

>
>- remove itself from a load balancer
>
> your load balancer should detect that; it shouldn't wait to be told that a 
backend has failed.
 

>
>- 
>- alert some monitoring program that it has experienced critical errors
>
> The monitoring program should detect that the process exited; not the 
other way around.
 

>
>- depending on widespread severity, have a monitoring program alert a 
>human to inspect it
>
>
Same; relying on a malfunctioning program to report its failure is like 
asking a sick human to perform their own surgery. 
 

> On Tuesday, April 25, 2017 at 3:32:56 PM UTC-7, Dave Cheney wrote:
>>
>> Aside from arguments about using panic/recover to simulate longjmp inside 
>> recursive descent parsers I can think of no valid reason why recover should 
>> be used in production code. 
>>
>> Imo, the arguments about wrapping all goroutines in a catch all recover 
>> are solving th wrong problem​. 
>>
>> - if third party code you use panics regularly, maybe don't use it, or at 
>> least validate inputs passed to it to avoid provoking it. 
>> - if your program needs to be available, then rather than trying to 
>> diagnose the program's state internally, use something like daemontools, 
>> upstart, or systemd to restart it if it crashes. Dont forget there are 
>> plenty of other ways to exit a go program abruptly; os.Exit or log.Fatal 
>> are two that come to mind. Prefer only software. 
>> - if your program has to be highly available, then abandon the falsehood 
>> that a single machine can meet these requirements and invest your 
>> engineering effort in making your application run across multiple machines. 
>>
>> IMO there is no justification for using recover as a general safety net 
>> in production Go code. 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Recover considered harmful

2017-04-25 Thread Chris G
I think those are all excellent things to do. They do not preclude the use 
of recovering from a panic to assist (emphasis on assist - it is certainly 
no silver bullet) in achieving fault tolerance.

Assuming a web service that needs to be highly available, crashing the 
entire process due to one misbehaved goroutine is irresponsible.  There can 
be thousands of other active requests in flight that could fail gracefully 
as well, or succeed at their task.

In this scenario, I believe a well behaved program should 

   - clearly log all information about the fault
   - remove itself from a load balancer
   - alert some monitoring program that it has experienced critical errors
   - depending on widespread severity, have a monitoring program alert a 
   human to inspect it

On Tuesday, April 25, 2017 at 3:32:56 PM UTC-7, Dave Cheney wrote:
>
> Aside from arguments about using panic/recover to simulate longjmp inside 
> recursive descent parsers I can think of no valid reason why recover should 
> be used in production code. 
>
> Imo, the arguments about wrapping all goroutines in a catch all recover 
> are solving th wrong problem​. 
>
> - if third party code you use panics regularly, maybe don't use it, or at 
> least validate inputs passed to it to avoid provoking it. 
> - if your program needs to be available, then rather than trying to 
> diagnose the program's state internally, use something like daemontools, 
> upstart, or systemd to restart it if it crashes. Dont forget there are 
> plenty of other ways to exit a go program abruptly; os.Exit or log.Fatal 
> are two that come to mind. Prefer only software. 
> - if your program has to be highly available, then abandon the falsehood 
> that a single machine can meet these requirements and invest your 
> engineering effort in making your application run across multiple machines. 
>
> IMO there is no justification for using recover as a general safety net in 
> production Go code. 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: Recover considered harmful

2017-04-24 Thread Henry
I do think that panic should be avoided whenever possible. I had a third 
party library that panicked and crashed my application during the 
production run. If it were to return errors instead, I could have 
anticipated the problem and handled the situation with a bit more grace. 
The problem with panic is that it isn't obvious from the method signature 
that there is a possible alternate path. The author does not always 
document it. Thus, this hidden path is often unhandled and crashes the 
application. This may be acceptable during development phase, but not in 
the production run. 

I am pretty sure panic has its uses, but at the moment there are still 
people who use panic as a rare error. An error is an error. If you can 
return an error, you should return an error, even if it is rare or near 
impossible to happen. The fact that panic is used as a rare error makes it 
even dangerous because they represent the corner cases that are often 
unanticipated by the developers.

Nowadays I just wrap any third party library and use recover in case if any 
of them suddenly goes into shock and panic.

On Monday, April 24, 2017 at 4:02:55 PM UTC+7, Sokolov Yura wrote:

> Good day, people.
>
> Title is a bit controversial :-)
>
> I want to ask:
> - how useful `recover` for you?
> - Don't you think it is a bit "dangerous"?
>
> I mean: panic usually means programmer error, so if it happens, then
> program behaves incorrectly, and there is always a chance of serious
> state corruption. So, is there reason to recover at all?
>
> Also, presence of `recover` complicates implementation of `defer`.
> I believe, it could be optimized much harder in absence of `recover`
> (i.e. if program always exits on panic).
>
> I could be mistaken.
>
> Yura.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.