Repository: Avaiga/taipy
File: taipy/core/job/job.py (Python)

Code before:
            ).total_seconds()

        return (datetime.now() - self._status_change_records[Status.PENDING.name]).total_seconds()

    @property
    @_self_reload(_MANAGER_NAME)
    def blocked_duration(self) -> Optional[float]:
        """Get the duration of the job in the blocked state in seconds.

        Returns:
            Optional[float]: The duration of the job in the blocked state in seconds.
                - If the job is not running, None is returned.
                - If the job is not blocked, the blocked time is the duration
                  from the submission to the current time.
        """
        if Status.BLOCKED.name not in self._status_change_records:
            return None

        if self.is_finished():
            return (self.finished_time - self._status_change_records[Status.BLOCKED.name]).total_seconds()
        if self.is_running():
            return (
                self._status_change_records[Status.RUNNING.name] - self._status_change_records[Status.BLOCKED.name]
            ).total_seconds()

        return (datetime.now() - self._status_change_records[Status.BLOCKED.name]).total_seconds()

    @property  # type: ignore
    @_self_reload(_MANAGER_NAME)
    def stacktrace(self) -> List[str]:
        return self._stacktrace

    @stacktrace.setter  # type: ignore
    @_self_setter(_MANAGER_NAME)
    def stacktrace(self, val):
        self._stacktrace = val

    @property
    def version(self):
        return self._version

    def __contains__(self, task: "Task"):
        return self.task.id == task.id

    def __lt__(self, other):
        return self.creation_date.timestamp() < other.creation_date.timestamp()

    def __le__(self, other):
        return self.creation_date.timestamp() <= other.creation_date.timestamp()

    def __gt__(self, other):

Review comment (suggestion):
Is it correct?

What if the job got blocked, unblocked(pending), running, and completed?
Your method returns the difference between the completion time and the blocked time. while we expect to return PENDING - BLOCKED.

Let me propose something like the following:
```suggestion
        if self.is_blocked():
            # Currently blocked
            return (datetime.now() - self._status_change_records[Status.BLOCKED.name]).total_seconds()
        if Status.PENDING.name in self._status_change_records:
            # has been pending at a point
            return (
                self._status_change_records[Status.PENDING.name] - self._status_change_records[Status.BLOCKED.name]
            ).total_seconds()
        if self.is_finished():
            # has never been pending but is finished
            return (self.finished_time - self._status_change_records[Status.BLOCKED.name]).total_seconds()
        # has never been pending, never been finished
        # I don't see any configuration where we should enter here. 
        # Am I correct?
        raise AppropriateError
```

Code after:
            ).total_seconds()

        return (datetime.now() - self._status_change_records[Status.PENDING.name]).total_seconds()

    @property
    @_self_reload(_MANAGER_NAME)
    def blocked_duration(self) -> Optional[float]:
        """Get the duration of the job in the blocked state in seconds.

        Returns:
            Optional[float]: The duration of the job in the blocked state in seconds.
                - If the job is not running, None is returned.
                - If the job is not blocked, the blocked time is the duration
                  from the submission to the current time.
        """
        if Status.BLOCKED.name not in self._status_change_records:
            return None

        if Status.PENDING.name in self._status_change_records:
            return (
                self._status_change_records[Status.PENDING.name] - self._status_change_records[Status.BLOCKED.name]
            ).total_seconds()
        if self.is_finished():
            return (self.finished_at - self._status_change_records[Status.BLOCKED.name]).total_seconds()

        # If pending time is not recorded, and the job is not finished, the only possible status left is blocked
        # which means the current status is blocked.
        return (datetime.now() - self._status_change_records[Status.BLOCKED.name]).total_seconds()

    @property  # type: ignore
    @_self_reload(_MANAGER_NAME)
    def stacktrace(self) -> List[str]:
        return self._stacktrace

    @stacktrace.setter  # type: ignore
    @_self_setter(_MANAGER_NAME)
    def stacktrace(self, val):
        self._stacktrace = val

    @property
    def version(self):
        return self._version

    def __contains__(self, task: "Task"):
        return self.task.id == task.id

    def __lt__(self, other):
        return self.creation_date.timestamp() < other.creation_date.timestamp()

    def __le__(self, other):
        return self.creation_date.timestamp() <= other.creation_date.timestamp()