def _ScheduleVariableHunt(hunt_obj):
  """Schedules flows for a variable hunt."""
  if hunt_obj.client_rate != 0:
    raise VariableHuntCanNotHaveClientRateError(hunt_obj.hunt_id,
                                                hunt_obj.client_rate)

  seen_clients = set()
  for flow_group in hunt_obj.args.variable.flow_groups:
    for client_id in flow_group.client_ids:
      if client_id in seen_clients:
        raise CanStartAtMostOneFlowPerClientError(hunt_obj.hunt_id, client_id)
      seen_clients.add(client_id)

  now = rdfvalue.RDFDatetime.Now()
  for flow_group in hunt_obj.args.variable.flow_groups:
    flow_cls = registry.FlowRegistry.FlowClassByName(flow_group.flow_name)
    flow_args = flow_group.flow_args if flow_group.HasField(
        "flow_args") else None

    for client_id in flow_group.client_ids:
      flow.StartFlow(
          client_id=client_id,
          creator=hunt_obj.creator,
          cpu_limit=hunt_obj.per_client_cpu_limit,
          network_bytes_limit=hunt_obj.per_client_network_bytes_limit,
          flow_cls=flow_cls,
          flow_args=flow_args,
          # Setting start_at explicitly ensures that flow.StartFlow won't
          # process flow's Start state right away. Only the flow request
          # will be scheduled.
          start_at=now,
          parent_hunt_id=hunt_obj.hunt_id)
Schedules flows for a variable hunt.