Python select.select leaking threads

Viewed 401

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()
1 Answers
Related