Vertigo

Vertigo

So I’ve been exploring Elixir/Erlang/OTP and totally love the syntaxes, concepts and theory models involving the actor model (thank you community, Carl Hewitt, Joe, Jose, et cetera). At this point I’m messing with GenServers and am seeking some guidance on a design pattern (this is pure hobby fun).

Say I have a ‘main’ GenServer which receives a call to find some word in multiple files, it distributes this silly task to a few workers (e.g. one per cpu, and they are also GenServers) that on their turn invoke a cast on a GenServer that does the actual searching.

Now imagine this crazy algorithm is in a competition with its fellow workers and as soon as one worker has found the word the other workers should stop(restart?) and start looking for the next word. How would I implement this as the mailbox of each process wont be read until the running task is finished. So the worker won’t cancel its, now, redundant search (poor worker :frowning:).

I thought of calling Process.exit on the actual worker once the parent receives a new instruction from the main GenServer, is this the way to go? Does ‘killing’ and starting a new GenServer include a lot of overhead or is this still considered ‘lightweight’ ?

Thanks for your insights!

Perhaps the snippet I describe is above considered an anti pattern and I should delve into supervisors more.. anyway this already has been an interesting learning experience :slight_smile:

Showing Posts 1 to 2

aenglisc

aenglisc

If I’m getting your idea correctly, you can start your workers via a supervisor with a one_for_all strategy and terminate as soon as the required task is finished, thus killing off the rest.

ityonemo

ityonemo

you know, I thought this would work, but it doesn’t:

test_pid = self()

children = Enum.map(1..10, &(%{
  id: "#{&1}",
  start: {Task, :start_link, [fn ->
    idx = &1

    # pick a random amount of time.
    duration = Enum.random(1000..10000) + 1000
    
    # report existence.
    IO.puts("starting #{idx} with #{duration} ms")

    # cache the pid of this task in the process mailbox of the test
    send(test_pid, {:pid_of, idx, self()})

    # sleep

    Process.sleep(duration)

    # return the result of our task.

    send(test_pid, {:finished, idx})

    IO.puts("#{idx} finished.")

    #Process.exit(self(), :kill)
  end]},
  restart: :temporary,
  #shutdown: :brutal_kill
}))

{:ok, sup} = Supervisor.start_link(children, strategy: :one_for_all)

#wait for the first to finish.
receive do {:finished, _} -> :ok end

# wait a hot moment for the task supervisor to do its thing
Process.sleep(100)

Enum.each(1..10, fn idx ->
  #check on the cached messages
  receive do {:pid_of, ^idx, pid} ->
    IO.puts("is #{idx} alive? #{Process.alive?(pid)}")
  end
end)

I tried (uncommenting the Process.kill), or (uncommenting the shutdown: :brutal_kill)
If you remove restart: :temporary it does correctly do the :one_for_all thing, so I either I’m setting something wrong in my code or there’s an undocumented interaction (or bug?) in the handling code:

seems to imply that you can do this, as it says “A temporary child process is never restarted (not even when the supervisor restart strategy is rest_for_one or one_for_all and a sibling death causes the temporary process to be terminated).” which doesn’t make sense if one_for_all interacts with temporary…

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
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
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
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
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
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
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
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 Top

GenericJam
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
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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
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
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews