sezaru
Hello,
I have some GenServers that will do some loading during init function using Task.async (so they will not block init and then get the result via handle_info function).
Recently I noticed that for the period that this task is running, the :observer Applications tab, with the app tab in which the caller server is supervised, will freeze and not respond until the task finishes its job. I have other GenServers that start Tasks for other stuff and they don’t show the same behavior.
I also get some errors from appmon during that period:
12:48:14.862 [error] #PID<0.741.0> :gen_server "error_info/7" "gen_server.erl" 889
GenServer :appmon_info terminating
** (MatchError) no match of right hand side value: {:error, {:EXIT, {:badarg, [{:erlang, :element, [2, :undefined], []}, {:appmon_info, :check_sasl_ancestor, 2, [file: 'appmon_info.erl', line: 618]}, {:appmon_info, :maybe_add_child_sasl, 4, [file: 'appmon_info.erl', line: 590]}, {:lists, :foldr, 3, [file: 'lists.erl', line: 1276]}, {:appmon_info, :do_find_proc2, 5, [file: 'appmon_info.erl', line: 497]}, {:appmon_info, :calc_app_tree, 2, [file: 'appmon_info.erl', line: 450]}, {:appmon_info, :do_work, 2, [file: 'appmon_info.erl', line: 308]}, {:appmon_info, :handle_info, 2, [file: 'appmon_info.erl', line: 276]}]}}}
appmon_info.erl:308: :appmon_info.do_work/2
appmon_info.erl:276: :appmon_info.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:do_it, {:app, :pipeline, #PID<0.729.0>}}
State: {:state, #PID<0.729.0>, [], #Reference<0.3006373769.2547122179.177556>, [#PID<0.729.0>]}
12:48:14.863 [error] #PID<0.741.0> :proc_lib "crash_report/4" "proc_lib.erl" 508
Process :appmon_info (#PID<0.741.0>) terminating
** (MatchError) no match of right hand side value: {:error, {:EXIT, {:badarg, [{:erlang, :element, [2, :undefined], []}, {:appmon_info, :check_sasl_ancestor, 2, [file: 'appmon_info.erl', line: 618]}, {:appmon_info, :maybe_add_child_sasl, 4, [file: 'appmon_info.erl', line: 590]}, {:lists, :foldr, 3, [file: 'lists.erl', line: 1276]}, {:appmon_info, :do_find_proc2, 5, [file: 'appmon_info.erl', line: 497]}, {:appmon_info, :calc_app_tree, 2, [file: 'appmon_info.erl', line: 450]}, {:appmon_info, :do_work, 2, [file: 'appmon_info.erl', line: 308]}, {:appmon_info, :handle_info, 2, [file: 'appmon_info.erl', line: 276]}]}}}
appmon_info.erl:308: :appmon_info.do_work/2
appmon_info.erl:276: :appmon_info.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Initial Call: :appmon_info.init/1
Ancestors: [#PID<0.729.0>, :observer, #PID<0.711.0>, #PID<0.82.0>]
Message Queue Length: 0
Messages: []
Links: [#PID<0.729.0>]
Dictionary: []
Trapping Exits: true
Status: :running
Heap Size: 10958
Stack Size: 27
Reductions: 115365
For completeness, this is more or less what I have:
defmodule Server do
...
@impl GenServer
def init(args),
do: {:ok, State.new(args), {:continue, :load_pipeline}}
@impl GenServer
def handle_continue(:load_pipeline, state) do
Task.async(fn ->
repo = Application.get_env(:database, :bla) |> Keyword.fetch!(:repo)
repo.transaction(
fn repo ->
# Do some work with streams that can take some time
end,
timeout: :infinity
)
end)
{:noreply, state}
end
...
end
Can I do something to help fix this issue?
Thanks.
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
ityonemo
Why not remove the Task.async? Since it’s in a handle_continue, it won’t block the init.
sezaru
Because I need to be able to handle external calls during the work I’m doing inside the Task.
I do other work inside the
handle_continuethat I didn’t show in the code above because it would not be related to the issue. I did try moving the Task to theinitcall and it still shows the same issue.I never had it before, so I’m not sure if I’m doing something wrong or this is a bug with
:observer.ityonemo
I don’t know enough about the observer internals to know for sure, but:
instead of Task.async use Task.start or Task.start_link, async returns a future which it seems like you don’t need (there’s no corresponding Task.await).
instead of Task, i would spawn inside an otp supervisor tree, so Task.Supervised.start or Task.Supervised.start_link
Doing these two things will make your architecture more otp-compliant and possibly help observer out? But again, I am not an expert on observer, so maybe someone else more experienced can comment.
dimitarvp
As @ityonemo said, you are not doing
Task.awaitto correspond with your earlierTask.async. You’re better off just doing one action then send yourself (i.e. the current process) a message that does the next, etc. until your initialisation is completed.sezaru
Thanks for the replies @ityonemo and @dimitarvp.
I’m not doing a
Task.awaitbecause this is running inside a GenServer, and as the documentation says in Task — Elixir v1.20.2 I don’t need aTask.await(the documentation goes as far as saying it is not recommended), it will trigger my matchinghandle_infocall.dimitarvp
I think you are doing it wrong. Let OTP handle itself.
Just don’t use
Task.asyncinsidehandle_continueat all. It will simplify your code and the app should behave properly. However, I have no background in your challenges – or how many other initialisation activities you need.sezaru
Basically I need to load somethings for that process in parallel to receiving call messages, I cannot block the server and wait it to load because of some constrains of my project.
I created a small project just to test this issue in isolation, and I cannot reproduce the issue, basically I just created an empty project (with --sup option), added the bellow GenServer and added it to the application supervisor.
This didn’t freeze my
:observer.I think that actually the issue is not the
Task.async, but maybe the repo.transaction I’m doing inside of it. I will try simulate something similar in my test project and see if I can reproduce the issue.sezaru
So, turns out that the issue was processing the data I’m loading, I do some computations inside an Enum.reduce and this can take some time (it takes ± 5 minutes to process 2kk rows of data). When the process is doing that the observer will freeze.
dimitarvp
You can likely chunk and multiplex the work on all CPU cores.