def process_sms(queued_sms_pk): """ queued_sms_pk - pk of a QueuedSMS entry """ client = get_redis_client() utcnow = get_utcnow() # Prevent more than one task from processing this SMS, just in case # the message got enqueued twice. message_lock = get_lock(client, "sms-queue-processing-%s" % queued_sms_pk) if message_lock.acquire(blocking=False): try: msg = QueuedSMS.objects.get(pk=queued_sms_pk) except QueuedSMS.DoesNotExist: # The message was already processed and removed from the queue release_lock(message_lock, True) return if message_is_stale(msg, utcnow): msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE) remove_from_queue(msg) release_lock(message_lock, True) return if msg.direction == OUTGOING: if msg.domain: domain_object = Domain.get_by_name(msg.domain) else: domain_object = None if domain_object and handle_domain_specific_delays(msg, domain_object, utcnow): release_lock(message_lock, True) return requeue = False # Process inbound SMS from a single contact one at a time recipient_block = msg.direction == INCOMING if (isinstance(msg.processed, bool) and not msg.processed and not msg.error and msg.datetime_to_process < utcnow): if recipient_block: recipient_lock = get_lock(client, "sms-queue-recipient-phone-%s" % msg.phone_number) recipient_lock.acquire(blocking=True) if msg.direction == OUTGOING: requeue = handle_outgoing(msg) elif msg.direction == INCOMING: handle_incoming(msg) else: msg.set_system_error(SMS.ERROR_INVALID_DIRECTION) remove_from_queue(msg) if recipient_block: release_lock(recipient_lock, True) release_lock(message_lock, True) if requeue: process_sms.delay(queued_sms_pk)
def handle_successful_processing_attempt(msg): utcnow = get_utcnow() msg.num_processing_attempts += 1 msg.processed = True msg.processed_timestamp = utcnow if msg.direction == OUTGOING: msg.date = utcnow msg.save() remove_from_queue(msg)
def process_sms(queued_sms_pk): """ queued_sms_pk - pk of a QueuedSMS entry """ client = get_redis_client() utcnow = get_utcnow() # Prevent more than one task from processing this SMS, just in case # the message got enqueued twice. message_lock = get_lock(client, "sms-queue-processing-%s" % queued_sms_pk) if message_lock.acquire(blocking=False): try: msg = QueuedSMS.objects.get(pk=queued_sms_pk) except QueuedSMS.DoesNotExist: # The message was already processed and removed from the queue release_lock(message_lock, True) return if message_is_stale(msg, utcnow): msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE) remove_from_queue(msg) release_lock(message_lock, True) return outbound_counter = None if msg.direction == OUTGOING: domain_object = Domain.get_by_name(msg.domain) if msg.domain else None if domain_object and handle_domain_specific_delays(msg, domain_object, utcnow): release_lock(message_lock, True) return outbound_counter = OutboundDailyCounter(domain_object) if not outbound_counter.can_send_outbound_sms(msg): release_lock(message_lock, True) return requeue = False # Process inbound SMS from a single contact one at a time recipient_block = msg.direction == INCOMING if (isinstance(msg.processed, bool) and not msg.processed and not msg.error and msg.datetime_to_process < utcnow): if recipient_block: recipient_lock = get_lock(client, "sms-queue-recipient-phone-%s" % msg.phone_number) recipient_lock.acquire(blocking=True) if msg.direction == OUTGOING: if ( msg.domain and msg.couch_recipient_doc_type and msg.couch_recipient and not is_contact_active(msg.domain, msg.couch_recipient_doc_type, msg.couch_recipient) ): msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE) remove_from_queue(msg) else: requeue = handle_outgoing(msg) elif msg.direction == INCOMING: try: handle_incoming(msg) except DelayProcessing: process_sms.apply_async([queued_sms_pk], countdown=60) if recipient_block: release_lock(recipient_lock, True) release_lock(message_lock, True) else: msg.set_system_error(SMS.ERROR_INVALID_DIRECTION) remove_from_queue(msg) if recipient_block: release_lock(recipient_lock, True) release_lock(message_lock, True) if requeue: if outbound_counter: outbound_counter.decrement() send_to_sms_queue(msg)
def process_sms(queued_sms_pk): """ queued_sms_pk - pk of a QueuedSMS entry """ utcnow = get_utcnow() # Prevent more than one task from processing this SMS, just in case # the message got enqueued twice. message_lock = get_lock("sms-queue-processing-%s" % queued_sms_pk) if message_lock.acquire(blocking=False): try: msg = QueuedSMS.objects.get(pk=queued_sms_pk) except QueuedSMS.DoesNotExist: # The message was already processed and removed from the queue release_lock(message_lock, True) return if message_is_stale(msg, utcnow): msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE) remove_from_queue(msg) release_lock(message_lock, True) return outbound_counter = None if msg.direction == OUTGOING: domain_object = Domain.get_by_name(msg.domain) if msg.domain else None if domain_object and handle_domain_specific_delays(msg, domain_object, utcnow): release_lock(message_lock, True) return outbound_counter = OutboundDailyCounter(domain_object) if not outbound_counter.can_send_outbound_sms(msg): release_lock(message_lock, True) return requeue = False # Process inbound SMS from a single contact one at a time recipient_block = msg.direction == INCOMING # We check datetime_to_process against utcnow plus a small amount # of time because timestamps can differ between machines which # can cause us to miss sending the message the first time and # result in an unnecessary delay. if ( isinstance(msg.processed, bool) and not msg.processed and not msg.error and msg.datetime_to_process < (utcnow + timedelta(seconds=10)) ): if recipient_block: recipient_lock = get_lock( "sms-queue-recipient-phone-%s" % msg.phone_number) recipient_lock.acquire(blocking=True) if msg.direction == OUTGOING: if ( msg.domain and msg.couch_recipient_doc_type and msg.couch_recipient and not is_contact_active(msg.domain, msg.couch_recipient_doc_type, msg.couch_recipient) ): msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE) remove_from_queue(msg) else: requeue = handle_outgoing(msg) elif msg.direction == INCOMING: try: handle_incoming(msg) except DelayProcessing: process_sms.apply_async([queued_sms_pk], countdown=60) if recipient_block: release_lock(recipient_lock, True) release_lock(message_lock, True) else: msg.set_system_error(SMS.ERROR_INVALID_DIRECTION) remove_from_queue(msg) if recipient_block: release_lock(recipient_lock, True) release_lock(message_lock, True) if requeue: if outbound_counter: outbound_counter.decrement() send_to_sms_queue(msg)