<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="81598" data-post-id="81598">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="cdegroot" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/120/4644_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  cdegroot
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="11" data-topic="14192">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>VSCode with ElixirLS</p>
</blockquote>
</aside>
<p>(I use Spacemacs/Alchemist, so I guess we’re both good. But frankly, code should be obvious in <code>less</code> as well)</p>
<p>I guess I’m trying to make the point that the SRP applied to modules is a nice thing. And this time around I don’t feel like I’m trying to transplant the wrong bits of my OO knowledge into Elixir. It’s a design gut feeling that’s been well honed over the decades and languages ranging across the spectrum: the single responsibility principle is something to take seriously and the dangers of taking it far or too far are small. I know that there’s no big functional difference between having one “do-everything” module separated by comments and broken up into sections, but qualitatively, I think that the difference is huge. If only because it stresses good design much more than the community currently does around genservers. When I watched Dave’s video on his solution (is it publicly available?), something just clicked and the uneasiness I’ve always had when writing GenServers and looking at the resulting code mess broken up with <code># API functions</code> comments like I was coding large C programs again in the '80s got a name.</p>
<p>I guess it just boils down to: should we ruthlessly apply the SRP to modules? I guess the answer is, to me, yes. Even though I have enough experience in large OO systems to know where delegation hell can lead you <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81598" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-81598" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81598"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="81599" data-post-id="81599">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="cdegroot" data-post="1" data-topic="14192">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/48/4644_2.png" class="avatar"> cdegroot:</div>
<blockquote>
<p>Lifting the Single Responsibility Principle to the module level just makes for way nicer code</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="cmkarlsson" data-post="2" data-topic="14192">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cmkarlsson/48/23000_2.png" class="avatar"> cmkarlsson:</div>
<blockquote>
<p>Yes, but as with everything there is a trade-off. With large and complex applications even following the single responsibility principle will give you large modules</p>
</blockquote>
</aside>
<p>And one also needs to keep in mind that we are talking about a single GenServer - all that code can only execute in a strictly sequential manner. Once you start focusing on modules that Genserver could take on too many responsibilities and become a bottleneck in the system. And lines of code or number of modules don’t tell the full story - given a realistic load does the GenServer remain responsive?</p>
<p>As <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> outlined, there is always a range of design and implementation choices. It’s important:</p>
<ul>
<li>To know what the full range of choices are</li>
<li>To be able to justify the choice made in reference to the relevant context (at the time) rather than just sticking to some default (“that’s the way we do it around here” is rarely good judgement).</li>
<li>Be willing to change the choice if either the relevant context or the knowledge about the relevant context changes.</li>
</ul>
<p>In short, don’t make the approach your “new default” (i.e. don’t have a default. Defaults have a habit of to turning into dogma). Add it to the toolbox, sure, but only use it when the trade offs (which <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> and <a class="mention" href="/u/rvirding" rel="nofollow">@rvirding</a> get into) can be justified.</p>
<p>FYI: <a href="https://youtu.be/eldYot7uxUc" rel="noopener nofollow ugc">SOLID Elixir - Georgina McFadyen - ElixirConf EU 2018</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81599" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-81599" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81599"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="81600" data-post-id="81600">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="cdegroot" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/120/4644_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  cdegroot
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="michalmuskala" data-post="5" data-topic="14192">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/48/20288_2.png" class="avatar"> michalmuskala:</div>
<blockquote>
<p>What is the GenServer’s callback module other than the raw “business logic” module already?</p>
</blockquote>
</aside>
<p>Well, that’s the issue - it is, usually, three things:</p>
<ul>
<li>The API to the server;</li>
<li>The business logic that the server implements;</li>
<li>The “glue” logic that sits between the GenServer protocol and the business logic.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81600" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-81600" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81600"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="81603" data-post-id="81603">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="rvirding" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rvirding/120/1409_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  rvirding
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Erlang</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>But all those are tightly integrated so having a rule which splits them up feels very wrong. Yes, there are cases where it would be reasonable, but not as the general rule.</p>
<p><strong>EDIT:</strong> Just a short comment about rules in this context. I see them as the good starting point for working out a solution. So they should always work but sometimes they might not be the best solution and then it can be reasonable to think about a better solution.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81603" data-batch-url="/posts/batch_likers">
                        7
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-81603" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81603"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="81607" data-post-id="81607">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="joaquinalcerro" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/joaquinalcerro/120/13928_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  joaquinalcerro
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Can you share some code showing how do you structure GenServer modules? Thanks,</p>
<p>Best Regards</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81607" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-81607" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81607"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="81614" data-post-id="81614">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="StefanHoutzager" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  StefanHoutzager
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Posting code yourself where you have doubts about might give interesting comments. So post your code, share your doubts.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81614" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-81614" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81614"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="81624" data-post-id="81624">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="joaquinalcerro" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/joaquinalcerro/120/13928_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  joaquinalcerro
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>So I have also taken the Dave’s course and really love the separation of concerns but in some way I agree with <a class="mention" href="/u/michalmuskala" rel="nofollow">@michalmuskala</a> that to many layers might not help much.</p>
<p>My doubt is how can I structure GenServers better. I am sure we will all learn something looking at others code.</p>
<p>This is one example on how I do it:</p>
<pre><code>  defmodule FindattachV2.Inbox do
  use GenServer
  require Logger

  ###################
  # Client API
  ###################

  def start_link(user) do
    GenServer.start_link(__MODULE__, [], name: String.to_atom(user))
  end

  def full_sync(user, token) do
    inbox = FindattachV2.MailServer.find_inbox(user)
    t = Date.utc_today()
    params = [params: [{"q", "has:attachment after:#{t.year}/#{t.month - 1}/#{t.day}"}]]
    GenServer.cast(inbox, {:full_sync, user, token, params})
  end

  def all_data(inbox) do
    GenServer.call(inbox, {:get_all})
  end

  def get_state(inbox) do
    GenServer.call(inbox, {:get_state})
  end

  def get_contact_attachments(inbox, contact) do
    GenServer.call(inbox, {:get_contact_attachments, contact}) 
  end

  def get_contacts(inbox) do
    GenServer.call(inbox, {:get_contacts})
  end

  def get_contact(inbox, contact_email) do
    GenServer.call(inbox, {:get_contact, contact_email})
  end

  ###################
  # Server API
  ###################

  def init(state) do
    new_state = [:ets.new(:data, [:bag, :public, read_concurrency: true, write_concurrency: true]) | state]
    {:ok, new_state}
  end

  def handle_cast({:full_sync, user, token, params}, state = [table | _]) do
    download_all_messages(table, user, token, params)
    {:noreply, state}
  end

  def handle_call({:get_contact_attachments, contact}, _from, state = [table | _]) do
    attachments =
      :ets.lookup(table, contact)
      |&gt; Enum.map(fn({_, _, id, date, attachments}) -&gt;
           Enum.map(Kernel.elem(attachments,0), fn(x) -&gt;
             Map.put(x, :msg_id, id)
             Map.put(x, :date, date)
           end)
         end)
      |&gt; List.flatten()
    {:reply, attachments, state}
  end

  def handle_call({:get_contacts}, _from, state = [table|_]) do
    contacts =
      :ets.match(table, {:'$1',:'$2',:'_',:'_',:'_'})
      |&gt; Enum.reduce(%{}, fn([k,v], acc) -&gt; Map.put(acc, k,v) end)
    {:reply, contacts, state}
  end

  def handle_call({:get_contact, contact_email}, _from, state = [table | _]) do
    {_,contact,_,_,_} = :ets.match_object(table, {contact_email, :"_", :"_", :"_", :"_"})  |&gt; List.first()
    {:reply, contact, state}
  end

  def handle_call({:get_all}, _from, state = [table | _]) do
    data = :ets.tab2list(table)
    {:reply, data, state}
  end

  def handle_call({:get_state}, _from, state) do
    {:reply, state, state}
  end
  
  ###################
  # Private Functions
  ###################

  defp download_all_messages(table, user, token, params) do

    case FindattachV2.GmailService.list_messages(token, user, params) do
      {:ok, data} -&gt;  
        if Map.has_key?(data, "messages") do 
          spawn_link(FindattachV2.Pmap, :pmap, [table, data["messages"], &amp;FindattachV2.Message.download_messages_details/3, token, user]) 
        
          if Map.has_key?(data, "nextPageToken") do
            download_all_messages(
              table, user, token,
              [params: [{"q","has:attachment"},{"pageToken", data["nextPageToken"]}]]
            )
          else
            Logger.info("Finish importing messages IDs for user")
          end
        end

      {:error, reason} -&gt; 
        if reason == :api_timeout do
          Logger.error("Error: --- #{inspect reason} ---") 
          download_all_messages(table, user, token, params)
        end
    end
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81624" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-81624" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81624"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="81631" data-post-id="81631">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="rvirding" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rvirding/120/1409_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  rvirding
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Erlang</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ok. I found most of the servers that I could distribute are pretty small but this one covers most of the ground. It is in Erlang which I mostly use but it should illustrate what I mean. The code is the simulation master from a spaceship simulation where the ships are implemented in Lua using my Luerl package.</p>
<pre><code>-module(sim_master).

-behaviour(gen_server).

-define(SERVER, sim_master).
-define(TABLE, sim_ship_array).

%% User API.
-export([start/3,start_link/3,stop/1]).
-export([start_run/1,start_run/2,stop_run/0,stop_run/1]).
-export([get_ship/1,get_ship/2]).

%% Behaviour callbacks.
-export([init/1,terminate/2,handle_call/3,handle_cast/2,
         handle_info/2,code_change/3]).

%% Test functions.
-export([init_lua/0,load/3]).

-record(st, {xsize,ysize,n,arr,tick=infinity,st}).

%% Management API.

start(Xsize, Ysize, N) -&gt;
    gen_server:start({local,?SERVER}, ?MODULE, {Xsize,Ysize,N}, []).

start_link(Xsize, Ysize, N) -&gt;
    gen_server:start_link({local,?SERVER}, ?MODULE, {Xsize,Ysize,N}, []).

stop(Pid) -&gt;
    gen_server:call(Pid, stop).

%% User API.

start_run(Tick) -&gt;
    gen_server:call(?SERVER, {start_run,Tick}).

start_run(Sim, Tick) -&gt;
    gen_server:call(Sim, {start_run,Tick}).

stop_run() -&gt;
    gen_server:call(?SERVER, stop_run).

stop_run(Sim) -&gt;
    gen_server:call(Sim, stop_run).

