Search code examples
pythonasynchronoustime

How do I implement a timeout in python


First I send an order to a microcontroller to generate a signal, when I send an order I add the order to a map which contains tracked orders, this order contains the frequency, and duration, this means that the MCU will send data to me for the duration specified at the desired frequency, this listening is done on a reading thread that receives UDP data. The thing I want to do is to stop the thread whenever there are no orders being tracked, to do this ideally I would like to make a timeout function that upon timeout would delete the element from the map.

code:

def read_pin(self,pin:Pin,duration,freq):
    self.tracked_orders.insert(Order(pin,duration,freq))

def __read_thread_UDP__(self):
    while len(self.tracked_orders)!= 0:
          # unparse the received message

TO DO

def __remove_order_by_timeout__(self,order):
    # pseudocode now 
    start = time.time()
    while start + order.duration < time.time():
        continue
    finally:
       self.tracked_orders.remove(order)

Ideally this should be something like an async function probably


Solution

  • Seems like this utility already existed, it is called timer within the threading module:

    I add the code below: from threading import Timer

    class Order:
        def __init__(self,pin_id, duration):
            self.pin_id = pin_id
            self.duration = duration
        def __str__(self)->str:
            return "[Order targeting {} should last {} seconds]".format(self.pin_id, self.duration)
    class MyClass:
        def __init__(self):
            self.orders = []
        def add_order(self, pin_id, duration):
            order = Order(pin_id, duration)
            self.orders.append(order)
            t = Timer(order.duration, self.expire_order, [order])
            t.start()
            print("Current orders: ")
            print(*self.orders)
        def expire_order(self, order):
            print("Order expired")
            self.orders.remove(order)
            print("Current orders: ")
            print(*self.orders)
    
    if __name__ == "__main__":
        my_class = MyClass()
        my_class.add_order(1, 5)
        my_class.add_order(2, 4)
    

    Which produces the following output: Program output This is exactly what I wanted, seems like I didn't know how to express my idea clearly, if someone can point me to similar SO questions I would appreciate it