<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>signal - Tag - Coding Life Share</title><link>https://blog.xwi88.com/en/tags/signal/</link><description>signal - Tag - Coding Life Share</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>278810732@qq.com (xwi88)</managingEditor><webMaster>278810732@qq.com (xwi88)</webMaster><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Wed, 16 Mar 2022 01:30:10 +0800</lastBuildDate><atom:link href="https://blog.xwi88.com/en/tags/signal/" rel="self" type="application/rss+xml"/><item><title>Common kill Signals and How to Catch Them in Go</title><link>https://blog.xwi88.com/en/go-kill-signal-catch/</link><pubDate>Wed, 16 Mar 2022 01:30:10 +0800</pubDate><author>xwi88</author><guid>https://blog.xwi88.com/en/go-kill-signal-catch/</guid><description><![CDATA[<p>Common kill signals for Go programs and how to catch them. Verified on <em>MacOS</em>, based on <code>go1.17.7</code>.</p>
<blockquote>
<p><strong>Copyright notice</strong>: This is an original article by <strong><a href="https://github.com/xwi88" target="_blank" rel="noopener noreffer ">xwi88</a></strong>, licensed under <a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener noreffer ">CC BY-NC 4.0</a>. Commercial use is prohibited; please cite the source when reposting. Follow at <a href="https://github.com/xwi88" target="_blank" rel="noopener noreffer ">https://github.com/xwi88</a></p>
</blockquote>
<h2 id="common-signals">
    <a href="#common-signals" class="header-anchor" aria-label="Link to Common signals"></a>Common signals</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-tex" data-lang="tex"><span class="line"><span class="cl">Some of the more commonly used signals:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> 1       HUP (hang up)
</span></span><span class="line"><span class="cl"> 2       INT (interrupt)
</span></span><span class="line"><span class="cl"> 3       QUIT (quit)
</span></span><span class="line"><span class="cl"> 6       ABRT (abort)
</span></span><span class="line"><span class="cl"> 9       KILL (non-catchable, non-ignorable kill)
</span></span><span class="line"><span class="cl"> 14      ALRM (alarm clock)
</span></span><span class="line"><span class="cl"> 15      TERM (software termination signal)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> 30      USR1 (user defined signal 1)
</span></span><span class="line"><span class="cl"> 31      USR2 (user defined signal 2)
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="go-code">
    <a href="#go-code" class="header-anchor" aria-label="Link to Go Code"></a>Go Code</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">done</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kd">struct</span><span class="p">{})</span>
</span></span><span class="line"><span class="cl"><span class="nx">ch</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="nx">os</span><span class="p">.</span><span class="nx">Signal</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">signal</span><span class="p">.</span><span class="nf">Notify</span><span class="p">(</span><span class="nx">ch</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGHUP</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGQUIT</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGABRT</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGKILL</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGALRM</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGUSR1</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGUSR2</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGTERM</span><span class="p">,</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">SIGINT</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">sgName</span> <span class="o">:=</span> <span class="o">&lt;-</span><span class="nx">ch</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;receive kill signal [%v], ready to exit ...&#34;</span><span class="p">,</span> <span class="nx">sgName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// resource release and other deals
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nx">done</span> <span class="o">&lt;-</span> <span class="kd">struct</span><span class="p">{}{}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">&lt;-</span><span class="nx">done</span>
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>For a more convenient wrapper, see <a href="https://github.com/love-wheel/signal" target="_blank" rel="noopener noreffer ">signal</a></p>
</blockquote>
<h2 id="kill-testing">
    <a href="#kill-testing" class="header-anchor" aria-label="Link to kill testing"></a>kill testing</h2>
<blockquote>
<p>Run <code>kill</code> on the host to stop the <code>app</code>. There are two runtime environments: <strong>host</strong> and <strong>docker</strong>.</p>
</blockquote>
<h3 id="host">
    <a href="#host" class="header-anchor" aria-label="Link to Host"></a>Host</h3>
<p><code>kill -&lt;signal_number | signal_name&gt; &lt;pid&gt;</code></p>
<div class="details admonition tip open">
        <div class="details-summary admonition-title">
            <i class="icon fas fa-lightbulb fa-fw" aria-hidden="true"></i>Tip<i class="details-icon fas fa-angle-right fa-fw" aria-hidden="true"></i>
        </div>
        <div class="details-content">
            <div class="admonition-content">linux/unix <code>kill</code> defaults to <code>signal_number=15</code> <strong>TERM</strong></div>
        </div>
    </div>
<p>Tested — <strong>signals that can be caught normally and return 0</strong>:</p>
<ul>
<li><code>1, 2, 3, 6, 14, 15</code>, <strong><code>30, 31</code></strong></li>
<li><code>HUP, INT, QUIT, ABRT, ALRM, TERM, USR1, USR2</code>
<ul>
<li><strong>case-insensitive</strong></li>
<li><strong><code>SIG</code> prefix allowed</strong>, also <strong>case-insensitive</strong></li>
</ul>
</li>
</ul>
<h3 id="docker">
    <a href="#docker" class="header-anchor" aria-label="Link to docker"></a>docker</h3>
<blockquote>
<p><code>docker kill -&lt;signal_number | signal_name&gt; &lt;container_id&gt;</code></p>
</blockquote>
<div class="details admonition tip open">
        <div class="details-summary admonition-title">
            <i class="icon fas fa-lightbulb fa-fw" aria-hidden="true"></i>Tip<i class="details-icon fas fa-angle-right fa-fw" aria-hidden="true"></i>
        </div>
        <div class="details-content">
            <div class="admonition-content"><code>docker kill</code> defaults to <code>signal_number=9</code> <strong>KILL</strong></div>
        </div>
    </div>
<p>Tested — <strong>signals that can be caught normally and return 0</strong>:</p>
<ul>
<li><code>1, 2, 3, 6, 14, 15</code>, <strong><code>10, 12</code></strong>
<ul>
<li><strong>In testing, <code>docker kill</code> only recognizes <code>10</code> and <code>12</code> as <code>USR1</code> and <code>USR2</code></strong></li>
<li>Reason unclear; <strong><code>USR1</code> / <code>USR2</code> not recommended</strong></li>
</ul>
</li>
<li><code>HUP, INT, QUIT, ABRT, ALRM, TERM, USR1, USR2</code>
<ul>
<li><strong>case-insensitive</strong></li>
<li><strong><code>SIG</code> prefix allowed</strong>, also <strong>case-insensitive</strong></li>
</ul>
</li>
</ul>
<h2 id="conclusion">
    <a href="#conclusion" class="header-anchor" aria-label="Link to Conclusion"></a>Conclusion</h2>
<blockquote>
<p>From the tests above, the <strong>commonly catchable, no-difference, return-0 signals</strong> are: <code>1, 2, 3, 6, 14, 15</code></p>
</blockquote>
<p>By signal semantics, we recommend using:</p>
<ul>
<li>2 <strong>SIGINT</strong> — trigger: <code>CTRL+C</code> or <code>kill -2</code></li>
<li>15 <strong>SIGTERM</strong></li>
</ul>
<h2 id="graceful-shutdown">
    <a href="#graceful-shutdown" class="header-anchor" aria-label="Link to Graceful shutdown"></a>Graceful shutdown</h2>
<ol>
<li>Send <code>kill</code> with <code>-15/-TERM/-SIGTERM</code></li>
<li>After the program catches the signal: <strong>remove the node from discovery</strong>, <strong>release resources</strong>, <em>stop the program</em></li>
<li>After a configured interval, check whether it stopped; if not, fall back to <code>kill -9/-KILL/-SIGKILL</code> per your policy</li>
</ol>
<h2 id="k8s-graceful-shutdown">
    <a href="#k8s-graceful-shutdown" class="header-anchor" aria-label="Link to k8s graceful shutdown"></a>k8s graceful shutdown</h2>
<ol>
<li><strong>Remove the node</strong></li>
<li><code>preStop hook</code> <em>optional delay, to drain in-flight traffic</em></li>
<li>Send <code>kill</code> with <code>-15/-TERM/-SIGTERM</code></li>
<li>The program catches the signal, <strong>releases resources</strong>, <em>stops</em></li>
<li>Force-killed on timeout via <code>kill -9/-KILL/-SIGKILL</code>
<ul>
<li>default 30s</li>
<li>pod: <code>terminationGracePeriodSeconds</code> to change it</li>
</ul>
</li>
</ol>
<h2 id="docker-compose-kill-issue">
    <a href="#docker-compose-kill-issue" class="header-anchor" aria-label="Link to Docker-compose kill issue"></a>Docker-compose kill issue</h2>
<ul>
<li>Current <code>Docker Compose version 2.2.2</code></li>
</ul>
<p><code>docker-compose</code> may fail to stop on <code>CTRL+C</code>; force quit with <code>CTRL+\</code></p>]]></description></item></channel></rss>