# Path: vnpy/rpc/common.py
# HEARTBEAT_TOPIC: str = "heartbeat"
# 
# HEARTBEAT_TOLERANCE: int = 30


import threading
import zmq
from datetime import datetime
from functools import lru_cache
from typing import Any
from zmq.backend.cython.constants import NOBLOCK
from .common import HEARTBEAT_TOPIC, HEARTBEAT_TOLERANCE
    def stop(self) -> None:
        """
        Stop RpcClient
        """
        if not self._active:
            return

        # Stop RpcClient status
        self._active = False

    def join(self) -> None:
        # Wait for RpcClient thread to exit
        if self._thread and self._thread.is_alive():
            self._thread.join()
        self._thread = None

    def run(self) -> None:
        """
        Run RpcClient function
        """
        pull_tolerance = HEARTBEAT_TOLERANCE * 1000

        while self._active:
            if not self._socket_sub.poll(pull_tolerance):
                self.on_disconnected()
                continue

            # Receive data from subscribe socket
            topic, data = self._socket_sub.recv_pyobj(flags=NOBLOCK)


# Path: vnpy/rpc/common.py
# HEARTBEAT_TOPIC: str = "heartbeat"
# 
# HEARTBEAT_TOLERANCE: int = 30


# Path: vnpy/rpc/client.py
import threading
import zmq
from datetime import datetime
from functools import lru_cache
from typing import Any
from zmq.backend.cython.constants import NOBLOCK
from .common import HEARTBEAT_TOPIC, HEARTBEAT_TOLERANCE

    def stop(self) -> None:
        """
        Stop RpcClient
        """
        if not self._active:
            return

        # Stop RpcClient status
        self._active = False

    def join(self) -> None:
        # Wait for RpcClient thread to exit
        if self._thread and self._thread.is_alive():
            self._thread.join()
        self._thread = None

    def run(self) -> None:
        """
        Run RpcClient function
        """
        pull_tolerance = HEARTBEAT_TOLERANCE * 1000

        while self._active:
            if not self._socket_sub.poll(pull_tolerance):
                self.on_disconnected()
                continue

            # Receive data from subscribe socket
            topic, data = self._socket_sub.recv_pyobj(flags=NOBLOCK)


            if topic == HEARTBEAT_TOPIC: