Skip to content

Instantly share code, notes, and snippets.

@erikvullings
Created August 9, 2017 14:20
Show Gist options
  • Save erikvullings/96d73549075b8756b1da24cbd6925d56 to your computer and use it in GitHub Desktop.
Save erikvullings/96d73549075b8756b1da24cbd6925d56 to your computer and use it in GitHub Desktop.
Elixir scheduler example
# Example of a simple scheduler in Elixir
# Source code from the book Programming Elixir
# See: https://pragprog.com/book/elixir/programming-elixir
#
# Start iex
# $ iex
# > c("scheduler.exs")
# > Scheduler.run(12, FibSolver, :fib, [38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38])
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 } ->
IO.puts "#{number}: #{result}"
schedule_processes(processes, queue, [ { number, result } | results ])
end
end
end
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment