Here is a code snippet from the book Programming Elixir:
defmodule FibSolver do
def fib(scheduler) do
send scheduler, { :ready, self() }
receive do
{ :fib, n, client } ->
send client, { :answer, n, fib_calc(n), self() }
fib(scheduler)
{ :shutdown } ->
exit(:normal)
end
end
# very inefficient, deliberately
defp fib_calc(0), do: 0
defp fib_calc(1), do: 1
defp fib_calc(n), do: fib_calc(n-1) + fib_calc(n-2)
end
defmodule Scheduler do
def run(num_processes, module, func, to_calculate) do
(1..num_processes)
|> Enum.map(fn(_) -> spawn(module, func, [self()]) end)
|> schedule_processes(to_calculate, [])
end
defp schedule_processes(processes, queue, results) do
receive do
{:ready, pid} when length(queue) > 0 ->
[ next | tail ] = queue
send pid, {:fib, next, self()}
schedule_processes(processes, tail, results)
{:ready, pid} ->
send pid, {:shutdown}
if length(processes) > 1 do
schedule_processes(List.delete(processes, pid), queue, results)
else
Enum.sort(results, fn {n1,_}, {n2,_} -> n1 <= n2 end)
end
{:answer, number, result, _pid} ->
schedule_processes(processes, queue, [ {number, result} | results ])
end
end
end
I don’t understand the following lines:
- In FibSolver:
send client, { :answer, n, fib_calc(n), self() }
- In Scheduler:
send pid, {:fib, next, self()}
Why does the Scheduler includes in the message its process’ PID ? The FibSolver has it already (variable “scheduler”).
And in the FibSolver, why send the message to “client”, he can just send the message to “scheduler” as it seems to me that client and scheduler are the same PID.
Thank you for any help…