Example #1
0
def handle_outgoing(msg):
    """
    Should return a requeue flag, so if it returns True, the message will be
    requeued and processed again immediately, and if it returns False, it will
    not be queued again.
    """
    backend = msg.outbound_backend
    sms_rate_limit = backend.get_sms_rate_limit()
    use_rate_limit = sms_rate_limit is not None
    use_load_balancing = isinstance(backend, PhoneLoadBalancingMixin)
    max_simultaneous_connections = backend.get_max_simultaneous_connections()
    orig_phone_number = None

    if use_load_balancing:
        orig_phone_number = backend.get_next_phone_number(msg.phone_number)

    if use_rate_limit:
        if use_load_balancing:
            redis_key = 'sms-rate-limit-backend-%s-phone-%s' % (
                backend.pk, orig_phone_number)
        else:
            redis_key = 'sms-rate-limit-backend-%s' % backend.pk

        if not rate_limit(
                redis_key, actions_allowed=sms_rate_limit, how_often=60):
            # Requeue the message and try it again shortly
            return True

    if max_simultaneous_connections:
        connection_slot_lock = get_connection_slot_lock(
            msg.phone_number, backend, max_simultaneous_connections)
        if not connection_slot_lock.acquire(blocking=False):
            # Requeue the message and try it again shortly
            return True

    if passes_trial_check(msg):
        result = send_message_via_backend(msg,
                                          backend=backend,
                                          orig_phone_number=orig_phone_number)

    if max_simultaneous_connections:
        release_lock(connection_slot_lock, True)

    if msg.error:
        remove_from_queue(msg)
    else:
        # Only do the following if an unrecoverable error did not happen
        if result:
            handle_successful_processing_attempt(msg)
        else:
            handle_unsuccessful_processing_attempt(msg)

    return False
Example #2
0
def handle_outgoing(msg):
    """
    Should return a requeue flag, so if it returns True, the message will be
    requeued and processed again immediately, and if it returns False, it will
    not be queued again.
    """
    backend = msg.outbound_backend
    sms_rate_limit = backend.get_sms_rate_limit()
    use_rate_limit = sms_rate_limit is not None
    use_load_balancing = isinstance(backend, PhoneLoadBalancingMixin)
    max_simultaneous_connections = backend.get_max_simultaneous_connections()
    orig_phone_number = None

    if use_load_balancing:
        orig_phone_number = backend.get_next_phone_number(msg.phone_number)

    if use_rate_limit:
        if use_load_balancing:
            redis_key = 'sms-rate-limit-backend-%s-phone-%s' % (backend.pk, orig_phone_number)
        else:
            redis_key = 'sms-rate-limit-backend-%s' % backend.pk

        if not rate_limit(redis_key, actions_allowed=sms_rate_limit, how_often=60):
            # Requeue the message and try it again shortly
            return True

    if max_simultaneous_connections:
        connection_slot_lock = get_connection_slot_lock(msg.phone_number, backend, max_simultaneous_connections)
        if not connection_slot_lock.acquire(blocking=False):
            # Requeue the message and try it again shortly
            return True

    if passes_trial_check(msg):
        result = send_message_via_backend(
            msg,
            backend=backend,
            orig_phone_number=orig_phone_number
        )

    if max_simultaneous_connections:
        release_lock(connection_slot_lock, True)

    if msg.error:
        remove_from_queue(msg)
    else:
        # Only do the following if an unrecoverable error did not happen
        if result:
            handle_successful_processing_attempt(msg)
        else:
            handle_unsuccessful_processing_attempt(msg)

    return False
Example #3
0
    def test_rate_limit(self):
        start = datetime.datetime.utcnow()
        rate_limit_count = 0
        iteration_count = 0

        while (datetime.datetime.utcnow() - start) < datetime.timedelta(seconds=5):
            # Only allow 10 actions every 3 seconds in an 5 second period of time
            if rate_limit('rate-limit-test', actions_allowed=10, how_often=3):
                rate_limit_count += 1
            iteration_count += 1

        self.assertEqual(rate_limit_count, 20)
        self.assertGreater(iteration_count, 20)
Example #4
0
def handle_outgoing(msg):
    """
    Should return a requeue flag, so if it returns True, the message will be
    requeued and processed again immediately, and if it returns False, it will
    not be queued again.
    """
    backend = msg.outbound_backend
    sms_rate_limit = backend.get_sms_rate_limit()
    use_rate_limit = sms_rate_limit is not None
    use_load_balancing = isinstance(backend, PhoneLoadBalancingMixin)
    orig_phone_number = None

    if use_load_balancing:
        orig_phone_number = backend.get_next_phone_number()

    if use_rate_limit:
        if use_load_balancing:
            redis_key = 'sms-rate-limit-backend-%s-phone-%s' % (backend.pk, orig_phone_number)
        else:
            redis_key = 'sms-rate-limit-backend-%s' % backend.pk

        if not rate_limit(redis_key, actions_allowed=sms_rate_limit, how_often=60):
            # Requeue the message and try it again shortly
            return True

    result = send_message_via_backend(
        msg,
        backend=backend,
        orig_phone_number=orig_phone_number
    )

    if not msg.error:
        # Only do the following if an unrecoverable error did not happen
        if result:
            handle_successful_processing_attempt(msg)
        else:
            handle_unsuccessful_processing_attempt(msg)

    return False