def end_flow_activity(self, org): self._log(" > Ending flow %s for in org %s\n" % (org.cache['activity']['flow'].name, org.name)) org.cache['activity'] = None runs = FlowRun.objects.filter(org=org, is_active=True) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_EXPIRED)
def apply_manual(): from temba.flows.models import Flow, FlowRun flows = Flow.objects.filter(is_archived=True) for flow in flows: runs = FlowRun.objects.filter(is_active=True, exit_type=None, flow_id=flow.id) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_INTERRUPTED)
def end_flow_activity(self, org): self._log(" > Ending flow %s for in org %s\n" % (org.cache["activity"]["flow"].name, org.name)) org.cache["activity"] = None runs = FlowRun.objects.filter(org=org, is_active=True) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_EXPIRED)
def remove_expired_flows_from_active(apps, schema_editor): r = get_redis_connection() for key in r.keys('*:step_active_set:*'): # make sure our flow run activity is removed runs = FlowRun.objects.filter(pk__in=r.smembers(key), is_active=False, contact__is_test=False) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_EXPIRED)
def remove_never_expirations(apps, schema_editor): from temba.flows.models import Flow, FlowRun # for every flow that has an expiration set to 0 for flow in Flow.objects.filter(expires_after_minutes=0): # set the expiration to 30 days flow.expires_after_minutes = 60 * 24 * 30 flow.save(update_fields=["expires_after_minutes"]) # recalculate expiration on any active runs (possibly expiring them) for run in FlowRun.objects.filter(flow=flow, is_active=True): run.flow = flow if run.path: last_arrived_on = iso8601.parse_date(run.path[-1]["arrived_on"]) run.update_expiration(last_arrived_on) # check and expire any flows that are now expired runs = FlowRun.objects.filter(is_active=True, expires_on__lte=timezone.now()).order_by("expires_on") FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_EXPIRED)
def exit_active_flowruns(Contact, log=False): from temba.flows.models import FlowRun exit_runs = [] # find all contacts that have more than one active run active_contact_ids = Contact.objects.filter(runs__is_active=True).order_by('id')\ .annotate(run_count=Count('id')).filter(run_count__gt=1).values_list('id', flat=True) if log: print "%d contacts to evaluate runs for" % len(active_contact_ids) for idx, contact_id in enumerate(active_contact_ids): active_runs = FlowRun.objects.filter( contact_id=contact_id, is_active=True).order_by('-modified_on') # more than one? we may need to expire some if len(active_runs) > 1: last = active_runs[0] contact_exit_runs = [r.id for r in active_runs[1:]] ancestor = last.parent while ancestor: exit_runs.remove(ancestor.id) ancestor = ancestor.parent exit_runs += contact_exit_runs if (idx % 100) == 0: if log: print " - %d / %d contacts evaluated. %d runs to exit" % ( idx, len(active_contact_ids), len(exit_runs)) # ok, now exit those runs exited = 0 for batch in chunk_list(exit_runs, 1000): runs = FlowRun.objects.filter(id__in=batch) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_INTERRUPTED, timezone.now()) exited += len(batch) if log: print " * %d / %d runs exited." % (exited, len(exit_runs))
def exit_active_flowruns(Contact, log=False): from temba.flows.models import FlowRun exit_runs = [] # find all contacts that have more than one active run active_contact_ids = Contact.objects.filter(runs__is_active=True).order_by('id')\ .annotate(run_count=Count('id')).filter(run_count__gt=1).values_list('id', flat=True) if log: print "%d contacts to evaluate runs for" % len(active_contact_ids) for idx, contact_id in enumerate(active_contact_ids): active_runs = FlowRun.objects.filter(contact_id=contact_id, is_active=True).order_by('-modified_on') # more than one? we may need to expire some if len(active_runs) > 1: last = active_runs[0] contact_exit_runs = [r.id for r in active_runs[1:]] ancestor = last.parent while ancestor: exit_runs.remove(ancestor.id) ancestor = ancestor.parent exit_runs += contact_exit_runs if (idx % 100) == 0: if log: print " - %d / %d contacts evaluated. %d runs to exit" % (idx, len(active_contact_ids), len(exit_runs)) # ok, now exit those runs exited = 0 for batch in chunk_list(exit_runs, 1000): runs = FlowRun.objects.filter(id__in=batch) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_INTERRUPTED, timezone.now()) exited += len(batch) if log: print " * %d / %d runs exited." % (exited, len(exit_runs))
def enable_flow_server(org): """ Enables the flow server for an org. This switches all flows to be flow-server-enabled and switched all handling to take place through Mailroom going forward. Note that people currently in flows will be interrupted and there's no going back after doing this. """ from temba.flows.models import FlowRun # update all channels (we do this first as this may throw and we don't want to do the rest unless it succeeds) for channel in org.channels.filter(is_active=True): channel_type = channel.get_type() channel_type.enable_flow_server(channel) # interrupt all active runs FlowRun.bulk_exit(org.runs.filter(is_active=True), FlowRun.EXIT_TYPE_INTERRUPTED) # flip all flows org.flows.filter(is_active=True).update(flow_server_enabled=True) # finally flip our org org.flow_server_enabled = True org.save(update_fields=["flow_server_enabled", "modified_on"])
def remove_expired_flows_from_active(apps, schema_editor): r = get_redis_connection() for key in r.keys('*:step_active_set:*'): # make sure our flow run activity is removed runs = FlowRun.objects.filter(pk__in=r.smembers(key), is_active=False, contact__is_test=False) FlowRun.bulk_exit(runs, FlowRun.EXIT_TYPE_EXPIRED)