python/lambdaQueue.py

from datetime import datetime, timedelta
import time
import threading
from queue import Queue, Empty

class Work(threading.Thread):
    """ a working thread
            has a workinput queue of lambdas which are executed with a parameter
            every second some regular work is done
            stops after Work.running is set to False """
    running = True;
    def __init__(self):
        threading.Thread.__init__(self)
        self.queue = Queue()

    def run(self):
        print(f"{datetime.now()} Work.run begin")
        i = 0
        nxTi = datetime.now() + timedelta(seconds=1)
        while Work.running:
            i = i + 1
            w = 0
            try:
                # if we can get an element from the queue (before timeout) execute it
                w = self.queue.get(True, (nxTi - datetime.now()).total_seconds())
                w(i)
            except Empty:
                # Timeout, no input in given time
                print(f"{datetime.now()} Work {i} get empty")
                nxTi = datetime.now() + timedelta(seconds=1)
        print(f"{datetime.now()} getting -1")
        try: w = self.queue.get(True, -1)
        except: print(f"{datetime.now()} except end")

        # let the work do its work (async)
w = Work()
w.start()
        
        
class AW(threading.Thread):
    """ async Worker - gives queues lambdas to w in regular intervals """
    def run(self):
        for i in range(3):
            w.queue.put(lambda a: print(f"{datetime.now()} AW {i} Work {a}"))
            time.sleep(1.23)

AW().start()

        # word for w in regular intervalse
for j in range(3):
    w.queue.put(lambda w: print(f"{datetime.now()} lambda {j} Work {w}"))
    time.sleep(1.7)

        # we also may use a function
def f(w):
    print(f"{datetime.now()} fun#1 {j} Work {w}")
    print(f"{datetime.now()} fun#2 {j} Work {w}")
w.queue.put(f)
time.sleep(0.01)
Work.running = False
print(f"{datetime.now()} main running=False")