Skip to content

Sync

Overview

The sync module provides the types for the 9 synchronous start/stop/restart methods on MQRESTSession. These methods wrap fire-and-forget START and STOP commands with a polling loop that waits until the object reaches its target state or the timeout expires.

SyncOperation

An enum indicating the operation that was performed:

class SyncOperation(Enum):
    STARTED    = "started"     # Object confirmed running
    STOPPED    = "stopped"     # Object confirmed stopped
    RESTARTED  = "restarted"   # Stop-then-start completed

SyncConfig

Configuration controlling the polling behaviour:

@dataclass
class SyncConfig:
    timeout: float = 30.0         # Max seconds before raising
    poll_interval: float = 1.0    # Seconds between polls
Attribute Type Description
timeout float Maximum seconds to wait before raising MQRESTTimeoutError
poll_interval float Seconds between DISPLAY *STATUS polls

SyncResult

Contains the outcome of a sync operation:

class SyncResult(NamedTuple):
    operation: SyncOperation   # What happened
    polls: int                 # Number of status polls issued
    elapsed: float             # Wall-clock seconds from command to confirmation
Attribute Type Description
operation SyncOperation What happened: STARTED, STOPPED, or RESTARTED
polls int Number of status polls issued
elapsed float Wall-clock seconds from command to confirmation

Method signature pattern

All 9 sync methods follow the same signature pattern:

result = session.start_channel_sync("TO.PARTNER")
result = session.start_channel_sync("TO.PARTNER", config=SyncConfig(timeout=60))

Usage

from pymqrest.sync import SyncConfig

result = session.start_channel_sync("TO.PARTNER")

match result.operation:
    case SyncOperation.STARTED:
        print(f"Running after {result.polls} polls")
    case SyncOperation.STOPPED:
        print("Stopped")
    case SyncOperation.RESTARTED:
        print(f"Restarted in {result.elapsed:.1f}s")

See Sync Methods for the full conceptual overview, polling behaviour, and the complete list of available methods.

API reference

Configuration for synchronous polling operations.

Attributes:

Name Type Description
timeout_seconds float

Maximum wall-clock seconds to wait for the object to reach the target state.

poll_interval_seconds float

Seconds to sleep between status polls.

Source code in src/pymqrest/sync.py
@dataclass(frozen=True)
class SyncConfig:
    """Configuration for synchronous polling operations.

    Attributes:
        timeout_seconds: Maximum wall-clock seconds to wait for the
            object to reach the target state.
        poll_interval_seconds: Seconds to sleep between status polls.

    """

    timeout_seconds: float = 30.0
    poll_interval_seconds: float = 1.0

timeout_seconds = 30.0 class-attribute instance-attribute

poll_interval_seconds = 1.0 class-attribute instance-attribute

__init__(timeout_seconds=30.0, poll_interval_seconds=1.0)

Bases: Enum

Operation performed by a synchronous wrapper.

Attributes:

Name Type Description
STARTED

The object was started and confirmed running.

STOPPED

The object was stopped and confirmed stopped.

RESTARTED

The object was stopped then started.

Source code in src/pymqrest/sync.py
class SyncOperation(enum.Enum):
    """Operation performed by a synchronous wrapper.

    Attributes:
        STARTED: The object was started and confirmed running.
        STOPPED: The object was stopped and confirmed stopped.
        RESTARTED: The object was stopped then started.

    """

    STARTED = "started"
    STOPPED = "stopped"
    RESTARTED = "restarted"

STARTED = 'started' class-attribute instance-attribute

STOPPED = 'stopped' class-attribute instance-attribute

RESTARTED = 'restarted' class-attribute instance-attribute

Result of a synchronous start/stop/restart operation.

Attributes:

Name Type Description
operation SyncOperation

The :class:SyncOperation that was performed.

polls int

Total number of status polls issued.

elapsed_seconds float

Total wall-clock seconds from command to target state confirmation.

Source code in src/pymqrest/sync.py
@dataclass(frozen=True)
class SyncResult:
    """Result of a synchronous start/stop/restart operation.

    Attributes:
        operation: The :class:`SyncOperation` that was performed.
        polls: Total number of status polls issued.
        elapsed_seconds: Total wall-clock seconds from command to
            target state confirmation.

    """

    operation: SyncOperation
    polls: int
    elapsed_seconds: float

