Discovery: Improve the lifecycle management of the join control thread in zen discovery.

This PR also includes:
* Better exception handling in UnicastZenPing#ping
* In the join thread that runs the innerJoinCluster loop, remember the last known exception and throw that when assertions are enabled. We loop until inner join has successfully completed and if continues exceptions are thrown we should fail the test, because the exception shouldn't occur in production (at least not too often).
I think we can simplify the exception capturing here and just throw it as soon as we catch it (and assertions are enabled).