In order to do a thread interrupt, we need to get the actual thread, stored
in the RubyRunnable instance and tell it to interrupt. Future does not
provide a mechanism for passing an interrupt to the thread running it.
If the runnable is not being executed by a thread (not yet, or already
done) do nothing.
If the future has not yet run and or is running and not yet complete.
We defined "alive" for a FutureThread to be the following:
The Runnable has not yet been submitted to the Executor. This is equivalent
to a Ruby thread that has not yet been scheduled to run. Because Ruby
considered a thread alive immediately, a FutureThread with no Future yet
is still considered alive, because it will eventually be submitted.
The Runnable has been submitted to the Executor but no Future has
been returned yet. There's a bit of a race here if we expect future to
not be null, since the runnable could be submitted to the Executor and
complete execution before the future is ever assigned. This manifested
as Thread.current.status from within a thread coming up as false...
because isAlive returned false if the future was still null.
The Runnable has been submitted to the Executor, the Future has
been assigned, but the Future is not "done" yet. The thread is running,
and we report it is alive.
All other cases are considered "not alive" and we return fals here.
We check for zero millis here because Future appears to wait for zero if
you pass it zero, where Thread behavior is to wait forever.
We also catch and swallow CancellationException because it means the Future
was cancelled before it ran, and is therefore as done as it will ever be.