def handle_long_action_in_progress(self) -> str:
        """Figure out what to do with the task AsyncExecutor is performing."""
        if self.has_lock() and self.update_lock():
            if self._async_executor.scheduled_action == 'doing crash recovery in a single user mode':
                time_left = global_config.primary_start_timeout - (time.time() - self._crash_recovery_started)
                if time_left <= 0 and self.is_failover_possible():
                    logger.info("Demoting self because crash recovery is taking too long")
                    self.state_handler.cancellable.cancel(True)
                    self.demote('immediate')
                    return 'terminated crash recovery because of startup timeout'

            return 'updated leader lock during {0}'.format(self._async_executor.scheduled_action)
        elif not self.state_handler.bootstrapping and not self.is_paused():
            # Don't have lock, make sure we are not promoting or starting up a primary in the background
            if self._async_executor.scheduled_action == 'promote':
                with self._async_response:
                    cancel = self._async_response.cancel()
                if cancel:
                    self.state_handler.cancellable.cancel()
                    return 'lost leader before promote'

            if self.state_handler.role == PostgresqlRole.PRIMARY:
                logger.info('Demoting primary during %s', self._async_executor.scheduled_action)
                if self._async_executor.scheduled_action in ('restart', 'starting primary after failure'):
                    # Restart needs a special interlocking cancel because postmaster may be just started in a
                    # background thread and has not even written a pid file yet.
                    with self._async_executor.critical_task as task:
                        if not task.cancel() and isinstance(task.result, PostmasterProcess):
                            self.state_handler.terminate_starting_postmaster(postmaster=task.result)
                self.demote('immediate-nolock')
                return 'lost leader lock during {0}'.format(self._async_executor.scheduled_action)
        if self.cluster.is_unlocked():
            logger.info('not healthy enough for leader race')

        return '{0} in progress'.format(self._async_executor.scheduled_action)
Figure out what to do with the task AsyncExecutor is performing.
patroni/ha.py