Assistant: 
User: Привет. Я тут делаю связь микросервисов через вебсокет. Вот написал класс для главного сервиса. Он получает все микросервисы из базы данных и должен каждый мониторить. Он должен выставлять статусы для микросервисов, работают они в данный момент или нет. Если нет то переподключаться.

Внимательно проанализируй код и посмотри, все ли ошибки я учёл, и нормальный ли вообще у меня код?
```python
import asyncio
import traceback
import websockets
from asyncio import Task
from websockets.exceptions import ConnectionClosed, WebSocketException
from websockets.client import WebSocketClientProtocol
from dataclasses import dataclass, field
from typing import Dict, Optional

from loguru import logger
from pydantic import BaseModel

from ..database.crud import CommonCRUD
from ..database.models import Microservice


@dataclass
class MicroserviceInfo:
    id: int
    name: str
    description: str
    ws: WebSocketClientProtocol
    manage_task: Task
    status: bool = field(default=False)


class BotResponse(BaseModel):
    name: str
    description: str


class WebSocketHandler:
    """Class to handle websocket communication with a microservice."""
    
    def __init__(self, url: str, microservice_id: int, ws: WebSocketClientProtocol):
        self.url = url
        self.microservice_id = microservice_id
        self.ws: WebSocketClientProtocol = ws
    
    async def receive_messages(self) -> None:
        """Receive and process messages."""
        if self.ws.closed:
            logger.error("Websocket is not connected.")
            return

        try:
            async for msg in self.ws:
                self.handle_message(msg)
        except ConnectionClosed:
            logger.warning(f"Connection closed for microservice {self.microservice_id}.")
        except Exception as e:
            logger.error(f"Error receiving message from microservice {self.microservice_id}: {str(e)}")
        finally:
            await self.ws.close()

    def handle_message(self, message: str) -> None:
        """Handle incoming messages from the websocket."""
        logger.debug(f"Received message from microservice {self.microservice_id}: {message}")
        ...

    async def close(self) -> None:
        """Close the websocket connection."""
        if self.ws:
            await self.ws.close()


class BotsManager:
    def __init__(self, db_crud: CommonCRUD, recheck_sec: int = 10) -> None:
        self.db_crud: CommonCRUD = db_crud
        self.recheck_sec: int = recheck_sec
        self.microservices: Dict[int, MicroserviceInfo] = {}
        self.control_task: Optional[Task] = None

    async def _microservice_ws(self, microservice_id: int, handler: WebSocketHandler) -> None:
        """Create a websocket connection and handle messages."""
        try:
            microservice: Optional[MicroserviceInfo] = self.microservices.get(microservice_id, None)

            if microservice:     
                self._set_microservice_status(microservice_id, True)
                handler = WebSocketHandler(microservice.url, microservice.id, microservice.ws)
                await handler.receive_messages()
        except Exception:
            logger.error(f"An error occurred while managing microservice {microservice_id}: {traceback.format_exc()}")
        finally:
            await handler.close()
            self._set_microservice_status(microservice_id, False)

    def _set_microservice_status(self, microservice_id: int, status: bool) -> None:
        """Set the status of a given microservice."""
        if microservice_id in self.microservices:
            self.microservices[microservice_id].status = status

    async def _reconnect_microservice(self, microservice: Microservice) -> bool:
        """Reconnect to a microservice by URL."""
        try:

            try:
                ws: WebSocketClientProtocol = await websockets.connect(self.url)
            except Exception:
                return False

            task: Task = asyncio.create_task(self._microservice_ws(microservice.id))
            self.microservices[microservice.id] = MicroserviceInfo(
                id=microservice.id,
                name=microservice.name,
                description=microservice.description,
                ws=ws,
                manage_task=task
            )
            return True
        except WebSocketException as e:
            logger.error(f"Failed to connect to \"{microservice.name}\" ({microservice.url}): {str(e)}")
            return False

    async def _bots_control_task(self) -> None:
        """Manage connections and reconnections to all microservices."""
        while True:
            try:
                current_microservices = await self.db_crud.get_microservices()
                for microservice in current_microservices:
                    info: Optional[MicroserviceInfo] = self.microservices.get(microservice.id)

                    if info and info.status:
                        continue
                    
                    if info and info.ws:
                        await info.ws.close()
                    
                    await self._reconnect_microservice(microservice)

                await asyncio.sleep(self.recheck_sec)
            except asyncio.CancelledError:
                logger.info("Bots control task was cancelled.")
                break
            except Exception as e:
                logger.error(f"Error in bots control task: {str(e)} | {traceback.format_exc()}")

    async def manage_microservices(self) -> None:
        """Start managing microservice connections."""
        if self.control_task and not self.control_task.cancelled():
            self.control_task.cancel()

        self.control_task = asyncio.create_task(self._bots_control_task())
        logger.debug("Microservices monitoring started.")

    async def close_connections(self) -> None:
        """Shutdown all connections and tasks."""
        logger.debug("Stopping microservice monitoring.")
        if self.control_task and not self.control_task.cancelled():
            self.control_task.cancel()

        for m in self.microservices.values():
            if m.manage_task and not m.manage_task.cancelled():
                m.manage_task.cancel()
            if m.ws:
                await m.ws.close()
```
Assistant: