def handle_current_event(self): content = self.memoized_schedule.get_current_event_content(self) if isinstance(self, CaseScheduleInstanceMixin): content.set_context(case=self.case, schedule_instance=self) else: content.set_context(schedule_instance=self) logged_event = MessagingEvent.create_from_schedule_instance( self, content) recipient_count = 0 for recipient in self.expand_recipients(): recipient_count += 1 content.send(recipient, logged_event) # As a precaution, always explicitly move to the next event after processing the current # event to prevent ever getting stuck on the current event. self.memoized_schedule.move_to_next_event(self) self.memoized_schedule.move_to_next_event_not_in_the_past(self) # Update the MessagingEvent for reporting if recipient_count == 0: logged_event.error(MessagingEvent.ERROR_NO_RECIPIENT) else: logged_event.completed()
def send_current_event_content_to_recipients(self): content = self.memoized_schedule.get_current_event_content(self) if isinstance(content, (IVRSurveyContent, SMSCallbackContent)): raise TypeError( "IVR and Callback use cases are no longer supported. " "How did this schedule instance end up as active?") if isinstance(self, CaseScheduleInstanceMixin): content.set_context(case=self.case, schedule_instance=self) else: content.set_context(schedule_instance=self) logged_event = MessagingEvent.create_from_schedule_instance( self, content) recipient_count = 0 for recipient in self.expand_recipients(): recipient_count += 1 # The framework will retry sending a non-processed schedule instance # once every hour. # If we are processing a long list of recipients here and an error # occurs half-way through, we don't want to reprocess the entire list # of recipients again when the framework retries it an hour later. # So we use a non-blocking lock tied to the event due time and recipient # to make sure that we don't try resending the same content to the same # recipient more than once in the event of a retry. # If we succeed in sending the content, we don't release the lock so # that it won't retry later. If we fail in sending the content, we release # the lock so that it will retry later. lock = self.get_content_send_lock(recipient) if lock.acquire(blocking=False): try: content.send(recipient, logged_event) except: error = sys.exc_info()[1] # Release the lock if an error happened so that we can try sending # to this recipient again later. lock.release() logged_event.error( MessagingEvent.ERROR_INTERNAL_SERVER_ERROR, additional_error_text=str(error), ) raise # Update the MessagingEvent for reporting if recipient_count == 0: logged_event.error(MessagingEvent.ERROR_NO_RECIPIENT) else: logged_event.completed()
def send_current_event_content_to_recipients(self): client = get_redis_client() content = self.memoized_schedule.get_current_event_content(self) if isinstance(content, (IVRSurveyContent, SMSCallbackContent)): raise TypeError( "IVR and Callback use cases are no longer supported. " "How did this schedule instance end up as active?" ) if isinstance(self, CaseScheduleInstanceMixin): content.set_context(case=self.case, schedule_instance=self) else: content.set_context(schedule_instance=self) logged_event = MessagingEvent.create_from_schedule_instance(self, content) recipient_count = 0 for recipient in self.expand_recipients(): recipient_count += 1 # The framework will retry sending a non-processed schedule instance # once every hour. # If we are processing a long list of recipients here and an error # occurs half-way through, we don't want to reprocess the entire list # of recipients again when the framework retries it an hour later. # So we use a non-blocking lock tied to the event due time and recipient # to make sure that we don't try resending the same content to the same # recipient more than once in the event of a retry. # If we succeed in sending the content, we don't release the lock so # that it won't retry later. If we fail in sending the content, we release # the lock so that it will retry later. lock = self.get_content_send_lock(client, recipient) if lock.acquire(blocking=False): try: content.send(recipient, logged_event) except: # Release the lock if an error happened so that we can try sending # to this recipient again later. lock.release() raise # Update the MessagingEvent for reporting if recipient_count == 0: logged_event.error(MessagingEvent.ERROR_NO_RECIPIENT) else: logged_event.completed()
def send_current_event_content_to_recipients(self): client = get_redis_client() content = self.memoized_schedule.get_current_event_content(self) if isinstance(self, CaseScheduleInstanceMixin): content.set_context(case=self.case, schedule_instance=self) else: content.set_context(schedule_instance=self) logged_event = MessagingEvent.create_from_schedule_instance( self, content) recipient_count = 0 for recipient in self.expand_recipients(): recipient_count += 1 # The framework will retry sending a non-processed schedule instance # once every hour. # If we are processing a long list of recipients here and an error # occurs half-way through, we don't want to reprocess the entire list # of recipients again when the framework retries it an hour later. # So we use a non-blocking lock tied to the event due time and recipient # to make sure that we don't try resending the same content to the same # recipient more than once in the event of a retry. # If we succeed in sending the content, we don't release the lock so # that it won't retry later. If we fail in sending the content, we release # the lock so that it will retry later. lock = self.get_content_send_lock(client, recipient) if lock.acquire(blocking=False): try: content.send(recipient, logged_event) except: # Release the lock if an error happened so that we can try sending # to this recipient again later. lock.release() raise # Update the MessagingEvent for reporting if recipient_count == 0: logged_event.error(MessagingEvent.ERROR_NO_RECIPIENT) else: logged_event.completed()