Skip to content

Conversation

@jjb
Copy link

@jjb jjb commented Mar 3, 2018

note: this is based on #9, so that should be merged first. Then this can be rebased and look tidier.


This PR achieves two things.

  1. it introduces a more reliable and simple way to coordinate between threads and shut them down
  2. it defines behavior for TERM and INT signals - namely, it shuts down the thread pool, allowing them to finish their work first

So, it solves the problem described here: http://www.stathat.com/manual/code/ruby

the default StatHat::API Ruby methods are asynchronous. If you are using this gem in a script that is short-lived, you can use StatHat::SyncAPI to make synchronous calls to StatHat.

and clarified to me in a support ticket...

It’s possible the asynchronous requests didn’t finish [before the script exited].

It's also good behavior to have in the general case such as in a web server, which might also lose some items in the queue

n.b. each thread is given 5 seconds to shut down, serially (as opposed to the previous infinite time). If we want to give all threads 5 (or whatever) seconds to shut down from the start of stop_pool to guarantee that the overall time is fixed, we can use an approach like this.

let me know what you think!

jjb added 10 commits March 2, 2018 17:43
As of May 2017, successful submissions to stathat do
not return a body:

https://blog.stathat.com/2017/05/05/bandwidth.html

This changes the code and tests to accommodate this new behavior.

- the success code is now 200, not 204, so all 200s are
  considered successful
- because there is no body, we no longer check for resp.msg == "ok"
- oddly, failures return a "status: 500" in their body, but
  still have a 200 success code. I don't know if this is desired behavior or a bug,
  and I don't know how long this has been the case. i have written to StatHat support about it.
  so, we still parse for a code in the body and let it take precedent
- consistent use of {} for one-line blocks
- use do..end for more complicated block
While experimenting with the behavior of
StatHat::Reporter.instance.finish in master, I experienced
this message

    No live threads left. Deadlock?

And a stack trace every time. The cause was because
we call join on the threads, all of which are waiting,
via Queue#pop, for a new item to come from the queue.

I found that the best way to solve this is to close the Queue
before killing the threads. In going about this and reading the docs,
I found that the status of the Queue could be used to coordinate the threads,
which means there is no longer a need for the standalone synchronization
Mutex.

The cherry on top of this refactoring sundae is that Queue#pop
will immediately return nil when the Queue has been closed,
allowing us to use this return value as the condition
for continuing the loop.

I'm guessing that

    if th && th.alive?

was an attempt to accommodate the error that this change solves,
and regardless I feel those checks won't be needed or useful,
so I removed it.
@jjb jjb closed this Mar 19, 2018
@jjb jjb deleted the spool-down-threads-when-exiting branch March 19, 2018 21:10
@jjb jjb restored the spool-down-threads-when-exiting branch March 20, 2018 21:02
@jjb jjb reopened this Mar 20, 2018
- Waits 5 seconds to allow remaining queue to be cleared
- Prints warning message if processing stops before queue is
  finished
- Invokes existing signal trap behavior if there is any
- Doesn't need to check for default system signal behavior
  and invoke exit, because we only are trapping EXIT. If we
  were trapping INT or TERM, we would need to invoke exit.
  https://stackoverflow.com/questions/49393648/
@jjb jjb force-pushed the spool-down-threads-when-exiting branch from 82e57c8 to 8da65b0 Compare March 20, 2018 21:37
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.

1 participant