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

move thread caller stack and rescue+log to a common place #487

Closed
ColinDKelley opened this issue Aug 27, 2020 · 5 comments
Closed

move thread caller stack and rescue+log to a common place #487

ColinDKelley opened this issue Aug 27, 2020 · 5 comments
Milestone

Comments

@ColinDKelley
Copy link
Collaborator

ColinDKelley commented Aug 27, 2020

I was happy to see this PR remove the "ThreadPool": #483 . It was a nice improvement to track the threads inside the listeners rather than globally.

All the threads should have a rescue-and-log at the top. And it's very handing to remember the original caller who created the thread to help identify it. That's done here:
https://github.com/guard/listen/blob/master/lib/listen/adapter/base.rb#L72-L85

Let's put that in a general place and use it everywhere that threads are created. (And not raise from the top of the thread. That falls into some odd behavior in Ruby, where that exception can later be raised by code that calls join.)

Also: I don't believe the .kill is necessary here, since once a Thread#join returns, that means the thread has exited, right?
https://github.com/guard/listen/blob/master/lib/listen/event/loop.rb#L64

@ColinDKelley
Copy link
Collaborator Author

@jonathanhefner Are you good with the changes I suggested here? If so, I'll make a PR.

  1. Creating a wrapper around thread creation that keeps track of the thread creator and rescues/logs any exceptions, including that info.
  2. Dropping .kill after thread.join. The Ruby Thread#join documentation says:

Does not return until thr exits or until the given limit seconds have passed.

And we're not passing limit seconds, so the part after or doesn't apply here.

@jonathanhefner
Copy link
Contributor

@ColinDKelley I'm not actually affiliated with the Listen project, so I may not be the right person to ask. (I was fixing #476 to address some downstream issues in Rails.)

  1. Creating a wrapper around thread creation that keeps track of the thread creator and rescues/logs any exceptions, including that info.

It might be good to ellaborate more about how this would be useful. From a cursory search, it looks like there are three places where Thread.new is called, and each has a rescue:

But perhaps these don't provide all the information you want when debugging? Or is this more about refactoring?

2. Dropping .kill after thread.join. The Ruby Thread#join documentation says:

Does not return until thr exits or until the given limit seconds have passed.

And we're not passing limit seconds, so the part after or doesn't apply here.

I think you're correct!

@ColinDKelley
Copy link
Collaborator Author

@jonathanhefner Ah, you're correct that each Thread.new does have a rescue. Now that I study them, I find there are 3 approaches to rescue and log--all of them different! I think it will be cleaner and more DRY to unify them.

Sorry I wasn't clear about the debugging information. One of the 3 Thread.new instances here keeps a copy of the caller who created the thread: calling_stack = caller.dup. I don't think the dup is necessary. But I do think keeping the caller is a great idea so that we can link any exceptions that get logged here to the caller who created that thread. Lacking that, it can be a real mystery sometimes.

And related, I believe the re-raise here is an anti-pattern: Once the exception is logged, it has been handled. Re-raising it will cause it to be stored by Ruby and raised again later when we call thread.join, which would be redundant at best. Although the comment says # for unit tests mostly, I didn't find any tests failing when I removed it.

I'll make a PR with these suggestions. And I'll drop the combinations of .kill and .join.

ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Sep 20, 2020
@ColinDKelley
Copy link
Collaborator Author

PR: #496

ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 14, 2020
@ColinDKelley ColinDKelley added this to the v3.3.0 milestone Oct 14, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
ColinDKelley added a commit to Invoca/listen that referenced this issue Oct 29, 2020
@ColinDKelley
Copy link
Collaborator Author

Fix merged into master for v3.3 milestone.

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

2 participants