def call_method(*args, **kwargs): task = Task( fun, use_daemon_thread=use_daemon_thread, thread_name=thread_name, event_name=event_name, use_async_loop=use_async_loop, ) task.start(*args, **kwargs) return task
class CollectExecutionCallsContext: def __init__( self, parent, fun, on_error: str = None, use_daemon_thread: bool = True, ignore_waiting_calls_timeout: Union[timedelta, float] = None, ): super().__init__() thread_name = f"ccc_async::{fun.__module__}::{fun.__qualname__}" if parent is not None: thread_name = f"{thread_name} (oid: {id(parent)})" self.task = Task(fun, thread_name=thread_name, use_daemon_thread=use_daemon_thread) self.is_waiting_on_call = False self.was_triggered = False self.parent = parent self.invoke_error: Callable = None self.last_executed = None self.ignore_waiting_calls_timeout: timedelta = ( None if ignore_waiting_calls_timeout is None else ( ignore_waiting_calls_timeout if isinstance(ignore_waiting_calls_timeout, timedelta) else timedelta(ignore_waiting_calls_timeout) ) ) if isinstance(on_error, str): assert parent is not None, ValueError("Cannot assign on_error as string to a non class method") assert hasattr(parent, on_error), ValueError( f"Error method not found in {parent.__class__.__name__}.{on_error}" ) self.invoke_error = getattr(parent, on_error) elif on_error is not None: assert callable(on_error), ValueError("On error must be a callable or a string") self.invoke_error = on_error self.task.on(self.task.error_event_name, lambda task, ex: self.on_error(ex)) self.task.on(self.task.event_name, lambda *args, **kwargs: self.on_done()) def on_done(self): self.was_triggered = False if self.is_waiting_on_call: self.is_waiting_on_call = False elapsed = None if self.last_executed is None else datetime.now() - self.last_executed if ( self.ignore_waiting_calls_timeout is None or elapsed is None or (self.ignore_waiting_calls_timeout <= elapsed) ): self.execute_as_task() def on_error(self, ex): if self.invoke_error is not None: self.invoke_error(ex) self.on_done() def execute_as_task(self, *args): self.was_triggered = True self.last_executed = datetime.now() if self.parent is not None: self.task.start(self.parent) else: self.task.start()