<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://younghyun-ahn.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://younghyun-ahn.github.io/" rel="alternate" type="text/html" /><updated>2021-05-09T07:09:16+00:00</updated><id>https://younghyun-ahn.github.io/feed.xml</id><title type="html">lake log</title><subtitle></subtitle><author><name>younghyun-ahn</name></author><entry><title type="html">Go Currency Patterns - Pooling</title><link href="https://younghyun-ahn.github.io/2021/05/09/currency-patterns-pooling.html" rel="alternate" type="text/html" title="Go Currency Patterns - Pooling" /><published>2021-05-09T00:00:00+00:00</published><updated>2021-05-09T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/09/currency-patterns-pooling</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/09/currency-patterns-pooling.html">&lt;p&gt;버퍼가 있는 채널을 이용하여 공유가 가능한 리소스의 풀을 생성하고, 이 리소스들을 원하는 개수만큼의 고루틴에서 개별적으로 활용할 수 있는 기능을 작성한 코드가 모여있다. 이 패턴은 데이터베이스 연결이나 메모리 버퍼 등 공유되는 리소스의 정적인 집합을 관리할 때 특히 유용하다. 고루틴이 이런 리소스 중 하나를 사용해야 할 경우에는 리소스를 할당받고 사용한 후 다시 풀에 반환하는 구조로 동작한다.(풀 사이즈 초과시 생성&amp;amp;사용후 폐기)&lt;/p&gt;

&lt;p&gt;일종의 컨텍스와 같은 성격의 공유 풀을 생성하고 풀내 팩토리 메서드를 두어 공유 객체를 생성/재사용 한다. 불필요한 전역객체(컨텍스트) 생성을 하지 않고 공유객체를 보다 우아하게 전달하고 관리 할 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;poolgo&quot;&gt;pool.go&lt;/h2&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// 사용자가 정의한 리소스의 집합을 관리하는 패키지&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;errors&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;io&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;log&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;sync&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// Pool 구조체는 여러 개의 고루틴에서 안전하게 공유학 위한 리소스의 집합을 관리한다.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// 이 풀에서 관리하가 위한 리소스는 io.Closer 인터페이스를 반드시 구현해야 한다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mutex&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;closed&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// ErrorPoolClosed 에러는 리소스를 획득하려 할 때 풀이 닫혀있는 경우에 발생한다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrPoolClosed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;풀이 닫혔습니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// New 함수는 리소스 관리 풀을 생성한다.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// 풀은 새로운 리소스를 할당하기 위한 함수와 풀의 크기를 매개변수로 정의한다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;풀의 크기가 너무 작습니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 풀에서 리소스를 획득하는 메서드&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Acquire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 사용 가능한 리소스가 있는지 검사한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;리소스 획득:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;공유된 리소스&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrPoolClosed&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 사용 가능한 리소스가 없는 경우 새로운 리소스를 생성한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;리소스 획득:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;새로운 리소스&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 풀에 리소스를 반환하는 메서드&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 안전한 작업을 위해 잠금을 설정한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 풀이 닫혔으면 리소스를 해제한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;closed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 새로운 리소스를 큐에 추가한다&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;리소스 반환:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;리소스 큐에 반환&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 리소스 큐가 가득 찬 경우 리소스를 해제한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;리소스 반환:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;리소스 해제&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 풀을 종료하고 생성된 모든 리소스를 해제하는 메서드&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 안전한 작업을 위해 잠금을 설정한다&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 풀이 이미 닫혔으면 아무런 작업도 수행하지 않는다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;closed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 풀을 닫힌 상태로 전환한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;closed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 리소스를 해제하기에 앞서 채널을 먼저 닫는다.&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 그렇지 않으면 데드락에 걸릴 수 있다.&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 리소스를 해제한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;range&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;maingo&quot;&gt;main.go&lt;/h2&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// pool 패키지를 이용하여 데이터베이스 연결 풀을 생성하고 활용하는 예제&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;github.com/younghyun-ahn/go-currency-patterns/pooling/pool&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;io&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;log&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;math/rand&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;sync&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;sync/atomic&quot;&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;time&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;maxGoroutines&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 실행할 수 있는 고루틴의 최대 개수&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;pooledResources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;// 풀이 관리할 리소스의 개수&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 공유 자원을 표한한 구조체&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbConnection&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// dbConnection 타입의 풀에 의해 관리될 수 있도록 io.Closer 인터페이스를 구현한다.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// Close 메서드는 자원의 해제를 담당한다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbConn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;닫힘: 데이터베이스 연결&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbConn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 각 데이터베이스에 유일한 id를 할당하기 위한 변수&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idCounter&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 풀이 새로운 리소스가 필요할 때 호출할 팩토리 메서드&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;createConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Closer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atomic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddInt32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idCounter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;생성: 새 데이터베이스 연결&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 애플리케이션 진입점&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WaitGroup&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;wg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxGoroutines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 데이터베이스 연결을 관리할 풀을 생성한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;createConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pooledResources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 풀에서 데이터베이스 연결을 가져와 질의를 실행한다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxGoroutines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c&quot;&gt;// 각 고루틴에는 질의 값의 복사본을 전달해야 한다.&lt;/span&gt;
		&lt;span class=&quot;c&quot;&gt;// 그렇지 않으면 고루틴들이 동일한 질의 값을 공유하게 된다.&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;performQueries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;wg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 고루틴의 실행이 종료될 때까지 대기한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;wg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 풀을 닫는다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;프로그램을 종료합니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// 데이터베이스 연결 리소스 풀을 테스트한다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;performQueries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// 풀에서 데이터베이스 연결 리소스를 획득한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Acquire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 데이터베이스 연결 리소스를 다시 풀로 되돌린다.&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// 질의문이 실행되는 것처럼 얼마 동안 대기한다.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Intn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;질의: QID[%d] CID[%d]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;실행-결과&quot;&gt;실행 결과&lt;/h2&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ go build -race pooling/main.go
❯ main
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 1
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 2
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 3
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 5
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 9
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 11
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 10
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 질의: QID[24] CID[10]
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 13

2021/05/09 15:52:51 리소스 획득: 공유된 리소스

2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 14
2021/05/09 15:52:51 질의: QID[38] CID[14]
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 16
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 18
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 4
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 19
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 질의: QID[43] CID[13]
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 7
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 20
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 21
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 22
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 질의: QID[10] CID[22]
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 23
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 17
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 24
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 26
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 25
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 27
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 28
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 29
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 30
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 31
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 32
2021/05/09 15:52:51 질의: QID[17] CID[32]
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 33
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 질의: QID[18] CID[33]
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 34
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 35
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 36
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 37
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 38
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 39
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 6
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 8
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 40
2021/05/09 15:52:51 질의: QID[28] CID[40]
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 12
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 15
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 41
2021/05/09 15:52:51 질의: QID[29] CID[41]
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 42
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 43
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 44
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 45
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 46
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 47
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 48
2021/05/09 15:52:51 질의: QID[12] CID[24]
2021/05/09 15:52:51 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:51 리소스 획득: 새로운 리소스
2021/05/09 15:52:51 생성: 새 데이터베이스 연결 49
2021/05/09 15:52:52 질의: QID[26] CID[12]
2021/05/09 15:52:52 질의: QID[14] CID[17]
2021/05/09 15:52:52 질의: QID[35] CID[8]
2021/05/09 15:52:52 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:52 리소스 반환: 리소스 큐에 반환
2021/05/09 15:52:52 질의: QID[4] CID[34]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 질의: QID[23] CID[39]
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 8
2021/05/09 15:52:52 질의: QID[34] CID[37]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 질의: QID[49] CID[1]
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 39
2021/05/09 15:52:52 질의: QID[44] CID[18]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 1
2021/05/09 15:52:52 질의: QID[21] CID[9]
2021/05/09 15:52:52 질의: QID[47] CID[10]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 18
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 34
2021/05/09 15:52:52 질의: QID[46] CID[21]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 37
2021/05/09 15:52:52 질의: QID[9] CID[26]
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 9
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 26
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 10
2021/05/09 15:52:52 리소스 반환: 리소스 해제
2021/05/09 15:52:52 닫힘: 데이터베이스 연결 21
2021/05/09 15:52:53 질의: QID[27] CID[6]
2021/05/09 15:52:53 질의: QID[5] CID[30]
2021/05/09 15:52:53 질의: QID[6] CID[29]
2021/05/09 15:52:53 질의: QID[25] CID[4]
2021/05/09 15:52:53 질의: QID[20] CID[2]
2021/05/09 15:52:53 질의: QID[22] CID[3]
2021/05/09 15:52:53 질의: QID[8] CID[28]
2021/05/09 15:52:53 질의: QID[11] CID[23]
2021/05/09 15:52:53 질의: QID[1] CID[36]
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 6
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 30
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 29
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 2
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 3
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 28
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 4
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 23
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 36
2021/05/09 15:52:53 질의: QID[48] CID[45]
2021/05/09 15:52:53 리소스 반환: 리소스 해제
2021/05/09 15:52:53 닫힘: 데이터베이스 연결 45
2021/05/09 15:52:54 질의: QID[0] CID[7]
2021/05/09 15:52:54 질의: QID[31] CID[43]
2021/05/09 15:52:54 질의: QID[36] CID[11]
2021/05/09 15:52:54 질의: QID[13] CID[49]
2021/05/09 15:52:54 질의: QID[32] CID[31]
2021/05/09 15:52:54 질의: QID[15] CID[25]
2021/05/09 15:52:54 질의: QID[19] CID[35]
2021/05/09 15:52:54 질의: QID[7] CID[27]
2021/05/09 15:52:54 질의: QID[39] CID[15]
2021/05/09 15:52:54 질의: QID[42] CID[44]
2021/05/09 15:52:54 질의: QID[3] CID[46]
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 7
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 43
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 11
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 49
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 31
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 25
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 35
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 27
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 15
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 44
2021/05/09 15:52:54 리소스 반환: 리소스 해제
2021/05/09 15:52:54 닫힘: 데이터베이스 연결 46
2021/05/09 15:52:55 질의: QID[2] CID[48]
2021/05/09 15:52:55 질의: QID[45] CID[16]
2021/05/09 15:52:55 질의: QID[30] CID[20]
2021/05/09 15:52:55 질의: QID[33] CID[5]
2021/05/09 15:52:55 질의: QID[40] CID[42]
2021/05/09 15:52:55 질의: QID[41] CID[47]
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 48
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 16
2021/05/09 15:52:55 질의: QID[16] CID[38]
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 20
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 38
2021/05/09 15:52:55 질의: QID[37] CID[19]
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 5
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 19
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 42
2021/05/09 15:52:55 리소스 반환: 리소스 해제
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 47
2021/05/09 15:52:55 프로그램을 종료합니다.
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 14
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 13
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 22
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 32
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 33
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 40
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 41
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 24
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 12
2021/05/09 15:52:55 닫힘: 데이터베이스 연결 17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">버퍼가 있는 채널을 이용하여 공유가 가능한 리소스의 풀을 생성하고, 이 리소스들을 원하는 개수만큼의 고루틴에서 개별적으로 활용할 수 있는 기능을 작성한 코드가 모여있다. 이 패턴은 데이터베이스 연결이나 메모리 버퍼 등 공유되는 리소스의 정적인 집합을 관리할 때 특히 유용하다. 고루틴이 이런 리소스 중 하나를 사용해야 할 경우에는 리소스를 할당받고 사용한 후 다시 풀에 반환하는 구조로 동작한다.(풀 사이즈 초과시 생성&amp;amp;사용후 폐기)</summary></entry><entry><title type="html">Singal Handle</title><link href="https://younghyun-ahn.github.io/2021/05/06/singal-handle.html" rel="alternate" type="text/html" title="Singal Handle" /><published>2021-05-06T00:00:00+00:00</published><updated>2021-05-06T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/06/singal-handle</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/06/singal-handle.html">&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Interrupt&lt;/code&gt;를 발생시켜 운영체제가 프로그램에 제재를 걸수 있다. 반대로 특정 입력이 들어올때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Signal&lt;/code&gt;을 잡아서 처리할수 있다. Singal은 신호라는 의미로 프로세스간 서로 통신할 때 사용한다. 굉장히 작은 값으로 Interrupt 라고 부르기도 한다. 용도가 제한적이며 여러 시그널이 겹칠 경우 원치 않는 결과가 발생할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Singal handler&lt;/code&gt;는 시그널을 받았을때 특정 동작을 하도록 정의 하는 코드(함수)이다. 보통의 방식으로 종료하거나 무시 또는 재시작 처리 한다. 운영체제 인터럽트를 수신하고 Singal handler를 정의하여 응용프로그램이 (가능한)깔끔하게 종료될 수 있도록 처리하는 것 이 목적이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/images/dont_sigkill.png&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;출처: &lt;a href=&quot;https://www.quora.com/What-is-the-difference-between-the-SIGINT-and-SIGTERM-signals-in-Linux-What%E2%80%99s-the-difference-between-the-SIGKILL-and-SIGSTOP-signals&quot;&gt;www.quora.com&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;시그널-처리-유형&quot;&gt;시그널 처리 유형&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;종료&lt;/li&gt;
  &lt;li&gt;무시&lt;/li&gt;
  &lt;li&gt;코어 덤프&lt;/li&gt;
  &lt;li&gt;중단&lt;/li&gt;
  &lt;li&gt;재시작&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;시그널-정보&quot;&gt;시그널 정보&lt;/h2&gt;

&lt;div class=&quot;language-terminal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2

❯ man signal
No    Name         Default Action       Description
1     SIGHUP       terminate process    terminal line hangup
2     SIGINT       terminate process    interrupt program
3     SIGQUIT      create core image    quit program
4     SIGILL       create core image    illegal instruction
5     SIGTRAP      create core image    trace trap
6     SIGABRT      create core image    abort program (formerly SIGIOT)
7     SIGEMT       create core image    emulate instruction executed
8     SIGFPE       create core image    floating-point exception
9     SIGKILL      terminate process    kill program
10    SIGBUS       create core image    bus error
11    SIGSEGV      create core image    segmentation violation
12    SIGSYS       create core image    non-existent system call invoked
13    SIGPIPE      terminate process    write on a pipe with no reader
14    SIGALRM      terminate process    real-time timer expired
15    SIGTERM      terminate process    software termination signal
16    SIGURG       discard signal       urgent condition present on socket
17    SIGSTOP      stop process         stop (cannot be caught or ignored)
18    SIGTSTP      stop process         stop signal generated from keyboard
19    SIGCONT      discard signal       continue after stop
20    SIGCHLD      discard signal       child status has changed
21    SIGTTIN      stop process         background read attempted from control terminal
22    SIGTTOU      stop process         background write attempted to control terminal
23    SIGIO        discard signal       I/O is possible on a descriptor (see fcntl(2))
24    SIGXCPU      terminate process    cpu time limit exceeded (see setrlimit(2))
25    SIGXFSZ      terminate process    file size limit exceeded (see setrlimit(2))
26    SIGVTALRM    terminate process    virtual time alarm (see setitimer(2))
27    SIGPROF      terminate process    profiling timer alarm (see setitimer(2))
28    SIGWINCH     discard signal       Window size change
29    SIGINFO      discard signal       status request from keyboard
30    SIGUSR1      terminate process    User defined signal 1
31    SIGUSR2      terminate process    User defined signal 2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// main.go&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SIGINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;syscall&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SIGTERM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;//signal.Notify(sigs, os.Interrupt)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Kill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;awaiting signal&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;done&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;existing&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;kill--9-kill-program&quot;&gt;kill -9 (kill program)&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ go build main.go
❯ main
awaiting signal
[1]    13673 killed     main
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;kill--15-terminate-signal&quot;&gt;kill -15 (terminate signal)&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ go build main.go
❯ main      
awaiting signal
terminated
existing
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ctrlc-사용자-인터럽트&quot;&gt;Ctrl+C (사용자 인터럽트)&lt;/h3&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ go build main.go
❯ main
awaiting signal
^Cinterrupt
existing
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/younghyun-ahn/go-etc/blob/master/signal_handle/main.go&quot;&gt;GitHub repository&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Interrupt를 발생시켜 운영체제가 프로그램에 제재를 걸수 있다. 반대로 특정 입력이 들어올때 Signal을 잡아서 처리할수 있다. Singal은 신호라는 의미로 프로세스간 서로 통신할 때 사용한다. 굉장히 작은 값으로 Interrupt 라고 부르기도 한다. 용도가 제한적이며 여러 시그널이 겹칠 경우 원치 않는 결과가 발생할 수 있다.</summary></entry><entry><title type="html">Protocol Buffers 3</title><link href="https://younghyun-ahn.github.io/2021/05/04/protocol-buffers.html" rel="alternate" type="text/html" title="Protocol Buffers 3" /><published>2021-05-04T00:00:00+00:00</published><updated>2021-05-04T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/04/protocol-buffers</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/04/protocol-buffers.html">&lt;p&gt;Need to think about data model and efficiency of the API.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JSON / XML / Something Binary&lt;/li&gt;
  &lt;li&gt;How much data do I get out of one call?&lt;/li&gt;
  &lt;li&gt;Too much data&lt;/li&gt;
  &lt;li&gt;Too little data -&amp;gt; many API calls?&lt;/li&gt;
  &lt;li&gt;Latency&lt;/li&gt;
  &lt;li&gt;Scalability to 1000s of clients&lt;/li&gt;
  &lt;li&gt;Load balancing&lt;/li&gt;
  &lt;li&gt;Inter operability with many languages&lt;/li&gt;
  &lt;li&gt;Authenticatin, Monitoring, Logging&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;an-evolution-of-data-type&quot;&gt;An Evolution of data type&lt;/h2&gt;

