# Path: sygnal/exceptions.py
# class InvalidNotificationException(Exception):
#     pass
# 
# class NotificationDispatchException(Exception):
#     pass
# 
# class PushkinSetupException(Exception):
#     pass


import abc
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, TypeVar, overload
from matrix_common.regex import glob_to_regex
from opentracing import Span
from prometheus_client import Counter
from sygnal.exceptions import (
    InvalidNotificationException,
    NotificationDispatchException,
    PushkinSetupException,
)
    from sygnal.sygnal import Sygnal
    DEFAULT_CONCURRENCY_LIMIT = 512

    UNDERSTOOD_CONFIG_FIELDS = {"inflight_request_limit"}

    RATELIMITING_DROPPED_REQUESTS = Counter(
        "sygnal_inflight_request_limit_drop",
        "Number of notifications dropped because the number of inflight requests"
        " exceeded the configured inflight_request_limit.",
        labelnames=["pushkin"],
    )

    def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
        super().__init__(name, sygnal, config)
        self._concurrent_limit = config.get(
            "inflight_request_limit",
            ConcurrencyLimitedPushkin.DEFAULT_CONCURRENCY_LIMIT,
        )
        self._concurrent_now = 0

        # Grab an instance of the dropped request counter given our pushkin name.
        # Note this ensures the counter appears in metrics even if it hasn't yet
        # been incremented.
        dropped_requests = ConcurrencyLimitedPushkin.RATELIMITING_DROPPED_REQUESTS
        self.dropped_requests_counter = dropped_requests.labels(pushkin=name)

    async def dispatch_notification(
        self, n: Notification, device: Device, context: "NotificationContext"
    ) -> List[str]:
        if self._concurrent_now >= self._concurrent_limit:
            self.dropped_requests_counter.inc()

# Path: sygnal/exceptions.py
# class InvalidNotificationException(Exception):
#     pass
# 
# class NotificationDispatchException(Exception):
#     pass
# 
# class PushkinSetupException(Exception):
#     pass


# Path: sygnal/notifications.py
import abc
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, TypeVar, overload
from matrix_common.regex import glob_to_regex
from opentracing import Span
from prometheus_client import Counter
from sygnal.exceptions import (
    InvalidNotificationException,
    NotificationDispatchException,
    PushkinSetupException,
)
    from sygnal.sygnal import Sygnal

    DEFAULT_CONCURRENCY_LIMIT = 512

    UNDERSTOOD_CONFIG_FIELDS = {"inflight_request_limit"}

    RATELIMITING_DROPPED_REQUESTS = Counter(
        "sygnal_inflight_request_limit_drop",
        "Number of notifications dropped because the number of inflight requests"
        " exceeded the configured inflight_request_limit.",
        labelnames=["pushkin"],
    )

    def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
        super().__init__(name, sygnal, config)
        self._concurrent_limit = config.get(
            "inflight_request_limit",
            ConcurrencyLimitedPushkin.DEFAULT_CONCURRENCY_LIMIT,
        )
        self._concurrent_now = 0

        # Grab an instance of the dropped request counter given our pushkin name.
        # Note this ensures the counter appears in metrics even if it hasn't yet
        # been incremented.
        dropped_requests = ConcurrencyLimitedPushkin.RATELIMITING_DROPPED_REQUESTS
        self.dropped_requests_counter = dropped_requests.labels(pushkin=name)

    async def dispatch_notification(
        self, n: Notification, device: Device, context: "NotificationContext"
    ) -> List[str]:
        if self._concurrent_now >= self._concurrent_limit:
            self.dropped_requests_counter.inc()

            raise NotificationDispatchException(