Added debugging logic for our stopper pattern. #48
No reviewers
Labels
No labels
area: devops
area: discovery
area: docs
area: livestream
area: proposal
consider soon
dependencies
Epic
good first issue
hacktoberfest
help wanted
icebox
level: 1
level: 2
level: 3
level: 4
needs: exploration
needs: grooming
needs: priority
needs: repro
needs: tech design
on hold
priority: blocker
priority: high
priority: low
priority: medium
resilience
Tom's Wishlist
type: bug
type: discussion
type: improvement
type: new feature
type: refactor
type: task
type: testing
unplanned
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: LBRYCommunity/lbry.go#48
Loading…
Reference in a new issue
No description provided.
Delete branch "stopper_debugging"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Added debugging logic for our stopper pattern. Useful for when a stopper doesn't stop right away as expected.
I'd prefer not to have code like this in the library. It adds extra complexity and it's not something most people want most of the time. For one thing, go already provides tools for debugging. For another, the code in this is so simple that you could copy/paste it locally and add debugging statements if you wanted to. Finally, I haven to seen any other go library do things like this.
I have had to use it a number of times now, and figured instead of rewriting it every time, I would just commit it this time. It is VERY useful when there is a lot of concurrency, like in chainquery.
When using the stopper pattern, you link the stopping of the application to a specific subset of go routines. Knowing which go routine, where, is not ending fast enough, makes it really easy to debug and find the root cause.
Here the documentation referenced is clear how to get similar information. Niko and I did this once, but I can tell you this is MUCH easier and quicker than that method. There is no "figuring out" which routines are the applicable ones and no tracing the stack is required because the logging is functional.
I think this is a minimal impact and the user of the library can choose to do this based on their needs.
Minimal concurrency makes this added overhead, yes, but it is not required for the stopper to be used. The situations where you do not need this, can just use the standard methods. Although, I would argue it is still useful for when you get into a situation where a stopper doesn't stop right away.
Agreed, but I think if you find yourself re-writing the same thing over and over again, you might as well just finalize it. This being added to the library, makes it a 1 line change for me to turn on debugging of the stopper. Every time I close a routing it reports what else it is waiting on to finish closing.
I would be interested in an equally beneficial way of doing something similar. The key items I am looking for:
Different isn't always bad either. Domain specific debugging tactics can be priceless. This is just one specific to the stopper pattern. Not saying it can't be done better, but it works and fulfills it's expectations well.
I would argue that sometimes people think too generically. For example, look here. General debugging tactics. I get it, there are tools available. However, my need is very specific. delve is also another tool. This is overkill for me, but it is a generally acceptable and generic solution for debugging a golang app. I want to debug the stopper, quickly and easily.
If you still think this is too specific to my use case, I can remove this from the stopper library, just wanted to plead my case. When things are perfect, debugging is never needed, when there is a problem, you wish you had a switch like this to turn on.
Can you show me an example of where/how this is used?
this is an example. In the most recent example, the stopper was taking up to a minute to stop the application. So I added this and it told me right away the problem was in the mempoolsync and it was the go routine the stopper was waiting for. There are 2 dozen go routines running if I were to dump the app. I only care about the ones required to end with a graceful shutdown. Know, which ones the stopper is waiting on specifically, is really helpful output. In this implementation, I just change a line of code to turn it on.
i thought about it for a while but couldn't come up with a better approach that was also simple. i did have a few implementation suggestions and bugfixes: https://github.com/lbryio/lbry.go/pull/49
mu
instead ofl
for the mutex variable. its what ive seen used in the go standard libraries, and its technically more accurate (its a mutex, not a lock)make
ing the map until DebugAdd is called. then it is not made in the typical non-debug case (and you don't have to call a separate constructor.and now that ive thought about it some more, i think i misunderstood what you were trying to do with NewDebug. i see how it makes sense to leave AddNamed and DoneNamed in place, and simply turn on the debug behavior by changing the constructor. ignore that part of my suggested changes.
Ok I adjusted the other PR based on these comments.