dra

dra

Hi everyone, I have been playing with Elixir for a bit and I was told in passing that performing heavy lifting in a Genserver’s init call is an anti-pattern. If so, what are some patterns to do it the right way ?

For example, in the code below, I attempt at sending a message to the process itself and performing the task async. However, it seems like due to some sort of race condition(?), the last line of the handle_info where the process prints out the character count never works.

I am curious about what might be happening here?

defmodule Nine.PartOne do
  use GenServer
  require Logger

  # API
  def start_link(state) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  @impl true
  def init(state) do
    Logger.info("I got started")
    file_path = Application.get_env(:adventofcode, :filepath)
    Process.send(self(), {:solve, file_path}, [])
    {:ok, state}
  end

  @impl true
  def handle_info({:solve, file_path}, _state) do
    IO.puts("I got the message") #this is printed
    res =
      File.read!(file_path)
      |> String.graphemes()
      |> Enum.reduce(
        0,
        fn _x, acc ->
          acc+1
        end
      )
    #this is never printed
    Logger.debug("The result is #{inspect(res)}")
  end
end

Showing Posts 1 to 4

peerreynders

peerreynders

Welcome to the forum!

Have a look at handle_continue/2

If you look at init/1:

Returning {:ok, state, {:continue, continue}} is similar to {:ok, state} except that immediately after entering the loop the handle_continue/2 callback will be invoked with the value continue as first argument.


handle_info/2 is supposed to return a value just like handle_cast/2.

tty

tty

The handle_info should return {:noreply, new_state}

Your init is a common traditional method for heavy inits, pre-OTP 21.0. handle_continue is the current method for doing this.

bottlenecked

bottlenecked

Like others here suggested, the actual problem is that your handle_info does not return a valid result (it returns :ok from the Logger.debug() statement instead of {:noreply, state} or some other expected tuple).

As for handling heavy processing during initialization, handle_continue is indeed the pattern to use (as others here noted too).

dra

dra OP

Thanks everyone! I was not aware of handle_continue. I will look more into it.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
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
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

JesseHerrick
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
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews