How to use the dramatiq.middleware.middleware.Middleware function in dramatiq

To help you get started, we’ve selected a few dramatiq examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github Bogdanp / dramatiq / dramatiq / middleware / time_limit.py View on Github external
import warnings
from threading import Thread
from time import monotonic, sleep

from ..logging import get_logger
from .middleware import Middleware
from .threading import Interrupt, current_platform, raise_thread_exception, supported_platforms


class TimeLimitExceeded(Interrupt):
    """Exception used to interrupt worker threads when actors exceed
    their time limits.
    """


class TimeLimit(Middleware):
    """Middleware that cancels actors that run for too long.
    Currently, this is only available on CPython.

    Note:
      This works by setting an async exception in the worker thread
      that runs the actor.  This means that the exception will only get
      called the next time that thread acquires the GIL.  Concretely,
      this means that this middleware can't cancel system calls.

    Parameters:
      time_limit(int): The maximum number of milliseconds actors may
        run for.
      interval(int): The interval (in milliseconds) with which to
        check for actors that have exceeded the limit.
    """
github Bogdanp / dramatiq / dramatiq / middleware / age_limit.py View on Github external
# your option) any later version.
#
# Dramatiq is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see .

from ..common import current_millis
from ..logging import get_logger
from .middleware import Middleware


class AgeLimit(Middleware):
    """Middleware that drops messages that have been in the queue for
    too long.

    Parameters:
      max_age(int): The default message age limit in millseconds.
        Defaults to ``None``, meaning that messages can exist
        indefinitely.
    """

    def __init__(self, *, max_age=None):
        self.logger = get_logger(__name__, type(self))
        self.max_age = max_age

    @property
    def actor_options(self):
        return {"max_age"}
github Bogdanp / dramatiq / dramatiq / middleware / group_callbacks.py View on Github external
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see .

import os

from ..rate_limits import Barrier
from .middleware import Middleware

GROUP_CALLBACK_BARRIER_TTL = int(os.getenv("dramatiq_group_callback_barrier_ttl", "86400000"))


class GroupCallbacks(Middleware):
    def __init__(self, rate_limiter_backend):
        self.rate_limiter_backend = rate_limiter_backend

    def after_process_message(self, broker, message, *, result=None, exception=None):
        from ..message import Message

        if exception is None:
            group_completion_uuid = message.options.get("group_completion_uuid")
            group_completion_callbacks = message.options.get("group_completion_callbacks")
            if group_completion_uuid and group_completion_callbacks:
                barrier = Barrier(self.rate_limiter_backend, group_completion_uuid, ttl=GROUP_CALLBACK_BARRIER_TTL)
                if barrier.wait(block=False):
                    for message in group_completion_callbacks:
                        broker.enqueue(Message(**message))
github Bogdanp / dramatiq / dramatiq / middleware / retries.py View on Github external
import traceback

from ..common import compute_backoff
from ..logging import get_logger
from .middleware import Middleware

#: The default minimum amount of backoff to apply to retried tasks.
DEFAULT_MIN_BACKOFF = 15000

#: The default maximum amount of backoff to apply to retried tasks.
#: Must be less than the max amount of time tasks can be delayed by.
DEFAULT_MAX_BACKOFF = 86400000 * 7


class Retries(Middleware):
    """Middleware that automatically retries failed tasks with
    exponential backoff.

    Parameters:
      max_retries(int): The maximum number of times tasks can be retried.
      min_backoff(int): The minimum amount of backoff milliseconds to
        apply to retried tasks.  Defaults to 15 seconds.
      max_backoff(int): The maximum amount of backoff milliseconds to
        apply to retried tasks.  Defaults to 7 days.
      retry_when(Callable[[int, Exception], bool]): An optional
        predicate that can be used to programmatically determine
        whether a task should be retried or not.  This takes
        precedence over `max_retries` when set.
    """

    def __init__(self, *, max_retries=20, min_backoff=None, max_backoff=None, retry_when=None):
github Bogdanp / dramatiq / dramatiq / middleware / callbacks.py View on Github external
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# Dramatiq is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see .

from .middleware import Middleware


class Callbacks(Middleware):
    """Middleware that lets you chain success and failure callbacks
    onto Actors.

    Parameters:
      on_failure(str): The name of an actor to send a message to on
        failure.
      on_success(str): The name of an actor to send a message to on
        success.
    """

    @property
    def actor_options(self):
        return {
            "on_failure",
            "on_success",
        }
github Bogdanp / dramatiq / dramatiq / middleware / prometheus.py View on Github external
#: The path to store the prometheus database files.  This path is
#: cleared before every run.
DB_PATH = os.getenv("dramatiq_prom_db", "%s/dramatiq-prometheus" % tempfile.gettempdir())

# Ensure the DB_PATH exists.
os.makedirs(DB_PATH, exist_ok=True)

#: The HTTP host the exposition server should bind to.
HTTP_HOST = os.getenv("dramatiq_prom_host", "0.0.0.0")

#: The HTTP port the exposition server should listen on.
HTTP_PORT = int(os.getenv("dramatiq_prom_port", "9191"))


class Prometheus(Middleware):
    """A middleware that exports stats via Prometheus_.

    .. _Prometheus: https://prometheus.io
    """

    def __init__(self):
        self.logger = get_logger(__name__, type(self))
        self.delayed_messages = set()
        self.message_start_times = {}

    @property
    def forks(self):
        return [_run_exposition_server]

    def after_process_boot(self, broker):
        os.environ["prometheus_multiproc_dir"] = DB_PATH
github Bogdanp / dramatiq / dramatiq / middleware / shutdown.py View on Github external
import threading
import warnings

from ..logging import get_logger
from .middleware import Middleware
from .threading import Interrupt, current_platform, raise_thread_exception, supported_platforms


class Shutdown(Interrupt):
    """Exception used to interrupt worker threads when their worker
    processes have been signaled for termination.
    """


class ShutdownNotifications(Middleware):
    """Middleware that interrupts actors whose worker process has been
    signaled for termination.
    Currently, this is only available on CPython.

    Note:
      This works by setting an async exception in the worker thread
      that runs the actor.  This means that the exception will only get
      called the next time that thread acquires the GIL.  Concretely,
      this means that this middleware can't cancel system calls.

    Parameters:
      notify_shutdown(bool): When true, the actor will be interrupted
        if the worker process was terminated.
    """

    def __init__(self, notify_shutdown=False):
github Bogdanp / dramatiq / dramatiq / middleware / current_message.py View on Github external
# your option) any later version.
#
# Dramatiq is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see .

from threading import local

from .middleware import Middleware


class CurrentMessage(Middleware):
    """Middleware that exposes the current message via a thread-local
    variable.

    Example:
      >>> import dramatiq
      >>> from dramatiq.middleware import CurrentMessage

      >>> @dramatiq.actor
      ... def example(x):
      ...     print(CurrentMessage.get_current_message())
      ...
      >>> example.send(1)

    """

    STATE = local()
github Bogdanp / dramatiq / dramatiq / middleware / pipelines.py View on Github external
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# Dramatiq is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see .

from .middleware import Middleware


class Pipelines(Middleware):
    """Middleware that lets you pipe actors together so that the
    output of one actor feeds into the input of another.

    Parameters:
      pipe_ignore(bool): When True, ignores the result of the previous
        actor in the pipeline.
      pipe_target(dict): A message representing the actor the current
        result should be fed into.
    """

    @property
    def actor_options(self):
        return {
            "pipe_ignore",
            "pipe_target",
        }