&lt;h3 id=&quot;csv-comma-separated-values&quot;&gt;CSV (Comma Separated Values)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Advantegs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Easy to parse&lt;/li&gt;
  &lt;li&gt;Easy to read&lt;/li&gt;
  &lt;li&gt;Easy to make sense of&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The data types of elements has to be inferred and is not a guarantee&lt;/li&gt;
  &lt;li&gt;Parsing becomes tricky when data contains commas&lt;/li&gt;
  &lt;li&gt;Column names may or may not be there&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;relational-tables-definitions&quot;&gt;Relational tables definitions&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Data is fully typed&lt;/li&gt;
  &lt;li&gt;Data fits in a table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Data has to be flat&lt;/li&gt;
  &lt;li&gt;Data is stored in a database, and data definition will be different for each database&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;json-javascript-object-notation&quot;&gt;JSON (JavaScript Object Notation)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Data can take any form (arrays, nested elements)&lt;/li&gt;
  &lt;li&gt;JSON is a widely accepted format on the web&lt;/li&gt;
  &lt;li&gt;JSON can be read by pretty much any language&lt;/li&gt;
  &lt;li&gt;JSON can be easily shared over a network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Data has no schema enforcing&lt;/li&gt;
  &lt;li&gt;JSON Objects can be quite big in size because of repeated keys&lt;/li&gt;
  &lt;li&gt;No comments, metadata, documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;protocol-buffers&quot;&gt;Protocol Buffers&lt;/h3&gt;

&lt;p&gt;Protocol Buffers is defined by a .proto text file. You can easily read it and understand it as a human.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Data is fully typed&lt;/li&gt;
  &lt;li&gt;Data is compressed automatically (less CPU usage)&lt;/li&gt;
  &lt;li&gt;Schema (defined using .proto file) is needed to generate code and read the data&lt;/li&gt;
  &lt;li&gt;Documentation can be embedded in the schema&lt;/li&gt;
  &lt;li&gt;Data can be read across any language (C#, Java, Go, Python, Javascript, etc…)&lt;/li&gt;
  &lt;li&gt;Schema can evolve over time, in a safe manager (schema evolution)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3-10x&lt;/code&gt; smaller, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;20-100x&lt;/code&gt; faster than XML&lt;/li&gt;
  &lt;li&gt;Code is generated for you automatically!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Protobuf support for some languages might be lacking (but the amin ones is fine)&lt;/li&gt;
  &lt;li&gt;Can’t “open” the serialized data with a text editor (because it’s compressed and serialised)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;to-share-data-accross-languages&quot;&gt;To share data accross languages!&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/images/protocol_buffers_accross_language.png&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;message-structure&quot;&gt;Message structure&lt;/h4&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// We are using proto3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;syntax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;proto3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;c&quot;&gt;// In Protocol Buffers we define message&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;// Field Ttype, Field Name, Field Tag (e.g. Number)&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_validated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;default-vlaues-for-fields&quot;&gt;Default Vlaues for fields&lt;/h4&gt;

&lt;p&gt;All fields, if not specified or unknown, will take a default value&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;bool: false&lt;/li&gt;
  &lt;li&gt;number (int32, etc…): 0&lt;/li&gt;
  &lt;li&gt;string: empty string&lt;/li&gt;
  &lt;li&gt;bytes: empty bytes&lt;/li&gt;
  &lt;li&gt;enum: first value&lt;/li&gt;
  &lt;li&gt;repeated: empty list&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;enums&quot;&gt;Enums&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;If you know all the values a field can take in advance, you can leverage th Enum type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The first value of an Enum is the default value&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Enum must start by the tag 0 (which is the default value)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;example&quot;&gt;Example&lt;/h4&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// simple.proto&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;syntax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;proto3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;go_package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;simple/simplepb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SimpleMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_simple&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;repeated&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;simple_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;protoc &lt;span class=&quot;nt&quot;&gt;-I&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--go_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; simple/simplepb/simple.proto
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// main.go&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doSimple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doSimple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;simplepb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SimpleMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;simplepb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SimpleMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12345&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;IsSimple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;My Simple Message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;SimpleList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;I renamed you&quot;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The ID is: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ go run main.go
0 &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; 12345 &lt;span class=&quot;nb&quot;&gt;true &lt;/span&gt;My Simple Message &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1 2 3 4]
0 &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; 12345 &lt;span class=&quot;nb&quot;&gt;true &lt;/span&gt;I renamed you &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;1 2 3 4]
The ID is:  12345
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/younghyun-ahn/go-etc/tree/master/protobuf&quot;&gt;GitHub repository&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Need to think about data model and efficiency of the API.</summary></entry><entry><title type="html">gRPC Deadlines</title><link href="https://younghyun-ahn.github.io/2021/05/03/grpc-deadlines.html" rel="alternate" type="text/html" title="gRPC Deadlines" /><published>2021-05-03T00:00:00+00:00</published><updated>2021-05-03T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/03/grpc-deadlines</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/03/grpc-deadlines.html">&lt;p&gt;Deadlines allow gRPC lcients to specify how long they ar willing to wait for and RPC to complete before the RPC is terminated with error DEADLINE_EXCEEDED. &lt;strong&gt;The gRPC documentation recommends you set a deadline for all client RPC calls.&lt;/strong&gt; Setting the deadline is up to you: how long do you feel your API should have to complete?&lt;/p&gt;

