Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restart thread after exception on Python

I wrote this script in order to extract metadata from data on specific ftp then save it on specific directory and waits a random time and extract again etc... So there is 2 points : First : to extract from specific ftp Second : to save it and wait a random time which depends of the ftp used.

Sometime I have timeout issue from ftp. When it occurs there is no extract, save or waiting from the thread anymore. The others thread continue to work until they meet a timeout issue too.

I tried to catch exception in order to "restart" the thread which concerns by the ftp timeout issue. But nothing changes.

Someone please can help me to find a way to "restart" the thread?

Many thank's

class ftp_id(Thread):
    def __init__(self, ftpID):
        Thread.__init__(self)
        self.ftpID = ftpID
    def run(self):
        while True:
            with verrou:
                siteID = self.ftpID
                directory = str(datetime.now())[:-16].replace('-', '')
                filename = siteID + '_' + str(datetime.now())[:-7].replace(':', '').replace(' ', '_').replace('-', '') + '.txt'
                dictstr = myExtract(siteID)
                myWriteFile(directory, filename, dictstr)
                pendingtime = myWaiting(siteID, dictstr)
            time.sleep(pendingtime)
        except :
            self.stop = True
            self.stop = False
            self.start()
            self.join()

thread_01 = ftp_id("ftp-01")
thread_02 = ftp_id("ftp-02")
thread_03 = ftp_id("ftp-03")
thread_04 = ftp_id("ftp-04")

thread_01.start()
thread_02.start()
thread_03.start()
thread_04.start()

thread_01.join()
thread_02.join()
thread_03.join()
thread_04.join()
like image 217
Wansonce Avatar asked Oct 11 '17 21:10

Wansonce


People also ask

What happens when a thread throws an exception Python?

To catch the exception in the caller thread we maintain a separate variable exc, which is set to the exception raised when the called thread raises an exception. This exc is finally checked in the join() method and if is not None, then join simply raises the same exception.

How do you initialize a thread in Python?

Use the Python threading module to create a multi-threaded application. Use the Thread(function, args) to create a new thread. Call the start() method of the Thread class to start the thread. Call the join() method of the Thread class to wait for the thread to complete in the main thread.

How do you join a thread in Python?

A thread can be joined in Python by calling the Thread. join() method. This has the effect of blocking the current thread until the target thread that has been joined has terminated.


2 Answers

Threads cannot be restarted. So you should put the exception handling inside the while-block, and never exit the loop:

def download(server):
    while True:
        try:
            with verrou:
                now = datetime.now()
                directory = '{:%Y%m%d}'.format(now)
                filename = '{}_{:%Y%m%d_%H%M%S}.txt'.format(server, now)
                dictstr = myExtract(server)
                myWriteFile(directory, filename, dictstr)
                pendingtime = myWaiting(server, dictstr)
            time.sleep(pendingtime)
        except:
            # restart
            pass

threads = [
    Thread(target=download, args=(server,))
    for server in ["ftp-01", "ftp-02", "ftp-03", "ftp-04"
]

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()
like image 132
Daniel Avatar answered Sep 21 '22 14:09

Daniel


threads cannot be restarted in python ... of coarse you could just implement your own "thread" class thats not really a thread

class ftp_id(object): # this is a bad name for a class please see pep8
    def __init__(self, ftpID):
        super(ftp_id,self)
        self.ftpID = ftpID
        self.thread = None
        self.thread_stop = False
    def __getattr__(self):
        return getattr(self.thread)
    def start(self):
        if self.thread:
           self.thread_stop = True
           self.thread.terminate()
           self.thread.join()

        self.thread = threading.Thread(target = self.run)
        self.thread.start()
    def run(self):
        self.thread_stop = False
        while not self.thread_stop:
            with verrou:
                siteID = self.ftpID
                directory = str(datetime.now())[:-16].replace('-', '')
                filename = siteID + '_' + str(datetime.now())[:-7].replace(':', '').replace(' ', '_').replace('-', '') + '.txt'
                dictstr = myExtract(siteID)
                myWriteFile(directory, filename, dictstr)
                pendingtime = myWaiting(siteID, dictstr)
            time.sleep(pendingtime)

although i dont know if this actually answers your question

like image 45
Joran Beasley Avatar answered Sep 23 '22 14:09

Joran Beasley