
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
import contextlib
import logging
from typing import Generator

from defence360agent.api.server import send_message, FGWSendMessgeException
from defence360agent.contracts.config import Core
from defence360agent.contracts.plugins import MessageSink
from defence360agent.internals.global_scope import g
from defence360agent.plugins.client import SendToServerClient
from defence360agent.utils import Scope

logger = logging.getLogger(__name__)


class SendToServerFGW(SendToServerClient, MessageSink):
    SCOPE = Scope.IM360

    @contextlib.contextmanager
    def _get_api(
        self,
    ) -> Generator[send_message.FileBasedGatewayAPI, None, None]:
        api = send_message.FileBasedGatewayAPI(Core.VERSION)

        yield self._set_api_attrs(api)

    async def _send_pending_messages(self) -> None:
        if self._pending.empty():
            return None

        batch = self._read_round_batch()
        messages = [(timestamp, message) for _, timestamp, message in batch]
        logger.info("Sending %s messages", len(batch))
        with self._get_api() as api:
            try:
                if g.get("DEBUG"):
                    logger.info(
                        "Writing messages to gw folder: %s",
                        list((m[0], m[1][:40], len(m[1])) for m in messages),
                    )
                await api.send_messages(messages)
                self._delete_stored(batch)
                if self._pending.qsize() > 0:
                    logger.info(
                        "Still need to send %s messages",
                        self._pending.qsize(),
                    )
            except FGWSendMessgeException:
                # the gateway write is all-or-nothing: nothing was confirmed
                self._requeue_fresh(batch)
                logger.warning(
                    "Unsuccessful to send %s messages",
                    self._pending.qsize(),
                )
            except BaseException:
                # cancellation included
                self._requeue_fresh(batch)
                raise