&lt;p&gt;The server should check if the deadline has exceeded and cancel the work it is doing.&lt;/p&gt;

&lt;p&gt;Note: Deadlines are propagated accross if gRPC calls are chained&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A =&amp;gt; B =&amp;gt; C (deadline for A is passed to B and thend passed to C)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;server&quot;&gt;Server&lt;/h2&gt;
&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Canceled&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c&quot;&gt;// the client canceled the request&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The client canceled the request!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Canceled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The client canceled the request&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;client&quot;&gt;Client&lt;/h2&gt;
&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WithTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Background&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HelloWithDeadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;statusErr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FromError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statusErr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeadlineExceeded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Timeout was hit! Deadline was exceeded&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Unexpected error: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statusErr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error while calling Hello RPC: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Response from Hello: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;console&quot;&gt;Console&lt;/h2&gt;
&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;❯ go run hello/hello_server/server.go
Hello server
HelloWithDeadline function was invoked with hello:{first_name:&quot;Younghyun&quot; last_name:&quot;Ahn&quot;}
HelloWithDeadline function was invoked with hello:{first_name:&quot;Younghyun&quot; last_name:&quot;Ahn&quot;}

❯ go run hello/hello_client/client.go
Hello client
2021/05/03 22:46:56 Response from Hello: Hello Younghyun
Timeout was hit! Deadline was exceeded
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://grpc.io/blog/deadlines/&quot;&gt;gRPC and Deadlines&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Deadlines allow gRPC lcients to specify how long they ar willing to wait for and RPC to complete before the RPC is terminated with error DEADLINE_EXCEEDED. The gRPC documentation recommends you set a deadline for all client RPC calls. Setting the deadline is up to you: how long do you feel your API should have to complete?</summary></entry><entry><title type="html">gRPC Introduction</title><link href="https://younghyun-ahn.github.io/2021/05/02/grpc-introduction.html" rel="alternate" type="text/html" title="gRPC Introduction" /><published>2021-05-02T00:00:00+00:00</published><updated>2021-05-02T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/02/grpc-introduction</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/02/grpc-introduction.html">&lt;p&gt;At the core of gRPC, you need to define the messages and services using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Protocol Buffers&lt;/code&gt;. The rest of the gRPC code will be generated for you and you’ll have to provide and implementatin for it. one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt; file works for over 12 programming languages (server and client), and allow you to use a framework that scales to millions of RPC per seconds.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;gRPC is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open-source&lt;/code&gt; framework developed by Google&lt;/li&gt;
  &lt;li&gt;gRPC is part of the Cloud Native Computation Foundation (CNCF) - like Docker &amp;amp; Kubernetes for example&lt;/li&gt;
  &lt;li&gt;At a high level, it allows you to define REQUEST and RESPONSE for RPC (Remote Procedure Calls) and handles all the rest for you&lt;/li&gt;
  &lt;li&gt;On top of it, it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modern&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fast and efficient&lt;/code&gt;, build on top of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP/2&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;low latency&lt;/code&gt;, supports &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;streaming&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;language independent&lt;/code&gt;, and makes it supper easy to plug in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authentication&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load balancing&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logging&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;monitoring&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;whats-an-rpc&quot;&gt;What’s an RPC?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;It’s not a new concept (CORBA had this berore).&lt;/li&gt;
  &lt;li&gt;With gRPC, it’s implemented very cleanly and solves a lot of problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/images/landing-2.svg&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;protocol-buffers&quot;&gt;Protocol Buffers?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;gRPC use Protocol Buffers for communications.&lt;/li&gt;
  &lt;li&gt;Let’s measure the payload size vs JSON:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// JSON: 55 bytes&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;age&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;first_name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Younhghyun&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;last_name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Ahn&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// same in Protocol BUffers: 20 bytes&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We save in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Network Bandwidth&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;efficiency-of-protocol-buffers-over-json&quot;&gt;Efficiency of Protocol Buffers over JSON&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Parsing JSON is actually CPU intensive (because toe format is human readable)&lt;/li&gt;
  &lt;li&gt;Parsing Protocol Buffers (binary format) is less CPU intensive because it’s closer to how a machine represents data&lt;/li&gt;
  &lt;li&gt;By using gRPC, the use of Protocol Buffers means &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;faster&lt;/code&gt; and more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;effcient&lt;/code&gt; communication, friendly with mobile device that have a slower CPU&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;summary-why-protocol-buffers&quot;&gt;Summary: Why Protocol Buffers?&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Easy to write message definition&lt;/li&gt;
  &lt;li&gt;The definition of the API is independent from the implementation&lt;/li&gt;
  &lt;li&gt;A huge amount of code can be generated, in andy language, from a simpe .proto file&lt;/li&gt;
  &lt;li&gt;The payload is binary, therefor very efficient to send / receive on a network and serialize / de-serializer on a CPU&lt;/li&gt;
  &lt;li&gt;Protocol Buffers defines rules to make an API evolve without breaking existing clients, with is helpful for microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;language-interoperability&quot;&gt;Language Interoperability&lt;/h2&gt;

&lt;p&gt;gRPC can be used by any language. Because the code can be generated for any language, it makes it super simple to create micro-services in any language that interact with each other.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/images/language_interoperability.png&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;4-types-of-api-in-grpc&quot;&gt;4 Types of API in gRPC&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;../../../assets/images/grpc_4type.png&quot; alt=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unary is what a traditional API looks like (HTTP REST)&lt;/li&gt;
  &lt;li&gt;HTTP/2 enables APIs to now have streaming capabilities.&lt;/li&gt;
  &lt;li&gt;The server and client can push multiple messages as part of one request!&lt;/li&gt;
  &lt;li&gt;In gRPC it’s very easy to define thes APIs as we’ll see&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;scalability-in-grpc&quot;&gt;Scalability in gRPC&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;gRPC Server are asynchronous by default&lt;/li&gt;
  &lt;li&gt;This means they do not block threads on request&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Therefore each gRPC server can serve millions of requests in parallel&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;gRPC Clients can be asynchronous or synchronous (blocking)&lt;/li&gt;
  &lt;li&gt;The client decides which model works best for the performance nees&lt;/li&gt;
  &lt;li&gt;gRPC Client can perform client side load balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;grpc-vs-rest&quot;&gt;gRPC vs REST&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;gRPC&lt;/th&gt;
      &lt;th&gt;REST&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Protocol Buffers - smaller, faster&lt;/td&gt;
      &lt;td&gt;JSON - text based, slower, bigger&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;HTTP/2 (lower latency) - from 2015&lt;/td&gt;
      &lt;td&gt;HTTP1.1 (high latency) - from 1997&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bidirectional &amp;amp; Async&lt;/td&gt;
      &lt;td&gt;Client =&amp;gt; Server requests only&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Stream Support&lt;/td&gt;
      &lt;td&gt;Request / Response support only&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;API Oriented-“WHAT” (no constraints - free design)&lt;/td&gt;
      &lt;td&gt;CRUD Oriented (Create-Retrieve-Update-Delete / POST GET PUT DELETE)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Code Generation through Protocol Buffers in any language - 1st class citizen&lt;/td&gt;
      &lt;td&gt;Code generation through OpenAPI / Swagger(add-on) - 2nd class citizen&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RPC Based - gRPC does the plumbing for us&lt;/td&gt;
      &lt;td&gt;HTTP verbs based - we have to write the plumbing or use a 3rd party library&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;summary-why-use-grpc&quot;&gt;Summary: Why use gRPC&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Easy code defiition in over 11 languages&lt;/li&gt;
  &lt;li&gt;Uses a mordern, low latency HTTP/2 transport mechanism&lt;/li&gt;
  &lt;li&gt;SSL Security is built in&lt;/li&gt;
  &lt;li&gt;Support for streaming APIs for maximum performance&lt;/li&gt;
  &lt;li&gt;gRPC is API oriented, insted of Resource Oriented like REST&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://medium.com/ruangguru-engineering/grpc-and-grpc-reflection-8cc1e395adb3&quot;&gt;gRPC and gRPC Reflection&lt;/a&gt;, &lt;a href=&quot;https://husobee.github.io/golang/rest/grpc/2016/05/28/golang-rest-v-grpc.html&quot;&gt;REST v. gRPC&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">At the core of gRPC, you need to define the messages and services using Protocol Buffers. The rest of the gRPC code will be generated for you and you’ll have to provide and implementatin for it. one .proto file works for over 12 programming languages (server and client), and allow you to use a framework that scales to millions of RPC per seconds.</summary></entry><entry><title type="html">gRPC Reflection &amp;amp; Evans CLI</title><link href="https://younghyun-ahn.github.io/2021/05/01/grpc-reflection.html" rel="alternate" type="text/html" title="gRPC Reflection &amp;amp; Evans CLI" /><published>2021-05-01T00:00:00+00:00</published><updated>2021-05-01T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/05/01/grpc-reflection</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/05/01/grpc-reflection.html">&lt;p&gt;gRPC Clients to connect to Server to have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt; file which defines the service.
This is fine for proeuctin(you definitely want to know the API definition in advance). For development, when you hanve a gRPC server you don’t know, simetimes you wish you could ask the server:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;“What APIs do you Have” ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reflection for two reaseons&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Having server &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expose&lt;/code&gt; which endpoints are available&lt;/li&gt;
  &lt;li&gt;Allow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;command line interfaces&lt;/code&gt; (CLI) to talk to our server without have preliminary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt; file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/grpc/grpc-go/tree/master/reflection&quot;&gt;gRPC Reflection&lt;/a&gt; for more info.&lt;/p&gt;

&lt;h2 id=&quot;server&quot;&gt;Server&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;google.golang.org/grpc/reflection&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RegisterYourOwnServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// Register reflection service on gRPC server.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;h3 id=&quot;macos&quot;&gt;macOS&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ brew tap ktr0731/evans
$ brew install evans
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;go-get&quot;&gt;go get&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ go get github.com/ktr0731/evans
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;usage-repl&quot;&gt;Usage (REPL)&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; evans
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; evans &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 50051 &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; show package
+---------+
| PACKAGE |
+---------+
| api     |
+---------+
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; package api
api@172.0.0.1:50051&amp;gt; show service
+---------+----------------------+-----------------------------+----------------+
| SERVICE |         RPC          |         REQUESTTYPE         |  RESPONSETYPE  |
+---------+----------------------+-----------------------------+----------------+
| Example | Unary                | SimpleRequest               | SimpleResponse |
|         | UnaryMessage         | UnaryMessageRequest         | SimpleResponse |
|         | UnaryRepeated        | UnaryRepeatedRequest        | SimpleResponse |
|         | UnaryRepeatedMessage | UnaryRepeatedMessageRequest | SimpleResponse |
|         | UnaryRepeatedEnum    | UnaryRepeatedEnumRequest    | SimpleResponse |
|         | UnarySelf            | UnarySelfRequest            | SimpleResponse |
|         | UnaryMap             | UnaryMapRequest             | SimpleResponse |
|         | UnaryMapMessage      | UnaryMapMessageRequest      | SimpleResponse |
|         | UnaryOneof           | UnaryOneofRequest           | SimpleResponse |
|         | UnaryEnum            | UnaryEnumRequest            | SimpleResponse |
|         | UnaryBytes           | UnaryBytesRequest           | SimpleResponse |
|         | ClientStreaming      | SimpleRequest               | SimpleResponse |
|         | ServerStreaming      | SimpleRequest               | SimpleResponse |
|         | BidiStreaming        | SimpleRequest               | SimpleResponse |
+---------+----------------------+-----------------------------+----------------+
api@172.0.0.1:50051&amp;gt; show message
+-----------------------------+
|           MESSAGE           |
+-----------------------------+
| SimpleRequest               |
| SimpleResponse              |
| Name                        |
| UnaryMessageRequest         |
| UnaryRepeatedRequest        |
| UnaryRepeatedMessageRequest |
| UnaryRepeatedEnumRequest    |
| UnarySelfRequest            |
| Person                      |
| UnaryMapRequest             |
| UnaryMapMessageRequest      |
| UnaryOneofRequest           |
| UnaryEnumRequest            |
| UnaryBytesRequest           |
+-----------------------------+
api@172.0.0.1:50051&amp;gt; desc SimpleRequest
+-------+-------------+
| FIELD |    TYPE     |
+-------+-------------+
| name  | TYPE_STRING |
+-------+-------------+

&lt;span class=&quot;c&quot;&gt;# Call a gRPC&lt;/span&gt;
api@172.0.0.1:50051&amp;gt; service Example
api.Example@172.0.0.1:50051&amp;gt; call Unary
name &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;TYPE_STRING&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; ktr
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;hello, ktr&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;real-world-service-reference&quot;&gt;Real world service (reference)&lt;/h2&gt;

&lt;p&gt;Google uses gRPC for some of ti’s most important cloud service:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/googleapis/googleapis/blob/master/google/pubsub/v1/pubsub.proto&quot;&gt;Google Pub/Sub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/googleapis/googleapis/blob/master/google/spanner/v1/spanner.proto&quot;&gt;Google Spanner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://grpc.io/&quot;&gt;grpc.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/grpc-ecosystem/grpc-gateway&quot;&gt;RESTful HTTP API into gRPC&lt;/a&gt;&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">gRPC Clients to connect to Server to have a .proto file which defines the service. This is fine for proeuctin(you definitely want to know the API definition in advance). For development, when you hanve a gRPC server you don’t know, simetimes you wish you could ask the server: “What APIs do you Have” ?</summary></entry><entry><title type="html">gRPC SSL Security</title><link href="https://younghyun-ahn.github.io/2021/04/29/grpc-ssl-security.html" rel="alternate" type="text/html" title="gRPC SSL Security" /><published>2021-04-29T00:00:00+00:00</published><updated>2021-04-29T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2021/04/29/grpc-ssl-security</id><content type="html" xml:base="https://younghyun-ahn.github.io/2021/04/29/grpc-ssl-security.html">&lt;p&gt;gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, and to encrypt all the data exchanged between the client and the server. Optional mechanisms are available for clients to provide certificates for mutual authentication.&lt;/p&gt;

&lt;h2 id=&quot;certificate-files-by-openssl&quot;&gt;Certificate files by openssl&lt;/h2&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;ca.key&lt;/td&gt;
      &lt;td&gt;Certificate Authority &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private key&lt;/code&gt; file (this shouldn’t be shsare in real-life)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ca.crt&lt;/td&gt;
      &lt;td&gt;Certificate Authority trust &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;certificate&lt;/code&gt; (this should be share with user in real-life)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;server.key&lt;/td&gt;
      &lt;td&gt;Server private key, passwrod protected (this shouldn’t b share)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;server.csr&lt;/td&gt;
      &lt;td&gt;Server certificate signing request (thils should be shared with the CA owner)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;server.crt&lt;/td&gt;
      &lt;td&gt;Server certificate signed by the CA (this would be sent back by the CA owner) - keep on server&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;server.pem&lt;/td&gt;
      &lt;td&gt;Conversion for server.key into a format gRRPC like (this shouldn’t be share)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;caution&quot;&gt;Caution&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Private files: ca.key, server.key, sever.pem, server.crt&lt;/li&gt;
  &lt;li&gt;Share files: ca.crt (need by the client), server.csr (need by th CA)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;openssl&quot;&gt;Openssl&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Changes these CN's to match your hosts in your envrioment if need.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SERVER_CN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;localhost

&lt;span class=&quot;c&quot;&gt;# Step 1: Generate Certificate Authority + Trust Certificate (ca.crt)&lt;/span&gt;
openssl genrsa &lt;span class=&quot;nt&quot;&gt;-passout&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-des3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; ca.key 4096
openssl req &lt;span class=&quot;nt&quot;&gt;-passin&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-x509&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-days&lt;/span&gt; 365 &lt;span class=&quot;nt&quot;&gt;-key&lt;/span&gt; ca.key &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; ca.crt &lt;span class=&quot;nt&quot;&gt;-subj&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/CN=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SERVER_CN&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Step 2: Generate the Server Private Key (server.key)&lt;/span&gt;
openssl genrsa &lt;span class=&quot;nt&quot;&gt;-passout&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-des3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; server.key 4096

&lt;span class=&quot;c&quot;&gt;# Step 3: Get a certificate signing request from the CA (server.csr)&lt;/span&gt;
openssl req &lt;span class=&quot;nt&quot;&gt;-passin&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-key&lt;/span&gt; server.key &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; server.csr &lt;span class=&quot;nt&quot;&gt;-subj&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/CN=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SERVER_CN&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Step 4: Sign the certificate with the CA we created (it's called self signing) - server.crt&lt;/span&gt;
openssl x509 &lt;span class=&quot;nt&quot;&gt;-req&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-passin&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-days&lt;/span&gt; 365 &lt;span class=&quot;nt&quot;&gt;-in&lt;/span&gt; server.csr &lt;span class=&quot;nt&quot;&gt;-CA&lt;/span&gt; ca.crt &lt;span class=&quot;nt&quot;&gt;-CAkey&lt;/span&gt; ca.key &lt;span class=&quot;nt&quot;&gt;-set_serial&lt;/span&gt; 01 &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; server.crt

&lt;span class=&quot;c&quot;&gt;# Step 5: Convert the server certificate to .pem format (server.pem) - usable by gRPC&lt;/span&gt;
openssl pkcs8 &lt;span class=&quot;nt&quot;&gt;-topk8&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-nocrypt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-passin&lt;/span&gt; pass:1111 &lt;span class=&quot;nt&quot;&gt;-in&lt;/span&gt; server.key &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; server.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example-code&quot;&gt;Example Code&lt;/h2&gt;

&lt;h2 id=&quot;sever&quot;&gt;Sever&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;n&quot;&gt;lis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0.0.0.0:50051&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Faild to listen: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;certFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;server.crt&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;keyFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;server.pem&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newServerTLSFromFIle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;certFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Faild loading certificates: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;faild to serve: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;client&quot;&gt;Client&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-golang&quot; data-lang=&quot;golang&quot;&gt;&lt;span class=&quot;n&quot;&gt;certFile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ca.cert&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// Certification Authority Trust certificate&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newClientTLSFromFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;certFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error while loading CA trust certificate: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WithTransportCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;localhost:50051&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;could not connect: %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewGreetClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://grpc.io/docs/guides/auth/#go&quot;&gt;gRPC Docs&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, and to encrypt all the data exchanged between the client and the server. Optional mechanisms are available for clients to provide certificates for mutual authentication.</summary></entry><entry><title type="html">Welcome to minima-reboot</title><link href="https://younghyun-ahn.github.io/2017/12/26/welcome-to-minima-reboot.html" rel="alternate" type="text/html" title="Welcome to minima-reboot" /><published>2017-12-26T00:00:00+00:00</published><updated>2017-12-26T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2017/12/26/welcome-to-minima-reboot</id><content type="html" xml:base="https://younghyun-ahn.github.io/2017/12/26/welcome-to-minima-reboot.html">&lt;p&gt;Welcome to &lt;a href=&quot;https://github.com/aterenin/minima-reboot&quot;&gt;Minima Reboot&lt;/a&gt;, a Bootstrap-based rewrite of &lt;a href=&quot;https://github.com/jekyll/minima&quot;&gt;Minima&lt;/a&gt;, the base Jekyll theme. Check out the responsive navigation menu and footer by changing your browser’s width. This is a post in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_posts&lt;/code&gt; directory. You can view Minima Reboot’s source on &lt;a href=&quot;https://github.com/aterenin/minima-reboot&quot;&gt;GitHub&lt;/a&gt;. Minima Reboot inherits Jekyll’s support for code highlighting, as shown below.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_hi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hi, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;print_hi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Tom'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#=&amp;gt; prints 'Hi, Tom' to STDOUT.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/aterenin/minima-reboot&quot;&gt;GitHub repository&lt;/a&gt; for more info.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Welcome to Minima Reboot, a Bootstrap-based rewrite of Minima, the base Jekyll theme. Check out the responsive navigation menu and footer by changing your browser’s width. This is a post in the _posts directory. You can view Minima Reboot’s source on GitHub. Minima Reboot inherits Jekyll’s support for code highlighting, as shown below.</summary></entry><entry><title type="html">Even More Posts For Pagination</title><link href="https://younghyun-ahn.github.io/2016/05/20/even-more-posts-for-pagination.html" rel="alternate" type="text/html" title="Even More Posts For Pagination" /><published>2016-05-20T00:00:00+00:00</published><updated>2016-05-20T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2016/05/20/even-more-posts-for-pagination</id><content type="html" xml:base="https://younghyun-ahn.github.io/2016/05/20/even-more-posts-for-pagination.html">&lt;p&gt;Eos eu docendi tractatos sapientem, brute option menandri in vix, quando vivendo accommodare te ius. Nec melius fastidii constituam id, viderer theophrastus ad sit, hinc semper periculis cum id. Noluisse postulant assentior est in, no choro sadipscing repudiandae vix. Vis in euismod delenit dignissim. Ex quod nostrum sit, suas decore animal id ius, nobis solet detracto quo te.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Eos eu docendi tractatos sapientem, brute option menandri in vix, quando vivendo accommodare te ius. Nec melius fastidii constituam id, viderer theophrastus ad sit, hinc semper periculis cum id. Noluisse postulant assentior est in, no choro sadipscing repudiandae vix. Vis in euismod delenit dignissim. Ex quod nostrum sit, suas decore animal id ius, nobis solet detracto quo te.</summary></entry><entry><title type="html">More Posts For Pagination</title><link href="https://younghyun-ahn.github.io/2016/05/20/more-posts-for-pagination.html" rel="alternate" type="text/html" title="More Posts For Pagination" /><published>2016-05-20T00:00:00+00:00</published><updated>2016-05-20T00:00:00+00:00</updated><id>https://younghyun-ahn.github.io/2016/05/20/more-posts-for-pagination</id><content type="html" xml:base="https://younghyun-ahn.github.io/2016/05/20/more-posts-for-pagination.html">&lt;p&gt;Eos eu docendi tractatos sapientem, brute option menandri in vix, quando vivendo accommodare te ius. Nec melius fastidii constituam id, viderer theophrastus ad sit, hinc semper periculis cum id. Noluisse postulant assentior est in, no choro sadipscing repudiandae vix. Vis in euismod delenit dignissim. Ex quod nostrum sit, suas decore animal id ius, nobis solet detracto quo te.&lt;/p&gt;</content><author><name>younghyun-ahn</name></author><summary type="html">Eos eu docendi tractatos sapientem, brute option menandri in vix, quando vivendo accommodare te ius. Nec melius fastidii constituam id, viderer theophrastus ad sit, hinc semper periculis cum id. Noluisse postulant assentior est in, no choro sadipscing repudiandae vix. Vis in euismod delenit dignissim. Ex quod nostrum sit, suas decore animal id ius, nobis solet detracto quo te.</summary></entry></feed>