예제 #1
0
 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
예제 #2
0
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()