def check_flow_timeouts_task():
    """
    See if any flow runs have timed out
    """
    # find any runs that should have timed out
    runs = FlowRun.objects.filter(is_active=True,
                                  timeout_on__lte=timezone.now())
    runs = runs.only('id', 'org', 'timeout_on')

    queued_timeouts = QueueRecord(
        'flow_timeouts', lambda r: '%d:%d' %
        (r.id, datetime_to_epoch(r.timeout_on)))

    for run in runs:
        # ignore any run which was locked by previous calls to this task
        if not queued_timeouts.is_queued(run):
            try:
                task_payload = dict(type=TIMEOUT_EVENT,
                                    run=run.id,
                                    timeout_on=run.timeout_on)
                push_task(run.org_id, HANDLER_QUEUE, HANDLE_EVENT_TASK,
                          task_payload)

                queued_timeouts.set_queued([run])
            except Exception:  # pragma: no cover
                logger.error("Error queuing timeout task for run #%d" % run.id,
                             exc_info=True)
Beispiel #2
0
def check_campaigns_task():
    """
    See if any event fires need to be triggered
    """
    from temba.flows.models import Flow

    unfired = EventFire.objects.filter(fired=None,
                                       scheduled__lte=timezone.now())
    unfired = unfired.values('id', 'event__flow_id')

    # group fire events by flow so they can be batched
    fire_ids_by_flow_id = defaultdict(list)
    for fire in unfired:
        fire_ids_by_flow_id[fire['event__flow_id']].append(fire['id'])

    # fetch the flows used by all these event fires
    flows_by_id = {
        flow.id: flow
        for flow in Flow.objects.filter(id__in=fire_ids_by_flow_id.keys())
    }

    queued_fires = QueueRecord('queued_event_fires')

    # create queued tasks
    for flow_id, fire_ids in six.iteritems(fire_ids_by_flow_id):
        flow = flows_by_id[flow_id]

        # create sub-batches no no single task is too big
        for fire_id_batch in chunk_list(fire_ids, 500):

            # ignore any fires which were queued by previous calls to this task but haven't yet been marked as fired
            queued_fire_ids = queued_fires.filter_unqueued(fire_id_batch)

            if queued_fire_ids:
                try:
                    push_task(flow.org_id, HANDLER_QUEUE, HANDLE_EVENT_TASK,
                              dict(type=FIRE_EVENT, fires=queued_fire_ids))

                    queued_fires.set_queued(queued_fire_ids)
                except Exception:  # pragma: no cover
                    fire_ids_str = ','.join(
                        six.text_type(f) for f in queued_fire_ids)
                    logger.error("Error queuing campaign event fires: %s" %
                                 fire_ids_str,
                                 exc_info=True)
Beispiel #3
0
def check_campaigns_task():
    """
    See if any event fires need to be triggered
    """
    from temba.flows.models import Flow

    unfired = EventFire.objects.filter(
        fired=None, scheduled__lte=timezone.now(), event__flow__flow_server_enabled=False
    ).select_related("event")
    unfired = unfired.values("id", "event_id", "event__flow_id")

    # group fire events by event so they can be batched
    fire_ids_by_event_id = defaultdict(list)
    event_flow_map = dict()
    for fire in unfired:
        event_flow_map[fire["event_id"]] = fire["event__flow_id"]
        fire_ids_by_event_id[fire["event_id"]].append(fire["id"])

    # fetch the flows used by all these event fires
    flows_by_id = {flow.id: flow for flow in Flow.objects.filter(id__in=event_flow_map.values())}

    queued_fires = QueueRecord("queued_event_fires")

    # create queued tasks
    for ev_id, fire_ids in fire_ids_by_event_id.items():
        flow_id = event_flow_map[ev_id]
        flow = flows_by_id[flow_id]

        # create sub-batches no no single task is too big
        for fire_id_batch in chunk_list(fire_ids, 500):

            # ignore any fires which were queued by previous calls to this task but haven't yet been marked as fired
            queued_fire_ids = queued_fires.filter_unqueued(fire_id_batch)

            if queued_fire_ids:
                try:
                    push_task(
                        flow.org_id, Queue.HANDLER, HANDLE_EVENT_TASK, dict(type=FIRE_EVENT, fires=queued_fire_ids)
                    )

                    queued_fires.set_queued(queued_fire_ids)
                except Exception:  # pragma: no cover
                    fire_ids_str = ",".join(str(f) for f in queued_fire_ids)
                    logger.error("Error queuing campaign event fires: %s" % fire_ids_str, exc_info=True)
Beispiel #4
0
def check_flow_timeouts_task():
    """
    See if any flow runs have timed out
    """
    # find any runs that should have timed out
    runs = FlowRun.objects.filter(is_active=True, timeout_on__lte=timezone.now())
    runs = runs.only("id", "org", "timeout_on")

    queued_timeouts = QueueRecord("flow_timeouts", lambda r: "%d:%d" % (r.id, datetime_to_epoch(r.timeout_on)))

    for run in runs:
        # ignore any run which was locked by previous calls to this task
        if not queued_timeouts.is_queued(run):
            try:
                task_payload = dict(type=TIMEOUT_EVENT, run=run.id, timeout_on=run.timeout_on)
                push_task(run.org_id, HANDLER_QUEUE, HANDLE_EVENT_TASK, task_payload)

                queued_timeouts.set_queued([run])
            except Exception:  # pragma: no cover
                logger.error("Error queuing timeout task for run #%d" % run.id, exc_info=True)