operation instance-attribute

polls instance-attribute

elapsed_seconds instance-attribute

__init__(operation, polls, elapsed_seconds)

Mixin providing synchronous start/stop/restart wrappers.

Each *_sync method issues the MQSC command then polls the corresponding DISPLAY *STATUS until the object reaches a stable state or the timeout expires. restart_* methods perform a synchronous stop followed by a synchronous start.

Source code in src/pymqrest/sync.py
class MQRESTSyncMixin:
    """Mixin providing synchronous start/stop/restart wrappers.

    Each ``*_sync`` method issues the MQSC command then polls the
    corresponding ``DISPLAY *STATUS`` until the object reaches a
    stable state or the timeout expires.  ``restart_*`` methods
    perform a synchronous stop followed by a synchronous start.
    """

    def _mqsc_command(  # noqa: PLR0913
        self,
        *,
        command: str,
        mqsc_qualifier: str,
        name: str | None,
        request_parameters: Mapping[str, object] | None,
        response_parameters: Sequence[str] | None,
        where: str | None = None,
    ) -> list[dict[str, object]]:
        raise NotImplementedError  # pragma: no cover

    # ------------------------------------------------------------------
    # Channel
    # ------------------------------------------------------------------

    def start_channel_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Start a channel and wait until it is running.

        Args:
            name: Channel name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the channel does not reach RUNNING
                within the timeout.

        """
        return self._start_and_poll(name, _CHANNEL_CONFIG, config)

    def stop_channel_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop a channel and wait until it is stopped.

        Args:
            name: Channel name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the channel does not reach STOPPED
                within the timeout.

        """
        return self._stop_and_poll(name, _CHANNEL_CONFIG, config)

    def restart_channel(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop then start a channel, waiting for each phase.

        Each phase gets the full timeout independently.

        Args:
            name: Channel name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with total polls and elapsed time
            across both phases.

        Raises:
            MQRESTTimeoutError: If either phase exceeds the timeout.

        """
        return self._restart(name, _CHANNEL_CONFIG, config)

    # ------------------------------------------------------------------
    # Listener
    # ------------------------------------------------------------------

    def start_listener_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Start a listener and wait until it is running.

        Args:
            name: Listener name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the listener does not reach RUNNING
                within the timeout.

        """
        return self._start_and_poll(name, _LISTENER_CONFIG, config)

    def stop_listener_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop a listener and wait until it is stopped.

        Args:
            name: Listener name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the listener does not reach STOPPED
                within the timeout.

        """
        return self._stop_and_poll(name, _LISTENER_CONFIG, config)

    def restart_listener(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop then start a listener, waiting for each phase.

        Each phase gets the full timeout independently.

        Args:
            name: Listener name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with total polls and elapsed time
            across both phases.

        Raises:
            MQRESTTimeoutError: If either phase exceeds the timeout.

        """
        return self._restart(name, _LISTENER_CONFIG, config)

    # ------------------------------------------------------------------
    # Service
    # ------------------------------------------------------------------

    def start_service_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Start a service and wait until it is running.

        Args:
            name: Service name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the service does not reach RUNNING
                within the timeout.

        """
        return self._start_and_poll(name, _SERVICE_CONFIG, config)

    def stop_service_sync(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop a service and wait until it is stopped.

        Args:
            name: Service name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with operation details.

        Raises:
            MQRESTTimeoutError: If the service does not reach STOPPED
                within the timeout.

        """
        return self._stop_and_poll(name, _SERVICE_CONFIG, config)

    def restart_service(
        self,
        name: str,
        *,
        config: SyncConfig | None = None,
    ) -> SyncResult:
        """Stop then start a service, waiting for each phase.

        Each phase gets the full timeout independently.

        Args:
            name: Service name.
            config: Optional polling configuration.

        Returns:
            A :class:`SyncResult` with total polls and elapsed time
            across both phases.

        Raises:
            MQRESTTimeoutError: If either phase exceeds the timeout.

        """
        return self._restart(name, _SERVICE_CONFIG, config)

    # ------------------------------------------------------------------
    # Core polling helpers
    # ------------------------------------------------------------------

    def _start_and_poll(
        self,
        name: str,
        obj_config: _ObjectTypeConfig,
        config: SyncConfig | None,
    ) -> SyncResult:
        """Issue START then poll until the object is RUNNING."""
        cfg = config or SyncConfig()
        self._mqsc_command(
            command="START",
            mqsc_qualifier=obj_config.start_qualifier,
            name=name,
            request_parameters=None,
            response_parameters=None,
        )
        polls = 0
        start_time = time.monotonic()
        while True:
            time.sleep(cfg.poll_interval_seconds)
            status_rows = self._mqsc_command(
                command="DISPLAY",
                mqsc_qualifier=obj_config.status_qualifier,
                name=name,
                request_parameters=None,
                response_parameters=["all"],
            )
            polls += 1
            if _has_status(status_rows, obj_config.status_keys, _RUNNING_VALUES):
                elapsed = time.monotonic() - start_time
                return SyncResult(SyncOperation.STARTED, polls=polls, elapsed_seconds=elapsed)
            elapsed = time.monotonic() - start_time
            if elapsed >= cfg.timeout_seconds:
                msg = f"{obj_config.start_qualifier} '{name}' did not reach RUNNING within {cfg.timeout_seconds}s"
                raise MQRESTTimeoutError(
                    msg,
                    name=name,
                    operation="start",
                    elapsed=elapsed,
                )

    def _stop_and_poll(
        self,
        name: str,
        obj_config: _ObjectTypeConfig,
        config: SyncConfig | None,
    ) -> SyncResult:
        """Issue STOP then poll until the object is STOPPED."""
        cfg = config or SyncConfig()
        self._mqsc_command(
            command="STOP",
            mqsc_qualifier=obj_config.stop_qualifier,
            name=name,
            request_parameters=None,
            response_parameters=None,
        )
        polls = 0
        start_time = time.monotonic()
        while True:
            time.sleep(cfg.poll_interval_seconds)
            status_rows = self._mqsc_command(
                command="DISPLAY",
                mqsc_qualifier=obj_config.status_qualifier,
                name=name,
                request_parameters=None,
                response_parameters=["all"],
            )
            polls += 1
            if obj_config.empty_means_stopped and not status_rows:
                elapsed = time.monotonic() - start_time
                return SyncResult(SyncOperation.STOPPED, polls=polls, elapsed_seconds=elapsed)
            if _has_status(status_rows, obj_config.status_keys, _STOPPED_VALUES):
                elapsed = time.monotonic() - start_time
                return SyncResult(SyncOperation.STOPPED, polls=polls, elapsed_seconds=elapsed)
            elapsed = time.monotonic() - start_time
            if elapsed >= cfg.timeout_seconds:
                msg = f"{obj_config.stop_qualifier} '{name}' did not reach STOPPED within {cfg.timeout_seconds}s"
                raise MQRESTTimeoutError(
                    msg,
                    name=name,
                    operation="stop",
                    elapsed=elapsed,
                )

    def _restart(
        self,
        name: str,
        obj_config: _ObjectTypeConfig,
        config: SyncConfig | None,
    ) -> SyncResult:
        """Stop-sync then start-sync, returning combined totals."""
        stop_result = self._stop_and_poll(name, obj_config, config)
        start_result = self._start_and_poll(name, obj_config, config)
        return SyncResult(
            SyncOperation.RESTARTED,
            polls=stop_result.polls + start_result.polls,
            elapsed_seconds=stop_result.elapsed_seconds + start_result.elapsed_seconds,
        )

_mqsc_command(*, command, mqsc_qualifier, name, request_parameters, response_parameters, where=None)

Source code in src/pymqrest/sync.py
def _mqsc_command(  # noqa: PLR0913
    self,
    *,
    command: str,
    mqsc_qualifier: str,
    name: str | None,
    request_parameters: Mapping[str, object] | None,
    response_parameters: Sequence[str] | None,
    where: str | None = None,
) -> list[dict[str, object]]:
    raise NotImplementedError  # pragma: no cover

start_channel_sync(name, *, config=None)

Start a channel and wait until it is running.

Parameters:

Name Type Description Default
name str

Channel name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the channel does not reach RUNNING within the timeout.

Source code in src/pymqrest/sync.py
def start_channel_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Start a channel and wait until it is running.

    Args:
        name: Channel name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the channel does not reach RUNNING
            within the timeout.

    """
    return self._start_and_poll(name, _CHANNEL_CONFIG, config)

stop_channel_sync(name, *, config=None)

Stop a channel and wait until it is stopped.

Parameters:

Name Type Description Default
name str

Channel name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the channel does not reach STOPPED within the timeout.

Source code in src/pymqrest/sync.py
def stop_channel_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop a channel and wait until it is stopped.

    Args:
        name: Channel name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the channel does not reach STOPPED
            within the timeout.

    """
    return self._stop_and_poll(name, _CHANNEL_CONFIG, config)

restart_channel(name, *, config=None)

Stop then start a channel, waiting for each phase.

Each phase gets the full timeout independently.

Parameters:

Name Type Description Default
name str

Channel name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with total polls and elapsed time

SyncResult

across both phases.

Raises:

Type Description
MQRESTTimeoutError

If either phase exceeds the timeout.

Source code in src/pymqrest/sync.py
def restart_channel(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop then start a channel, waiting for each phase.

    Each phase gets the full timeout independently.

    Args:
        name: Channel name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with total polls and elapsed time
        across both phases.

    Raises:
        MQRESTTimeoutError: If either phase exceeds the timeout.

    """
    return self._restart(name, _CHANNEL_CONFIG, config)

start_listener_sync(name, *, config=None)

Start a listener and wait until it is running.

Parameters:

Name Type Description Default
name str

Listener name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the listener does not reach RUNNING within the timeout.

Source code in src/pymqrest/sync.py
def start_listener_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Start a listener and wait until it is running.

    Args:
        name: Listener name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the listener does not reach RUNNING
            within the timeout.

    """
    return self._start_and_poll(name, _LISTENER_CONFIG, config)

stop_listener_sync(name, *, config=None)

Stop a listener and wait until it is stopped.

Parameters:

Name Type Description Default
name str

Listener name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the listener does not reach STOPPED within the timeout.

Source code in src/pymqrest/sync.py
def stop_listener_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop a listener and wait until it is stopped.

    Args:
        name: Listener name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the listener does not reach STOPPED
            within the timeout.

    """
    return self._stop_and_poll(name, _LISTENER_CONFIG, config)

restart_listener(name, *, config=None)

Stop then start a listener, waiting for each phase.

Each phase gets the full timeout independently.

Parameters:

Name Type Description Default
name str

Listener name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with total polls and elapsed time

SyncResult

across both phases.

Raises:

Type Description
MQRESTTimeoutError

If either phase exceeds the timeout.

Source code in src/pymqrest/sync.py
def restart_listener(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop then start a listener, waiting for each phase.

    Each phase gets the full timeout independently.

    Args:
        name: Listener name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with total polls and elapsed time
        across both phases.

    Raises:
        MQRESTTimeoutError: If either phase exceeds the timeout.

    """
    return self._restart(name, _LISTENER_CONFIG, config)

start_service_sync(name, *, config=None)

Start a service and wait until it is running.

Parameters:

Name Type Description Default
name str

Service name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the service does not reach RUNNING within the timeout.

Source code in src/pymqrest/sync.py
def start_service_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Start a service and wait until it is running.

    Args:
        name: Service name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the service does not reach RUNNING
            within the timeout.

    """
    return self._start_and_poll(name, _SERVICE_CONFIG, config)

stop_service_sync(name, *, config=None)

Stop a service and wait until it is stopped.

Parameters:

Name Type Description Default
name str

Service name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with operation details.

Raises:

Type Description
MQRESTTimeoutError

If the service does not reach STOPPED within the timeout.

Source code in src/pymqrest/sync.py
def stop_service_sync(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop a service and wait until it is stopped.

    Args:
        name: Service name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with operation details.

    Raises:
        MQRESTTimeoutError: If the service does not reach STOPPED
            within the timeout.

    """
    return self._stop_and_poll(name, _SERVICE_CONFIG, config)

restart_service(name, *, config=None)

Stop then start a service, waiting for each phase.

Each phase gets the full timeout independently.

Parameters:

Name Type Description Default
name str

Service name.

required
config SyncConfig | None

Optional polling configuration.

None

Returns:

Name Type Description
A SyncResult

class:SyncResult with total polls and elapsed time

SyncResult

across both phases.

Raises:

Type Description
MQRESTTimeoutError

If either phase exceeds the timeout.

Source code in src/pymqrest/sync.py
def restart_service(
    self,
    name: str,
    *,
    config: SyncConfig | None = None,
) -> SyncResult:
    """Stop then start a service, waiting for each phase.

    Each phase gets the full timeout independently.

    Args:
        name: Service name.
        config: Optional polling configuration.

    Returns:
        A :class:`SyncResult` with total polls and elapsed time
        across both phases.

    Raises:
        MQRESTTimeoutError: If either phase exceeds the timeout.

    """
    return self._restart(name, _SERVICE_CONFIG, config)

_start_and_poll(name, obj_config, config)

Issue START then poll until the object is RUNNING.

Source code in src/pymqrest/sync.py
def _start_and_poll(
    self,
    name: str,
    obj_config: _ObjectTypeConfig,
    config: SyncConfig | None,
) -> SyncResult:
    """Issue START then poll until the object is RUNNING."""
    cfg = config or SyncConfig()
    self._mqsc_command(
        command="START",
        mqsc_qualifier=obj_config.start_qualifier,
        name=name,
        request_parameters=None,
        response_parameters=None,
    )
    polls = 0
    start_time = time.monotonic()
    while True:
        time.sleep(cfg.poll_interval_seconds)
        status_rows = self._mqsc_command(
            command="DISPLAY",
            mqsc_qualifier=obj_config.status_qualifier,
            name=name,
            request_parameters=None,
            response_parameters=["all"],
        )
        polls += 1
        if _has_status(status_rows, obj_config.status_keys, _RUNNING_VALUES):
            elapsed = time.monotonic() - start_time
            return SyncResult(SyncOperation.STARTED, polls=polls, elapsed_seconds=elapsed)
        elapsed = time.monotonic() - start_time
        if elapsed >= cfg.timeout_seconds:
            msg = f"{obj_config.start_qualifier} '{name}' did not reach RUNNING within {cfg.timeout_seconds}s"
            raise MQRESTTimeoutError(
                msg,
                name=name,
                operation="start",
                elapsed=elapsed,
            )

_stop_and_poll(name, obj_config, config)

Issue STOP then poll until the object is STOPPED.

Source code in src/pymqrest/sync.py
def _stop_and_poll(
    self,
    name: str,
    obj_config: _ObjectTypeConfig,
    config: SyncConfig | None,
) -> SyncResult:
    """Issue STOP then poll until the object is STOPPED."""
    cfg = config or SyncConfig()
    self._mqsc_command(
        command="STOP",
        mqsc_qualifier=obj_config.stop_qualifier,
        name=name,
        request_parameters=None,
        response_parameters=None,
    )
    polls = 0
    start_time = time.monotonic()
    while True:
        time.sleep(cfg.poll_interval_seconds)
        status_rows = self._mqsc_command(
            command="DISPLAY",
            mqsc_qualifier=obj_config.status_qualifier,
            name=name,
            request_parameters=None,
            response_parameters=["all"],
        )
        polls += 1
        if obj_config.empty_means_stopped and not status_rows:
            elapsed = time.monotonic() - start_time
            return SyncResult(SyncOperation.STOPPED, polls=polls, elapsed_seconds=elapsed)
        if _has_status(status_rows, obj_config.status_keys, _STOPPED_VALUES):
            elapsed = time.monotonic() - start_time
            return SyncResult(SyncOperation.STOPPED, polls=polls, elapsed_seconds=elapsed)
        elapsed = time.monotonic() - start_time
        if elapsed >= cfg.timeout_seconds:
            msg = f"{obj_config.stop_qualifier} '{name}' did not reach STOPPED within {cfg.timeout_seconds}s"
            raise MQRESTTimeoutError(
                msg,
                name=name,
                operation="stop",
                elapsed=elapsed,
            )

_restart(name, obj_config, config)

Stop-sync then start-sync, returning combined totals.

Source code in src/pymqrest/sync.py
def _restart(
    self,
    name: str,
    obj_config: _ObjectTypeConfig,
    config: SyncConfig | None,
) -> SyncResult:
    """Stop-sync then start-sync, returning combined totals."""
    stop_result = self._stop_and_poll(name, obj_config, config)
    start_result = self._start_and_poll(name, obj_config, config)
    return SyncResult(
        SyncOperation.RESTARTED,
        polls=stop_result.polls + start_result.polls,
        elapsed_seconds=stop_result.elapsed_seconds + start_result.elapsed_seconds,
    )