nezzart
How to properly create handle_info with a list of Task?
In handle_info function I have this:
def handle_info(:tick, items) do
items2 = do_job(items)
tick()
{:noreply, items2}
end
In “do_job” I need to a) iterate throug items, b) make an http request which can take long and c) depending on a response, update a database and finish with the current item by removing it from “items” or merely update the database:
def do_job(items) do
Enum.each(items, fn(a) -> # or Enum.map
Task.start fn ->
case external_request(a) do
{:terminate, data} ->
Repo.update(....)
remove(a) # send a message to this GenServer to remove itself
{:continue, data} ->
Repo.update(....)
end
end
end)
end
-
Even if I had Enum.map, how would I return a value fro do_job since it creates Task for each one and executes asyncronously?
-
Do I have to return it at all? I think I do because handle_info should return a tuple with a list of items in case of success
-
Should I use Task.start or maybe better Task.async and wait? If so, how exactly for my case? Yet the #2 will remain.
Most Liked
peerreynders
Also note:
Task.await/2 Compatibility with OTP behaviours
It is not recommended to
awaita long-running task inside an OTP behaviour such asGenServer. Instead, you should match on the message coming from a task inside yourGenServer.handle_info/2callback.
This - somewhat dated - article could be a starting point: The Erlangelist: Beyond Task.Async 2015-07-31
The article demonstrates the approach with a raw “master” process - so the code still needs to be “ported” for use in a GenServer.
Edit: the article uses Task.find/2 which has been deprecated in Elixir 1.3.0
[Task] Task.find/2 is deprecated in favor of explicit message matching.
OvermindDL1
- Even if I had Enum.map, how would I return a value fro do_job since it creates Task for each one and executes asyncronously?
As your do_job/1 is right now it transforms (maps) a set of items to a set of tasks. If you want values from the tasks then have the task callback either send a message or return a value and await on the tasks. ![]()
- Do I have to return it at all? I think I do because handle_info should return a tuple with a list of items in case of success
You always have a return, right now you are returning a list of tasks equal to the original items.
- Should I use Task.create or maybe better Task.async and wait? If so, how exactly for my case? Yet the #2 will remain.
All depends on what you want to return and ‘how’?
net
Using Task.start will still perform the task asynchronously, you just won’t be given a reference to retrieve the return value of the task at a later point.
Task — Elixir v1.20.2
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









