Attempt to join heartbeat thread during close() (#1735)
Attempt to join heartbeat thread during close() (#1735)

Underlying issue here is a race on consumer.close() between the client, the connections/sockets, and the heartbeat thread. Although the heartbeat thread is signaled to close, we do not block for it. So when we go on to close the client and its underlying connections, if the heartbeat is still doing work it can cause errors/crashes if it attempts to access the now closed objects (selectors and/or sockets, primarily).

So this commit adds a blocking thread join to the heartbeat close. This may cause some additional blocking time on consumer.close() while the heartbeat thread finishes. But it should be small in average case and in the worst case will be no longer than the heartbeat_timeout_ms (though if we timeout the join, race errors may still occur).

Fix #1666
dpkp/kafka-python,wikimedia/operations-debs-python-kafka,ohmu/kafka-python,wikimedia/operations-debs-python-kafka,Yelp/kafka-python,mumrah/kafka-python,Aloomaio/kafka-python,mumrah/kafka-python,scrapinghub/kafka-python,DataDog/kafka-python,Aloomaio/kafka-python,scrapinghub/kafka-python,Yelp/kafka-python,dpkp/kafka-python,ohmu/kafka-python