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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<h3><a name="p-179594-temporary-hack-1" class="anchor" href="#p-179594-temporary-hack-1" aria-label="Heading link" rel="nofollow"></a>Temporary hack</h3>
<p>Thanks <a class="mention" href="/u/rvirding" rel="nofollow">@rvirding</a>! That makes sense. Since Ctrl-G does not trigger a signal, I guess someone needs to be monitoring standard input to do something about it.</p>
<p>By now, I am moving on with a dirty solution, which is to monitor a file:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Halter do
  @halter "halt"

  def run(on_halt) do
    if File.exists?(@halter) do
      File.rm(@halter)
      on_halt.()
      System.stop()
    else
      Process.sleep(1000)
      run(on_halt)
    end
  end
end

Halter.run(fn -&gt; IO.puts("done") end)
</code></pre>
<p>You leave the script running, and <code>touch halt</code> whenever you want it to stop. Enough for my purposes right now.</p>
<p>That solution prints these noisy traces, so it is definitely not clean:</p>
<pre><code class="lang-plaintext">** (exit) exited in: GenServer.call(Mix.ProjectStack, {:get_stack, #Function&lt;10.12591541/1 in Mix.ProjectStack.peek/0&gt;}, :infinity)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.10.3) lib/gen_server.ex:1013: GenServer.call/3
</code></pre>
<p><code>System.at_exit/1</code> is not invoked (that is why <code>run/1</code> above receives a callback), I do not know why.</p>
<h3><a name="p-179594-is-this-a-missing-feature-2" class="anchor" href="#p-179594-is-this-a-missing-feature-2" aria-label="Heading link" rel="nofollow"></a>Is this a missing feature?</h3>
<p>Not being able to do this easily surprises to me. It is a fundamental aspect of Erlang/OTP that you start applications and, symmetrically, shut them down orderly.</p>
<p>So, given that <code>mix run</code> starts the application by default, you’d expect that there would be interface to shut it down too, no? <a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a> is there a technical reason this is not in place? Or is it something that could be contributed?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179594" 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/running-code-when-a-script-exits/32340/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-179594" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179594"
                     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="179596" data-post-id="179596">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<p>BTW, if you do not call <code>System.stop/1</code> and let <code>run/1</code> and the script finish by itself, then <code>System.at_exit/1</code> gets invoked, but the application is apparently not stopped. At least, I do not see <code>terminate/2</code> callbacks being invoked.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179596" 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/running-code-when-a-script-exits/32340/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-179596" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179596"
                     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="179711" data-post-id="179711">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There are two questions here:</p>
<ol>
<li>
<p>How to shut the system down cleanly</p>
</li>
<li>
<p>How to handle certain signals (interrupt)</p>
</li>
</ol>
<p>To answer 1, <code>System.stop/1</code> is the answer. If <code>terminate/2</code> callbacks are not invoked, make sure those processes are trapping exits.</p>
<p>To answer 2, since Erlang/OTP 20, there is OS signal handling: <a href="http://erlang.org/doc/man/kernel_app.html#os-signal-event-handler" rel="nofollow">http://erlang.org/doc/man/kernel_app.html#os-signal-event-handler</a></p>
<p>It is a bit of a long answer. In a nutshell, you need to implement a gen_event handler and react to the callbacks you are interested. There is a more detailed guide here: <a href="https://medium.com/@ellispritchard/graceful-shutdown-on-kubernetes-with-signals-erlang-otp-20-a22325e8ae98" rel="nofollow">https://medium.com/@ellispritchard/graceful-shutdown-on-kubernetes-with-signals-erlang-otp-20-a22325e8ae98</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="179711" 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/running-code-when-a-script-exits/32340/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-179711" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179711"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="179723" data-post-id="179723">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<p>Thanks <a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a>!</p>
<p>However, <code>System.stop/1</code> has three problems:</p>
<ol>
<li>It does not invoke <code>System.at_exit/1</code>, that is why my “halter” solution above needs to get passed a function.</li>
<li>The script ends printing the noisy “exit” traces I quoted above. Maybe that is cosmetic, but a user does not know if “no process: the process is not alive or…” is a normal message or something to worry about, and in any case the output is not clean as you’d expect from running a program that finishes normally.</li>
<li>The programmer needs to do this by hand. I am touching a file to finish the script! Alternatively, I could write a signal handler, but all this seems boilerplate for something <code>mix run</code> should have builtin in my view.</li>
</ol>
<p>The question is: <code>mix run</code> starts the application by default, why does not provide a builtin way to cleanly stop the application too?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179723" 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/running-code-when-a-script-exits/32340/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-179723" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179723"
                     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="179724" data-post-id="179724">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<p><a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a> ah, re <code>terminate/2</code>, what I said was that if you remove <code>System.stop/1</code> and let the script finish by itself, then <code>System.at_exit/1</code> is called, but <code>terminate/2</code> callbacks are not invoked (meaning that is an observable property that suggests to me the application is not being shutdown, there’s just the VM halting.)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179724" 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/running-code-when-a-script-exits/32340/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-179724" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179724"
                     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="179780" data-post-id="179780">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Could put the logic you want to execute on exit in a terminate/2 callback of a process in your app’s  sup tree?</p>
<p>We could execute at_exit for System.stop as well… but we do have an issue in that they would be executed way too late in the termination process, when almost everything would be shut down, so it is likely not useful. That’s why System.at_exit is about the script exiting normally.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179780" 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/running-code-when-a-script-exits/32340/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-179780" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179780"
                     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="179781" data-post-id="179781">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Another trick you could do is <code>System.at_exit(fn int -&gt; your_code(); System.stop(int) end)</code>. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" 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="179781" 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/running-code-when-a-script-exits/32340/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-179781" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179781"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="180178" data-post-id="180178">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<p>I have investigated a bit the solution with the signal handler.</p>
<p>Erlang executes <code>:init.stop()</code> on <code>SIGTERM</code> <a href="https://github.com/erlang/otp/blob/76bacff3e0f0d4ef1631323db28fb35c0b84f534/lib/kernel/src/erl_signal_handler.erl#L48" rel="noopener nofollow ugc">by default</a>. That means that a simple <code>kill PID</code> shuts the thing down orderly.</p>
<p>However, you need to figure out the PID of the process, and open a different terminal to execute the command. Besides, custom code passed to <code>System.at_exit/1</code> is not invoked by the event handler.</p>
<p><code>Ctrl-C</code> sends <code>SIGINT</code>. The only shortcut that I’ve seen sends a different signal is <code>Ctrl-\</code>, which sends <code>SIGQUIT</code>. So, I am using this event handler:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule QuitScript do
  @behaviour :gen_event

  def init(_), do: {:ok, nil}
  def handle_event(:sigquit, _state), do: :remove_handler
  def handle_event(signal, state), do: :erl_signal_handler.handle_event(signal, state)
  def handle_call(_, state), do: {:ok, :ok, state}

  def terminate(_reason, _state) do
    IO.puts("My exit code")
    System.stop()
  end
end

:gen_event.swap_handler(:erl_signal_server, {:erl_signal_handler, []}, {QuitScript, []})
</code></pre>
<p>Notice that the <code>terminate/2</code> callback allows you to run custom code on exit.</p>
<p>If you throw that to a script and execute it for example like this</p>
<pre><code class="lang-plaintext">mix run --no-halt foo.exs
</code></pre>
<p><code>Ctrl-C</code> still behaves as always, and additionally <code>Ctrl-\</code> shuts the thing down orderly (you only see <code>^\</code> echoed in the terminal, not too bad).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180178" 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/running-code-when-a-script-exits/32340/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-180178" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180178"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="180196" data-post-id="180196">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="fxn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fxn/120/20274_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  fxn
                    <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">
								<p>Alternatively, we could move <code>System.stop()</code> to the callback:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule QuitScript do
  @behaviour :gen_event

  def init(_), do: {:ok, nil}
  def handle_event(:sigquit, _state), do: System.stop()
  def handle_event(signal, state), do: :erl_signal_handler.handle_event(signal, state)
  def handle_call(_, state), do: {:ok, :ok, state}

  def terminate(_reason, _state) do
    IO.puts("My exit code")
  end
end

:gen_event.swap_handler(:erl_signal_server, {:erl_signal_handler, []}, {QuitScript, []})
</code></pre>
<p>Looks more natural to me this way, though in the previous example the order in which the custom code runs is more obvious.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180196" 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/running-code-when-a-script-exits/32340/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-180196" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180196"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>