get_ship(I) -&gt;
    gen_server:call(?SERVER, {get_ship,I}).

get_ship(Sim, I) -&gt;
    gen_server:call(Sim, {get_ship,I}).

%% Behaviour callbacks.

init({Xsize,Ysize,N}) -&gt;
    process_flag(trap_exit, true),
    {ok,_} = esdl_server:start_link(Xsize, Ysize),
    {ok,_} = sim_renderer:start_link(Xsize, Ysize),
    {ok,_} = sim_sound:start_link(),
    {ok,_} = universe:start_link(Xsize, Ysize), %Start the universe
    random:seed(now()),                         %Seed the RNG
    Arr = ets:new(?TABLE, [named_table,protected]),
    St = init_lua(),                            %Get the Lua state
    lists:foreach(fun (I) -&gt;
                          {ok,S} = start_ship(I, Xsize, Ysize, St),
                          ets:insert(Arr, {I,S})
                  end, lists:seq(1, N)),
    {ok,#st{xsize=Xsize,ysize=Ysize,n=N,arr=Arr,st=St}}.

terminate(_, #st{}) -&gt; ok.

handle_call({start_run,Tick}, _, #st{arr=Arr}=St) -&gt;
    %% We don't need the Acc here, but there is no foreach.
    Start = fun ({_,S}, Acc) -&gt; ship:set_tick(S, Tick), Acc end,
    ets:foldl(Start, ok, Arr),
    {reply,ok,St#st{tick=Tick}};
handle_call(stop_run, _, #st{arr=Arr}=St) -&gt;
    %% We don't need the Acc here, but there is no foreach.
    Stop = fun ({_,S}, Acc) -&gt; ship:set_tick(S, infinity), Acc end,
    ets:foldl(Stop, ok, Arr),
    {reply,ok,St#st{tick=infinity}};
handle_call({get_ship,I}, _, #st{arr=Arr}=St) -&gt;
    case ets:lookup(Arr, I) of
        [] -&gt; {reply,error,St};
        [{I,S}] -&gt; {reply,{ok,S},St}
    end;
handle_call(stop, _, St) -&gt;
    %% Do everything in terminate.
    {stop,normal,ok,St}.

handle_info({'EXIT',S,E}, #st{arr=Arr}=St) -&gt;
    io:format("~p died: ~p\n", [S,E]),
    ets:match_delete(Arr, {'_',S}),             %Remove the ship
    {noreply,St};
handle_info(_, St) -&gt; {noreply,St}.

%% Unused callbacks.
handle_cast(_, St) -&gt; {noreply,St}.

code_change(_, St, _) -&gt; {ok,St}.

%% Local functions.

%% init_lua() -&gt; LuaState.
%%  Initialise a LuaState to be used for each ship process.

init_lua() -&gt;
    L0 = luerl:init(),
    L1 = lists:foldl(fun({Name,Mod}, L) -&gt; load([Name], Mod, L) end, L0,
                     [{esdl_server,luerl_esdl_server},
                      {universe,luerl_universe},
                      {sound,luerl_sound},
                      {ship,luerl_ship}]),
    %% Set the default ship.
    {_,L2} = luerl:do("this_ship = require 'default_ship'", L1),
    L2.

load(Key, Module, St0) -&gt;
    {Lk,St1} = luerl:encode_list(Key, St0),
    {T,St2} = Module:install(St1),
    luerl:set_table1(Lk, T, St2).

start_ship(I, Xsize, Ysize, St) -&gt;
    %% Spread out the ships over the whole space.
    X = random:uniform(Xsize) - 1,
    Y = random:uniform(Ysize) - 1,
    {ok,S} = ship:start_link(X, Y, St),
    %% Random speeds from -0.25 to 0.25 sectors per tick (very fast).
    Dx = 2.5*random:uniform() - 1.25,
    Dy = 2.5*random:uniform() - 1.25,
    ship:set_speed(S, Dx, Dy),
    {ok,S}.
</code></pre>
<p>Yes, it is pretty comment-free but it is not for release yet.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81631" data-batch-url="/posts/batch_likers">
                        16
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-81631" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81631"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="81642" data-post-id="81642">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="joaquinalcerro" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/joaquinalcerro/120/13928_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  joaquinalcerro
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for sharing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="81642" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-81642" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="81642"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="82035" data-post-id="82035">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="AstonJ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/AstonJ/120/15_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  AstonJ
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This might be related…</p>
<p><a href="https://twitter.com/pragdave/status/997184002267246592?s=21" class="onebox" target="_blank" rel="noopener nofollow">https://twitter.com/pragdave/status/997184002267246592?s=21</a></p>
<p>Can’t wait for the video!!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82035" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/elixir-for-programmers-course-should-we-adopt-dave-thomas-way-of-organizing-genservers/14192/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-82035" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82035"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/14192/load_more?page=3">Load more posts (12 remaining)</a>
</div></template></turbo-stream>