# Programming Elixir - A Fibonacci Server

**URL:** <https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651>\
**Category:** Questions\
**Tags:** book-programming-elixir\
**Created:** [May 19, 2016, 10:05pm UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651 "2016-05-19T22:05:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sztosz](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sztosz/32/1251_2.png) [@sztosz](https://forum.elixirforum.com/u/sztosz)\
**Post date:** [May 19, 2016, 10:05pm UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651/1 "2016-05-19T22:05:29Z")

</div>

Hi, somehow, after typing code from book i managed only to make my code stuck at infinite loop. I did comparision side by side of my code to that i get from zipped examples i got with book (code from zip works ok). I can’t find where did i do mistake. Can anyone spot what did do wrong? I know i can move on, i understand what is going on, but it’s driving me nuts, beside, there is a big chance i won’t repeat that mistake if only i would know where it is ☹

Anyway, here’s the code:

```elixir
defmodule FibSolver do

  def fib(scheduler) do
    send(scheduler, { :read, self })
    receive do
      { :fib, n, client } ->
        send(client, { :answer, n, fib_calc(n), self })
        fib(scheduler)
      { :shutdown } ->
        exit(:normal)
    end
  end

  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

to_process = [37, 37, 37, 37, 37, 37]

Enum.each(1..10, fn num_processes ->
  { time, result } = :timer.tc(Scheduler, :run, [num_processes, FibSolver, :fib, to_process])
  if num_processes == 1 do
    IO.puts(inspect(result))
    IO.puts("\n # time(s)")
  end
  :io.format("~2B ~.2f~n", [num_processes, time/1000000.0])
  end)

```

---

<div class="post-metadata">

**Author:** ![lionize](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lionize/32/1340_2.png) [@lionize](https://forum.elixirforum.com/u/lionize)\
**Post date:** [May 19, 2016, 11:16pm UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651/2 "2016-05-19T23:16:22Z")

</div>

> [@sztosz](#):
>
> ```
> def fib(scheduler) do
> send(scheduler, { :read, self })
> 
> ```

Looks like that should be `{:ready, self}`. Can’t start the circus if it’s never telling the Scheduler it’s ready. 🙂

---

<div class="post-metadata">

**Author:** ![sztosz](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sztosz/32/1251_2.png) [@sztosz](https://forum.elixirforum.com/u/sztosz)\
**Post date:** [May 20, 2016, 6:17am UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651/3 "2016-05-20T06:17:55Z")

</div>

Thank you very much. Such typos are hard to spot, i normally rely on IDE to help me with them, but i have none for elixir 🙂

I think the lesson for me is to also pattern match “anything” at end of receive and exit program printing the oddity I just catch, at least when I’m learning 😉

PS. Func fact: Single core performance of my 1.6 Ghz i5 in mac book air (OSX) is better than single core performance of 3.7 Ghz AMD (Win10)

---

<div class="post-metadata">

**Author:** ![rvirding](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rvirding/32/1409_2.png) [@rvirding](https://forum.elixirforum.com/u/rvirding)\
**Post date:** [May 20, 2016, 8:57am UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651/4 "2016-05-20T08:57:03Z")

</div>

Deciding what to do when you get a message in which you are not interested is a general problem. Should I crash, or should I ignore it, or what? Unfortunately there is no general solution which is good for everyone everywhere.

Just some philosophy.

Robert

---

<div class="post-metadata">

**Author:** ![Qqwy](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/32/1349_2.png) [@Qqwy](https://forum.elixirforum.com/u/Qqwy)\
**Post date:** [May 20, 2016, 10:20am UTC](https://forum.elixirforum.com/t/programming-elixir-a-fibonacci-server/651/5 "2016-05-20T10:20:03Z")

</div>

> [@rvirding](#):
>
> Deciding what to do when you get a message in which you are not interested is a general problem. Should I crash, or should I ignore it, or what? Unfortunately there is no general solution which is good for everyone everywhere.
> 
> Just some philosophy.
> 
> Robert

This is very true.

For completeness: When you use an OTP GenServer, it picks the ‘let it crash’ approach for you, as it will simply attempt to call a variant of `handle_call`, `handle_cast` or `handle_info` that does not exist. (Of course, when you don’t have, for instance, any overridden variants of `handle_info`, it will default to doing nothing with any info-messages it receives).

You can of course change it to the second variant by creating a fallback function variant that accepts any other message.
