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
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
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
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews