4.0.0 (Unreleased)

Breaking Changes

  • REMOVED rejected.consumer.Consumer.reply as it was wonky and problematic
  • REMOVED rejected.consumer.Consumer.statsd_* functions that were deprecated in v3.13.0
  • REMOVED rejected.consumer.PublishingConsumer class that was deprecated in v3.17.0
  • REMOVED rejected.consumer.SmartPublishingConsumer class that was deprecated in v3.17.0
  • CHANGED when a message is returned from RabbitMQ so that it will no longer invoke rejected.consumer.Consumer.process

High-Level Changes

  • Refactored publishing with publisher confirmations enabled to return a tornado.concurrent.Future that can be yielded on to wait for confirmations to be returned
  • When publisher confirmations are enabled, all publishing is done with the mandatory flag set
  • Documentation cleaned up and rewritten in parts

Other Changes

  • ADDED rejected.consumer.Consumer.rpc_reply as a replacement of rejected.consumer.Consumer.reply
  • ADDED ability to to allow for keyword arguments
  • ADDED rejected.consumer.Consumer.IGNORE_OOB_STATS_CALLS to not log when rejected.consumer.Consumer.stats_* calls are made when no message is currently being processed
  • ADDED rejected.log.CorrelationID and rejected.log.NoCorrelationID as a replacement of rejected.log.CorrelationFilter
  • ADDED When a rejected.consumer.ConfigurationException is raised in prepare or process it’s not longer treated as an unhandled exception and will cause the consumer to shutdown
  • ADDED When a rejected.consumer.ConfigurationException is raised when initializing a consumer, it will now explicitly shutdown the consumer process
  • REMOVED code duplication when dealing with rejected.consumer.Consumer property methods
  • ADDED additional exception handling support in rejected.testing.AsyncTestCase
  • REMOVED catching of KeyboardInterrupt in rejected.consumer.Consumer.execute favoring catching higher up in the processing flow
  • ADDED call to Consumer.shutdown in rejected.testing.AsyncTestCase.tearDown (#25 nvllsvm)
  • CHANGED rejected.consumer.SmartConsumer parsing of content-type to use ietfparse, including charset for use in decoding in Python 3
  • CHANGED In rejected.consumer.SmartConsumer attempting to auto-encode or auto-serialize a non-string or non-bytes object with an invalid content encoding or content type will now raise a ValueError
  • CHANGED rejected.consumer.SmartConsumer auto-serialization of CSV to use csv.DictWriter and it now expects a list of dict rows
  • ADDED the raising of a rejected.consumer.MessageException in rejected.consumer.SmartConsumer when attempting to decode a message body and a decoding error is raised
  • CHANGED rejected.consumer.SmartConsumer auto-serialization to JSON to no longer ensure ASCII=True
  • ADDED type-hinting to bs4 parsing based upon the content-type in rejected.consumer.SmartConsumer

Bug Fixes

  • REMOVED extra call to rejected.consumer.Consumer.initialize in rejected.testing.AsyncTestCase._create_consumer #21 - dave-shawley
  • CHANGED rejected.consumer.Consumer to invoke on_finish even when an exception is raised during processing (#24)
  • CHANGED rejected.consumer.Consumer.io_loop to correctly return the proper loop


  • Add SSL connection flag support to configuration #20 - code-fabriek
  • Fix documentation for
  • Alter logging levels for connection failures
  • Add rejected.testing.AsyncTestCase.measurement


  • Try to handle a MCP process cleanup race condition better (Sentry REJECTED-DA)


  • Really fix a bug with the processing time and message age metrics


  • Fix a bug with the processing time and message age metrics
  • Catch a timeout when waiting on a zombie


  • Fix a bug in the new durations code


  • Sentry client changes: - Do not assign version, let the client figure that out - Do not specify the versions of loaded modules, let the client figure that out
  • Add, changing the behavior of recorded durations, creating a stack of timings instead of a single timing for the key. For InfluxDB submissions, if there is a only a single value, that metric will continue to submit as previous versions. If there are multiple, the average, min, max, median, and 95th percentile values will be submitted.
  • Add rejected.consumer.Consumer.stats_add_duration
  • Deprecate rejected.consumer.Consumer.stats_add_timing
  • Deprecate rejected.consumer.Consumer.stats_add_timing
  • Consumer tags are now in the format [consumer-name]-[os PID]
  • Created a base exception class rejected.consumer.RejectedException
  • rejected.consumer.ConsumerException, rejected.consumer.MessageException, and rejected.consumer.ProcessingException extend rejected.consumer.RejectedException
  • If a rejected.consumer.ConsumerException, rejected.consumer.MessageException, or rejected.consumer.ProcessingException are passed a keyword of metric, the consumer will automatically instrument a counter (statsd) or tag (InfluxDB) using the metric value.
  • rejected.consumer.ConsumerException, rejected.consumer.MessageException, and rejected.consumer.ProcessingException now support “new style” string formatting, automatically applying the args and keyword args that are passed into the creation of the exception.
  • Logging levels for exceptions changed: - rejected.consumer.ConsumerException are logged with error - `rejected.consumer.MessageException are logged with info - `rejected.consumer.ProcessingException are logged with warning
  • Fix the handling of child startup failures in the MCP
  • Fix a bug where un-configured consumers caused an exception in the MCP
  • Handle the edge case when a connection specified in the consumer config does not exist
  • Refactor how the version of the consumer module or package is determined
  • Add ProcessingException as a top-level package export
  • Fix misc docstrings
  • Fix the use of SIGABRT being used from child processes to notify the MCP when processes exit, instead register for SIGCHLD in the MCP.


  • Added rejected.testing.AsyncTestCase.published_messages and rejected.testing.PublishedMessage
  • Updated testing documentation
  • Updated the extras install for testing to install all testing dependencies
  • Made raven optional in rejected.testing


  • Fix the mocks in rejected.testing


  • Fix child process errors in shutdown
  • Fix unfiltered connection list returned to a process, introduced in v3.18.4


  • Move message age stat to Consumer, add method to override key


  • Treat NotImplementedError as an unhandled exception


  • Handle UNHANDLED_EXCEPTION in rejected.testing
  • Add the rejected.consumer.Consumer.io_loop property
  • Add the testing extras_require entry


  • Fix rejected.consumer.Consumer.require_setting


  • Fix the republishing of dropped messages


  • Fix ProcessingException AMQP header property assignment


  • Add connection as an attribute of channel in rejected.testing
  • Refactor how error text is extracted in rejected.consumer.Consumer.execute
  • When a message raises a ProcessingException, the string value of the exception is added to the AMQP message headers property
  • Messages dropped by a consumer can now be republished to a different exchange


  • Don’t start consuming until all connections are ready, fix shutdown


  • Fix publisher confirmations


  • Don’t blow up if stats is not defined in config


  • Documentation updates
  • Fix the test for Consumer configuration


  • rejected.testing updates
  • Add automatic assignment of correlation-id to rejected.consumer.Consumer
  • Only use sentry_client if it’s configured
  • Behavior change: Don’t spawn a process per connection, Spawn qty consumers with N connections
  • Add State.is_active
  • Add attributes for the connection the message was received on and if the message was published by the consumer and returned by RabbitMQ
  • Deprecate PublishingConsumer and SmartPublishingConsumer, folding them into Consumer and SmartConsumer respectively
  • Refactor to not have a singular channel instance, but rather a dict of channels for all connections
  • Add the ability to specify a channel to publish a message on, defaulting to the channel the message was delivered on
  • Add a property that indicates the current message that is being processed was returned by RabbitMQ
  • Change Consumer._execute and Consumer._set_channel to be “public” but will hide from docs.
  • Major Process refactor
    • Create a new Connection class to isolate direct AMQP connection/channel management from the Process class.
    • Alter Process to allow for multiple connections. This allows a consumer to consume from multiple AMQP broker connections or have AMQP broker connections that are not used for consuming. This could be useful for consuming from one broker and publishing to another broker in a different data center.
    • Add new enabled flag in the config for statsd and influxdb stats monitoring
    • Add a new behavior that puts pending messages sent into a collections.deque when a consumer is processing instead of just blocking on message delivery until processing is done. This could have a negative impact on memory utilization for consumers with large messages, but can be controlled by the qos_prefetch setting.
    • Process now sends messages returned from RabbitMQ to the Consumer
    • Process now will notify a consumer when RabbitMQ blocks and unblocks a connection


  • Allow for any AMQP properties when testing


  • Refactor and cleanup Sentry configuration and behavior


  • Fix InfluxDB error metrics


  • Update logging levels in rejected.consumer.Consumer._execute
  • Set exception error strings in per-request measurements


  • Better exception logging/sentry use in async consumers


  • Fix a bug using -o in Python 3


  • Add rejected.consumer.Consumer.send_exception_to_sentry


  • Add rejected.testing testing framework


  • Ensure that message age is always a float


  • Sentry Updates
    • Catch all top-level startup exceptions and send them to sentry
    • Fix the sending of consumer exceptions to sentry


  • Cleanup the shutdown and provide way to bypass cache in active_processes
  • If a consumer has not responded back with stats info after 3 attempts, it will be shutdown and a new consumer will take its place.
  • Add the consumer name to the extra values for logging


  • Properly handle finishing in rejected.consumer.Consumer.prepare
  • Fix default/class level config of error exchange, etc


  • Fix rejected.consumer.Consumer.stats_track_duration


  • Better backwards compatibility with rejected.consumer.Consumer “stats” commands


  • Bugfixes:
    • Construct the proper InfluxDB base URL
    • Fix the mixin __init__ signature to support the new kwargs
    • Remove overly verbose logging


  • Remove Python 2.6 support
  • Documentation Updates
  • consumer.Consumer: Accept multiple MESSAGE_TYPEs.
  • PublishingConsumer: Remove routing key from metric.
  • Add per-consumer sentry configuration
  • Refactor Consumer stats and statsd support
  • Update to use the per-message measurement
    • Changes how we submit measurements to statsd - Drops some redundant measurements that were submitted - Renames the exception measurement names
    • Adds support for InfluxDB