<p>In a lot of instances, you need to have the ability to wait for a MySQL database to startup (e.g. when using in a Docker container). This is something which can easily be done with a simple Go program:</p> <div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nx">main</span> <span class="kn">import</span> <span class="p">(</span> <span class="s">&quot;database/sql&quot;</span> <span class="s">&quot;fmt&quot;</span> <span class="s">&quot;os&quot;</span> <span class="s">&quot;time&quot;</span> <span class="s">&quot;github.com/go-sql-driver/mysql&quot;</span> <span class="p">)</span> <span class="kd">type</span> <span class="nx">discardLogger</span> <span class="kd">struct</span> <span class="p">{</span> <span class="p">}</span> <span class="kd">func</span> <span class="p">(</span><span class="nx">d</span> <span class="nx">discardLogger</span><span class="p">)</span> <span class="nx">Print</span><span class="p">(</span><span class="nx">args</span> <span class="o">...</span><span class="kd">interface</span><span class="p">{})</span> <span class="p">{</span> <span class="p">}</span> <span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span> <span class="nx">mysql</span><span class="p">.</span><span class="nx">SetLogger</span><span class="p">(</span><span class="nx">discardLogger</span><span class="p">{})</span> <span class="nx">host</span> <span class="o">:=</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="s">&quot;HOST&quot;</span><span class="p">,</span> <span class="s">&quot;127.0.0.1&quot;</span><span class="p">)</span> <span class="nx">port</span> <span class="o">:=</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="s">&quot;PORT&quot;</span><span class="p">,</span> <span class="s">&quot;3306&quot;</span><span class="p">)</span> <span class="nx">user</span> <span class="o">:=</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="s">&quot;USER&quot;</span><span class="p">,</span> <span class="s">&quot;root&quot;</span><span class="p">)</span> <span class="nx">passwd</span> <span class="o">:=</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="s">&quot;PASSWD&quot;</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">)</span> <span class="nx">dbName</span> <span class="o">:=</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="s">&quot;DB_NAME&quot;</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">)</span> <span class="nx">connectionString</span> <span class="o">:=</span> <span class="nx">user</span> <span class="o">+</span> <span class="s">&quot;:&quot;</span> <span class="o">+</span> <span class="nx">passwd</span> <span class="o">+</span> <span class="s">&quot;@tcp(&quot;</span> <span class="o">+</span> <span class="nx">host</span> <span class="o">+</span> <span class="s">&quot;:&quot;</span> <span class="o">+</span> <span class="nx">port</span> <span class="o">+</span> <span class="s">&quot;)/&quot;</span> <span class="o">+</span> <span class="nx">dbName</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;Waiting for:&quot;</span><span class="p">,</span> <span class="nx">user</span><span class="o">+</span><span class="s">&quot;@tcp(&quot;</span><span class="o">+</span><span class="nx">host</span><span class="o">+</span><span class="s">&quot;:&quot;</span><span class="o">+</span><span class="nx">port</span><span class="o">+</span><span class="s">&quot;)/&quot;</span><span class="o">+</span><span class="nx">dbName</span><span class="p">)</span> <span class="k">for</span> <span class="p">{</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">)</span> <span class="nx">db</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">sql</span><span class="p">.</span><span class="nx">Open</span><span class="p">(</span><span class="s">&quot;mysql&quot;</span><span class="p">,</span> <span class="nx">connectionString</span><span class="p">)</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">Error</span><span class="p">())</span> <span class="k">return</span> <span class="p">}</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">db</span><span class="p">.</span><span class="nx">Ping</span><span class="p">()</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">()</span> <span class="k">break</span> <span class="p">}</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="mi">1</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span> <span class="k">continue</span> <span class="p">}</span> <span class="p">}</span> <span class="kd">func</span> <span class="nx">getenvWithDefault</span><span class="p">(</span><span class="nx">name</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">defaultVal</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span> <span class="k">if</span> <span class="nx">val</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nx">Getenv</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span> <span class="nx">val</span> <span class="o">!=</span> <span class="s">&quot;&quot;</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">val</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">defaultVal</span> <span class="p">}</span> </pre></div> <p>What we first do is to register a custom logger for the <code>mysql</code> package so that it doesn't output anything. Then we read the environment variables which contain the connection details. Then, we just ping the database every second until it succeeds. If it does, the program exits.</p> <p>You can run it like this:</p> <div class="highlight"><pre><span></span>$ HOST=127.0.0.1 DB_NAME=my_database USER=root go run wait_for_db.go Waiting for: root@tcp(127.0.0.1:3308)/my_database ... </pre></div> <p>It can be easily modified to do the same for any other supported database engine.</p>

Related Posts

  • Assert vs require in testify
  • Handling Unix timestamps in JSON
  • Parsing a key pair from a PEM file in Go
  • Pointer vs value receivers
  • The beauty of io.Reader in Go