def attempt_forward_now(self, is_retry=False): from corehq.motech.repeaters.tasks import process_repeat_record, retry_process_repeat_record def is_ready(): return self.next_check < datetime.utcnow() def already_processed(): return self.succeeded or self.cancelled or self.next_check is None if already_processed() or not is_ready(): return # Set the next check to happen an arbitrarily long time from now. # This way if there's a delay in calling `process_repeat_record` (which # also sets or clears next_check) we won't queue this up in duplicate. # If `process_repeat_record` is totally borked, this future date is a # fallback. self.next_check = datetime.utcnow() + timedelta(hours=48) try: self.save() except ResourceConflict: # Another process beat us to the punch. This takes advantage # of Couch DB's optimistic locking, which prevents a process # with stale data from overwriting the work of another. return # separated for improved datadog reporting if is_retry: retry_process_repeat_record.delay(self) else: process_repeat_record.delay(self)
def attempt_forward_now(self): from corehq.motech.repeaters.tasks import process_repeat_record def is_ready(): return self.next_check < datetime.utcnow() def already_processed(): return self.succeeded or self.cancelled or self.next_check is None if already_processed() or not is_ready(): return # Set the next check to happen an arbitrarily long time from now so # if something goes horribly wrong with the delayed task it will not # be lost forever. A check at this time is expected to occur rarely, # if ever, because `process_repeat_record` will usually succeed or # reset the next check to sometime sooner. self.next_check = datetime.utcnow() + timedelta(hours=48) try: self.save() except ResourceConflict: # Another process beat us to the punch. This takes advantage # of Couch DB's optimistic locking, which prevents a process # with stale data from overwriting the work of another. return process_repeat_record.delay(self)