I have a program that maintains a connection to a server with a periodic heartbeat. Every once in a while, the server stops responding to heartbeats and I have to reconnect. I implemented this with a timer that, if no response is heard after n seconds, will call reconnect. Every time this happens, I leak a thread and over time I eventually run out of threads.
Now, simplifying massively for an easy repro, this illlustrates how reconnecting after a delay and how always causes an increase in threads. How can I kill the old threads/sockets/selects (which may be waiting on a recv)?
import socket
import select
import threading
class Connection():
def tick(self):
print(threading.active_count()) # this increases every 1s!
# ... certain conditions not met / it's been too long, then:
self.reconnect()
def reconnect(self):
self.socket.shutdown(socket.SHUT_WR)
self.socket.close()
self.timer.cancel()
self.connect()
def connect(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((IP, TCP_PORT))
self.timer = threading.Timer(1, self.tick)
self.timer.start()
r,_,_ = select.select([self.socket], [], [])
if __name__ == '__main__':
Connection().connect()