   """
   def scrape_from_bigquery() do
     Logger.info "Getting repositories from BigQuery to scrape"
-    Krihelinator.Periodic.BigQuery.query()
-    |> async_scrape()
-    |> handle_scraped_data()
+    names = Krihelinator.Periodic.BigQuery.query()
+    async_handle(names)
   end
 
   @doc """

    query = from(r in GH.Repo, where: r.dirty, select: r.name)
    names = Repo.all(query)
    Logger.info "Rescraping #{length(names)} still dirty repositories"
    names
    |> async_scrape
    |> handle_scraped_data()
  end

  @async_params [max_concurrency: 20, timeout: :infinity]

  @doc """
  Scrape repositories concurrently with `Task.async_stream`.
  """
  def async_scrape(names) do
    names
    |> Task.async_stream(&scrape_with_retries/1, @async_params)
    |> Stream.map(fn {:ok, cs} -> cs end)
  end

  @to_retry ~w(github_server_error timeout)a

    end
  end

  def put_extra_params({:error, error}, _extra_params) do
    {:error, error}
  end
  def put_extra_params({:ok, data}, extra_params) do
    {:ok, Map.merge(data, Map.new(extra_params))}
  end

  def persist({:error, error}) do
    {:error, error}
  end
  def persist({:ok, data}) do
    Repo.update_or_create_from_data(GH.Repo, data, by: :name)
  end

  def simplify_result({:error, %Ecto.Changeset{}}), do: :validation_error
