devfabiofreitas

devfabiofreitas

Task for requests HTTP

hello, i have the following problem:

I need to make http requests for a given site with thousands of pages. just stop the requests when the response returns {_page,}

I was able to make the code without using concurrency, and Tesla for requests

def fetch(page) do
   {:ok, response} = get(“/api/res”, query: [page: page])
   {page, response.body[“res”]}
end

def fetchAll(curr \\ 1 , list \\ ) do
  result = fetch(curr)
  case result do
   {_page, } →
      list
   {curr, nil} →
      fetchAll(curr,list)
   {_page, res} →
       curr = curr + 1
       fetchAll(curr,list++res)
  end
end

however I wanted to use Task to increase speed, but i don’t know how to do it.

if the number of pages was known, it would be easy to implement it using Task.async_stream

1..numberPages
|> Task.async_stream(fn page ->fetch(page) end, ordered: false,
max_concurrency: System.schedulers_online()*3)
|> Enum.reduce(, fn {:ok, {_page, res}}, j → res++ j end)

but as the number of pages depends on the return of the request, I don’t know how to do this

Most Liked

ruslandoga

ruslandoga

You can use Stream.reduce_while and halt when you receive {_page,[]}. Doesn’t seem like Stream.reduce_while exists. Maybe Task.async_stream and followed by Stream.take_while/2 would work.

You can use send requests in chunks and stop when you have {_page,[]} meaning you’d “overshoot” and make requests to the pages that don’t exist by that’s probably not a big problem.

Last Post!

lud

lud

You could try to find the last cursor first with a binary search: try page 1 then multiply the cursor by two until it returns []: 1, 2, 4, 8, 16, 34, 64, etc.. For instance you know that cursor 512 returned pages but 1024 returned []. Then you try in the middle: 768. If it returns [], the last page is between 512 and 768, if not the last page is between 768 and 1024. And you continue by trying in the new middle until you find the last cursor.

Then you can fetch all your pages from 1 to last cursor in an async stream.

Where Next?

Popular in Questions Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49134 226
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement