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

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New

Other Trending Topics Top

mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
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
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews