<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Fahmi Irfan</title>
	<subtitle></subtitle>
	<link href="https://fahmifan.id/feed.xml" rel="self"/>
	<link href="https://fahmifan.id/"/>
	
	<updated>2018-02-12T03:29:18+07:00</updated>
	
	<id>https://fahmifan.id</id>
	<author>
  <name>Fahmi Irfan</name>
  <email>me@fahmifan.id</email>
	</author>
	
  
  <entry>
    <title>Benchmarking Golang Slice Allocation</title>
    <link href="https://fahmifan.id/posts/2024/01/benchmarking-golang-slice-allocation/"/>
    <updated>2024-02-12T07:00:00+07:00</updated>
    <id>https://fahmifan.id/posts/2024/01/benchmarking-golang-slice-allocation/</id>
    <content type="html"><![CDATA[
      <p><picture><source type="image/webp" srcset="/images/floppy-disk-unsplash-300w.webp 300w, /images/floppy-disk-unsplash-640w.webp 640w, /images/floppy-disk-unsplash-800w.webp 800w, /images/floppy-disk-unsplash-1280w.webp 1280w, /images/floppy-disk-unsplash-2670w.webp 2670w" sizes="(min-width: 1024px) 100vw, 50vw"><source type="image/jpeg" srcset="/images/floppy-disk-unsplash-300w.jpeg 300w, /images/floppy-disk-unsplash-640w.jpeg 640w, /images/floppy-disk-unsplash-800w.jpeg 800w, /images/floppy-disk-unsplash-1280w.jpeg 1280w, /images/floppy-disk-unsplash-2670w.jpeg 2670w" sizes="(min-width: 1024px) 100vw, 50vw"><img alt="Photo by Vincent Botta on Unsplash" title="Photo by Vincent Botta on Unsplash" loading="lazy" decoding="async" src="/images/floppy-disk-unsplash-300w.jpeg" width="2670" height="1780"></picture></p>
<p>I was reading <a href="https://oilbeater.com/en/2024/03/04/golang-slice-performance/">The Impact of Pre-allocating Slice Memory on Performance in Golang</a> and was curious about the benchmark, so I wanted to try it too for <a href="https://github.com/fahmifan/autograd">Autograd</a>.</p>
<p>Slice preallocation means we specify the len when creating the slice and it will create a slice with n-empty items on it. Then, to assign a value to the slice, we need to use the index.
Example of prealloc a <code>userIDs</code></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line">userIDs <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span>uuid<span class="token punctuation">.</span>UUID<span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>assignments<span class="token punctuation">)</span><span class="token punctuation">)</span></span><br><span class="highlight-line"><span class="token keyword">for</span> i<span class="token punctuation">,</span> assignment <span class="token operator">:=</span> <span class="token keyword">range</span> assignments <span class="token punctuation">{</span></span><br><span class="highlight-line">	userIDs<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> assignment<span class="token punctuation">.</span>AssignedBy</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>In Autograd, there is a page where the admin can see a list of assignments. This page typically contains 10-20 assignments with pagination. Then, I was curious if there is an impact if we preallocate for this slice of struct, since in the article, the writer didn’t explain the struct layout. In the struct I tested, it has 8 fields, and 3 of them are also structs. In my honest opinion, this struct can represent many backend service codes.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">var</span> asg <span class="token operator">=</span> assignments<span class="token punctuation">.</span>Assignment<span class="token punctuation">{</span></span><br><span class="highlight-line">	ID<span class="token punctuation">:</span>          uuid<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	Name<span class="token punctuation">:</span>        <span class="token string">"Assignment 1"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	Description<span class="token punctuation">:</span> <span class="token string">"Description 1"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	DeadlineAt<span class="token punctuation">:</span>  time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	Assigner<span class="token punctuation">:</span> assignments<span class="token punctuation">.</span>Assigner<span class="token punctuation">{</span></span><br><span class="highlight-line">		ID<span class="token punctuation">:</span>     uuid<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		Name<span class="token punctuation">:</span>   <span class="token string">"Assigner 1"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		Active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	CaseInputFile<span class="token punctuation">:</span> assignments<span class="token punctuation">.</span>CaseFile<span class="token punctuation">{</span></span><br><span class="highlight-line">		ID<span class="token punctuation">:</span>   uuid<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		URL<span class="token punctuation">:</span>  <span class="token string">"http://example.com"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		Type<span class="token punctuation">:</span> <span class="token string">"input"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		TimestampMetadata<span class="token punctuation">:</span> core<span class="token punctuation">.</span>TimestampMetadata<span class="token punctuation">{</span></span><br><span class="highlight-line">			CreatedAt<span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			UpdatedAt<span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			DeletedAt<span class="token punctuation">:</span> null<span class="token punctuation">.</span><span class="token function">NewTime</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	CaseOutputFile<span class="token punctuation">:</span> assignments<span class="token punctuation">.</span>CaseFile<span class="token punctuation">{</span></span><br><span class="highlight-line">		ID<span class="token punctuation">:</span>   uuid<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		URL<span class="token punctuation">:</span>  <span class="token string">"http://example.com"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		Type<span class="token punctuation">:</span> <span class="token string">"input"</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		TimestampMetadata<span class="token punctuation">:</span> core<span class="token punctuation">.</span>TimestampMetadata<span class="token punctuation">{</span></span><br><span class="highlight-line">			CreatedAt<span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			UpdatedAt<span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			DeletedAt<span class="token punctuation">:</span> null<span class="token punctuation">.</span><span class="token function">NewTime</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	TimestampMetadata<span class="token punctuation">:</span> core<span class="token punctuation">.</span><span class="token function">NewTimestampMeta</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Time<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>For the benchmark, I want to check for lengths of 10, 20, and 50 slices to represent a real scenario. The result is interesting, where the preallocation has a big performance boost of 1000x! You can check the benchmark <a href="https://github.com/fahmifan/autograd/blob/f398f7ace1b22fb4d7cf81ebd87ee4cc7abc8132/pkg/core/assignments/assignment_repository_bench_test.go">here</a>.</p>
<pre class="language-log"><code class="language-log"><span class="highlight-line">go test <span class="token operator">-</span>benchmem <span class="token operator">-</span>bench <span class="token punctuation">.</span> github<span class="token punctuation">.</span>com<span class="token operator">/</span>fahmifan<span class="token operator">/</span>autograd<span class="token operator">/</span>pkg<span class="token operator">/</span>core<span class="token operator">/</span>assignments</span><br><span class="highlight-line"><span class="token property">goos:</span> darwin</span><br><span class="highlight-line"><span class="token property">goarch:</span> arm64</span><br><span class="highlight-line"><span class="token property">pkg:</span> github<span class="token punctuation">.</span>com<span class="token operator">/</span>fahmifan<span class="token operator">/</span>autograd<span class="token operator">/</span>pkg<span class="token operator">/</span>core<span class="token operator">/</span>assignments</span><br><span class="highlight-line">BenchmarkAssignmentNoPrealloc_10<span class="token operator">-</span><span class="token number">8</span>         <span class="token number">363208</span>              <span class="token number">3327</span> ns<span class="token operator">/</span>op           <span class="token number">15808</span> B<span class="token operator">/</span>op          <span class="token number">5</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line">BenchmarkAssignmentPrealloc_10<span class="token operator">-</span><span class="token number">8</span>        <span class="token number">165713173</span>             <span class="token number">7.198</span> ns<span class="token operator">/</span>op               <span class="token number">0</span> B<span class="token operator">/</span>op          <span class="token number">0</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line"></span><br><span class="highlight-line">BenchmarkAssignmentNoPrealloc_20<span class="token operator">-</span><span class="token number">8</span>         <span class="token number">177516</span>              <span class="token number">6080</span> ns<span class="token operator">/</span>op           <span class="token number">32192</span> B<span class="token operator">/</span>op          <span class="token number">6</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line">BenchmarkAssignmentPrealloc_20<span class="token operator">-</span><span class="token number">8</span>         <span class="token number">96115022</span>             <span class="token number">12.32</span> ns<span class="token operator">/</span>op               <span class="token number">0</span> B<span class="token operator">/</span>op          <span class="token number">0</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line"></span><br><span class="highlight-line">BenchmarkAssignmentNoPrealloc_50<span class="token operator">-</span><span class="token number">8</span>          <span class="token number">99542</span>             <span class="token number">12601</span> ns<span class="token operator">/</span>op           <span class="token number">64960</span> B<span class="token operator">/</span>op          <span class="token number">7</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line">BenchmarkAssignmentPrealloc_50<span class="token operator">-</span><span class="token number">8</span>         <span class="token number">43292256</span>             <span class="token number">27.91</span> ns<span class="token operator">/</span>op               <span class="token number">0</span> B<span class="token operator">/</span>op          <span class="token number">0</span> allocs<span class="token operator">/</span>op</span><br><span class="highlight-line">PASS</span><br><span class="highlight-line">ok      github<span class="token punctuation">.</span>com<span class="token operator">/</span>fahmifan<span class="token operator">/</span>autograd<span class="token operator">/</span>pkg<span class="token operator">/</span>core<span class="token operator">/</span>assignments       <span class="token number">8.980s</span></span></code></pre>
<p>So, it's highly recommended to always preallocate a slice if we know the size ahead of time. The overhead is small, but the performance boost is significant.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Self-Deploy Comment and Analytic App</title>
    <link href="https://fahmifan.id/posts/2022/feb/self-deploy-comment-and-analytics/"/>
    <updated>2022-02-26T07:00:00+07:00</updated>
    <id>https://fahmifan.id/posts/2022/feb/self-deploy-comment-and-analytics/</id>
    <content type="html"><![CDATA[
      <p><picture><source type="image/webp" srcset="/images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-300w.webp 300w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-640w.webp 640w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-800w.webp 800w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-1280w.webp 1280w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-3872w.webp 3872w" sizes="(min-width: 1024px) 100vw, 50vw"><source type="image/jpeg" srcset="/images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-300w.jpeg 300w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-640w.jpeg 640w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-800w.jpeg 800w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-1280w.jpeg 1280w, /images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-3872w.jpeg 3872w" sizes="(min-width: 1024px) 100vw, 50vw"><img alt="Photo by Étienne Beauregard-Riverin on Unsplash" title="Photo by Étienne Beauregard-Riverin on Unsplash" loading="lazy" decoding="async" src="/images/etienne-beauregard-riverin-B0aCvAVSX8E-unsplash-300w.jpeg" width="3872" height="2592"></picture></p>
<p>After <a href="/posts/2022/feb/migrating-blog-to-11ty/">Migrating My site to 11ty</a>, I decided to self-deploy the comment &amp; analytic app for this website. Why? Because it's fun to learn something new and I'd like to keep those data on my box. So, these are my review for comments &amp; analytics apps that you can self-deploy.</p>
<h2>Comment</h2>
<p>So, I begin by searching for the comment app. I want it to be lightweight so it won't take
many resources on my cheap server. I already know about Commento, so I search for &quot;<em>Commento alternative open-source</em>&quot;, these the top result list:</p>
<ul>
<li><a href="https://commento.io/">Commento</a></li>
<li><a href="https://utteranc.es/">Utterances</a></li>
<li><a href="https://posativ.org/isso/">Isso</a></li>
</ul>
<p>Commento is widely popular, actively maintained, has a nice UI, has a managed cloud version &amp; privacy compliant. The backend is written in Go, which is nice. But the managed version price is quite expensive for me &amp; the DB choice is only Postgres.</p>
<p>Utterances is popular too, it uses Github issues as its backend, it's open-source, &amp; privacy compliant. But you need to have a Github account to add a comment. So, It is not good for the general audience.</p>
<p>Isso is also popular, actively maintained, &amp; privacy compliant. The backend is written in Python, and uses SQLite for the DB. The UI is ok, I just need to style the font to match my website style.</p>
<p>For the comment app, I choose Isso for its simplicity &amp; SQLite choice as DB. The <a href="/tags/deployment">deployment</a> is quite easy, it comes with a prebuilt binary. So, I just deployed it as systemd service and put it behind a reverse proxy.</p>
<h2>Analytic</h2>
<p>For analytics I already have some choices, they are:</p>
<ul>
<li><a href="https://umami.is/">Umami</a></li>
<li><a href="https://plausible.io/">Plausible</a></li>
<li><a href="https://usefathom.com/">Fathom</a></li>
</ul>
<p>Umami is popular &amp; widely used, actively maintain, feature-rich &amp; privacy compliant. It is written in NextJS and Prism. The UI is nice &amp; the DB choices are Postgres or MySQL.</p>
<p>Plausible is quite the same as Umami, but it offered a SaaS version. It is written in Elixir, has modern UI, and It should be very performant. The DB choices are Clickhouse or Postgres.</p>
<p>Fathom has two versions the lite and pro. The lite version is the old Fathom, rarely maintained, written in Go and Preact, and the DB choices are SQLite or Postgres. The pro version is a SaaS &amp; has more features compared to the lite version.</p>
<blockquote>
<p>I also found <a href="https://goaccess.io/">GoAccess</a> a server-side tracker. Written in C (super fast!), feature-rich, &amp; privacy compliant.</p>
</blockquote>
<p>For the analytic, I choose Fathom Lite. Even if it's not actively maintained anymore, I'll still be able to maintain it to some extent. Yeah, I <a href="https://Github.com/fahmifan/fathom">forked</a> it, upgrade the Go version, and fix some accessibility issues as suggested by the Chrome Lighthouse.</p>
<p>Deployment is easy because it is single binary &amp; uses SQLite. I just make it as systemd service and put it behind a reverse proxy.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Migrating Blog to 11ty</title>
    <link href="https://fahmifan.id/posts/2022/feb/migrating-blog-to-11ty/"/>
    <updated>2022-02-24T07:00:00+07:00</updated>
    <id>https://fahmifan.id/posts/2022/feb/migrating-blog-to-11ty/</id>
    <content type="html"><![CDATA[
      <p><picture><source type="image/webp" srcset="/images/arron-choi-kRK1Bne4xEw-unsplash-300w.webp 300w, /images/arron-choi-kRK1Bne4xEw-unsplash-640w.webp 640w, /images/arron-choi-kRK1Bne4xEw-unsplash-800w.webp 800w, /images/arron-choi-kRK1Bne4xEw-unsplash-1280w.webp 1280w, /images/arron-choi-kRK1Bne4xEw-unsplash-6240w.webp 6240w" sizes="(min-width: 1024px) 100vw, 50vw"><source type="image/jpeg" srcset="/images/arron-choi-kRK1Bne4xEw-unsplash-300w.jpeg 300w, /images/arron-choi-kRK1Bne4xEw-unsplash-640w.jpeg 640w, /images/arron-choi-kRK1Bne4xEw-unsplash-800w.jpeg 800w, /images/arron-choi-kRK1Bne4xEw-unsplash-1280w.jpeg 1280w, /images/arron-choi-kRK1Bne4xEw-unsplash-6240w.jpeg 6240w" sizes="(min-width: 1024px) 100vw, 50vw"><img alt="Photo by Arron Choi on Unsplash" title="Photo by Arron Choi on Unsplash" loading="lazy" decoding="async" src="/images/arron-choi-kRK1Bne4xEw-unsplash-300w.jpeg" width="6240" height="4160"></picture></p>
<p>So, I migrate my blog to 11ty using <a href="https://hylia.website/">Hylia Starter Kit</a>. The reason is that it is more flexible and easier to customize.</p>
<p>My old Hugo blog was using template too but, it using the git submodule. Which is not realy easy to customize. Well Hugo is faster, but I don't think I'll need it for a small blog site like this.</p>
<p>The migration process is quite simple. First I <code>degit</code> the template using <code>npx degit github.com/hankchizljaw/hylia</code>. Then I change the site metadata like site title, author, email, favicon, etc. Then, I copy the markdown blog contents from Hugo to 11ty. Also, i decided to include the images in the blog repo, before this I store the images in a separate Github repo.</p>
<p>Deployment is the same, first I added a new submodule of my github pages into the 11ty blog repo. Build 11ty blog in production mode, copy the <code>dist</code> into the submodule, and pushed it. Then, the new site will be deployed by Github. The script looks like this</p>
<pre class="language-bash"><code class="language-bash"><span class="highlight-line"><span class="token function">rm</span> -rf ./dist/*</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token function">npm</span> run production</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token function">cp</span> -r ./dist/* ./thesubmodule</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment"># Go To the submodule folder</span></span><br><span class="highlight-line"><span class="token builtin class-name">cd</span> thesubmodule</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment"># Stage changes to git.</span></span><br><span class="highlight-line"><span class="token function">git</span> <span class="token function">add</span> <span class="token builtin class-name">.</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment"># Commit</span></span><br><span class="highlight-line"><span class="token assign-left variable">msg</span><span class="token operator">=</span><span class="token string">"rebuilding site <span class="token variable"><span class="token variable">`</span><span class="token function">date</span><span class="token variable">`</span></span>"</span></span><br><span class="highlight-line"><span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token variable">$#</span> -eq <span class="token number">1</span> <span class="token punctuation">]</span></span><br><span class="highlight-line">  <span class="token keyword">then</span> <span class="token assign-left variable">msg</span><span class="token operator">=</span><span class="token string">"<span class="token variable">$1</span>"</span></span><br><span class="highlight-line"><span class="token keyword">fi</span></span><br><span class="highlight-line"><span class="token function">git</span> commit -m <span class="token string">"<span class="token variable">$msg</span>"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment"># Push source and build repos.</span></span><br><span class="highlight-line"><span class="token function">git</span> push origin master</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment"># Come Back up to the Project Root</span></span><br><span class="highlight-line"><span class="token builtin class-name">cd</span> <span class="token punctuation">..</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token function">git</span> <span class="token function">add</span> thesubmodule/</span><br><span class="highlight-line"><span class="token function">git</span> commit -m <span class="token string">"rebuild site <span class="token variable"><span class="token variable">`</span><span class="token function">date</span><span class="token variable">`</span></span>"</span></span><br><span class="highlight-line"><span class="token function">git</span> push origin master</span></code></pre>
<p>That's it how I migrate from Hugo to 11ty. Here is the lighthouse audit result
<picture><source type="image/webp" srcset="/images/new-11ty-site-score-300w.webp 300w, /images/new-11ty-site-score-640w.webp 640w, /images/new-11ty-site-score-750w.webp 750w" sizes="(min-width: 1024px) 100vw, 50vw"><source type="image/jpeg" srcset="/images/new-11ty-site-score-300w.jpeg 300w, /images/new-11ty-site-score-640w.jpeg 640w, /images/new-11ty-site-score-750w.jpeg 750w" sizes="(min-width: 1024px) 100vw, 50vw"><img alt="Lighthouse audit result" title="Lighthouse audit result" loading="lazy" decoding="async" src="/images/new-11ty-site-score-300w.jpeg" width="750" height="455"></picture></p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Install Veikk Driver Linux</title>
    <link href="https://fahmifan.id/posts/2021/jun/install-veikk-driver-linux/"/>
    <updated>2021-06-14T05:52:08+07:00</updated>
    <id>https://fahmifan.id/posts/2021/jun/install-veikk-driver-linux/</id>
    <content type="html"><![CDATA[
      <p>I decided to buy a Veikk pen tablet S640, but it's drivers only for Mac and Windows.
And fortunately, there are <a href="https://github.com/jlam55555/veikk-linux-driver">driver</a> and <a href="https://github.com/jlam55555/veikk-linux-driver-gui">GUI tools</a> for the S640 from <a href="https://github.com/jlam55555">jlam55555</a>.</p>
<p>Following the installation guides, voila! enjoy your pen tablet on Linux.</p>
<p><img src="/images/veikk-driver/enjoy.png" alt="enjoy"></p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>What is LRU Cache And How It Works ?</title>
    <link href="https://fahmifan.id/posts/2021/jun/lru-cache/"/>
    <updated>2021-06-13T10:24:35+07:00</updated>
    <id>https://fahmifan.id/posts/2021/jun/lru-cache/</id>
    <content type="html"><![CDATA[
      <h1>What is LRU cache</h1>
<p>A cache is a way to store data that accessed frequently and needs to be fast. We can use cache to store a result from computation or result of SQL query. A cache is usually stored in memory with a key-value style to make sure it fast to store item and access.</p>
<p>One of the cache algorithms is LRU or <em>Least Recently Used</em>. LRU will limit the memory usage by gives maximum items that can be stored. When there is a new item to be store and it already reached the limit, it discards the least used item.</p>
<h1>How to make LRU Cache in GO</h1>
<blockquote>
<p>TLDR</p>
<p>Check the full code in this repo</p>
<ul>
<li><a href="https://github.com/fahmifan/lrucache/tree/lru-no-concurrency">lrucache (non concurrent)</a></li>
<li><a href="https://github.com/fahmifan/lrucache">lrucache (concurrent)</a></li>
</ul>
</blockquote>
<p>There are two main components in LRU cache, those are <code>Queue</code> and <code>Hash Map</code>. The <code>Queue</code> is used to store the items that implemented in a linked list, while the <code>Hash Map</code> is used to make the complexity <code>O(1)</code> when accessed.</p>
<p><img src="/images/lru-cache/queue-and-hash.png" alt="Queue &amp; Hash Map"></p>
<h2>Creating Queue</h2>
<blockquote>
<p>Disclaimer</p>
<p>The queue I implemented is based on my opinion, it may not be the &quot;right&quot; one :)</p>
</blockquote>
<p>We need to create a struct for the cache item, a linked list node, and the queue.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">type</span> Queue <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	head <span class="token operator">*</span>Node</span><br><span class="highlight-line">	tail <span class="token operator">*</span>Node</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> Node <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	item Item</span><br><span class="highlight-line">	next <span class="token operator">*</span>Node</span><br><span class="highlight-line">	prev <span class="token operator">*</span>Node</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> Item <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	Key   <span class="token builtin">string</span></span><br><span class="highlight-line">    <span class="token comment">// Value is used to store an item</span></span><br><span class="highlight-line">	Value <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>We will create three methods for the queue <code>InsertFirst</code>, <code>RemoveLast</code>, and <code>RemoveNode</code>.</p>
<p>The structure of the Node. It has three parts, <code>prev</code>, <code>value</code>, and <code>next</code>. The <code>prev</code> and <code>next</code> are pointers to an adjacent node. The <code>value</code> is an <code>interface{}</code> that can hold any data type.
<img src="/images/lru-cache/node.png" alt="a node"></p>
<p>These are algorithm and code for <code>InsertFirst</code>
<img src="/images/lru-cache/insert-first-algo.png" alt="insert first algorithm"></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// insert a node into the first of the queue</span></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">InsertFirst</span><span class="token punctuation">(</span>newHead <span class="token operator">*</span>Node<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>head <span class="token operator">=</span> newHead</span><br><span class="highlight-line">		q<span class="token punctuation">.</span>tail <span class="token operator">=</span> newHead</span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	oldHead <span class="token operator">:=</span> q<span class="token punctuation">.</span>head</span><br><span class="highlight-line">	newHead<span class="token punctuation">.</span>next <span class="token operator">=</span> oldHead</span><br><span class="highlight-line">	oldHead<span class="token punctuation">.</span>prev <span class="token operator">=</span> newHead</span><br><span class="highlight-line">	q<span class="token punctuation">.</span>head <span class="token operator">=</span> newHead</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>These are algorithm and code for <code>RemoveLast</code>
<img src="/images/lru-cache/remove-last-algo.png" alt="remove last"></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// remove a node from the last queue</span></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">RemoveLast</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>Node <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		last <span class="token operator">:=</span> q<span class="token punctuation">.</span>tail</span><br><span class="highlight-line">		q<span class="token punctuation">.</span>tail <span class="token operator">=</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>head <span class="token operator">=</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">		last<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span> last</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	oldLast <span class="token operator">:=</span> q<span class="token punctuation">.</span>tail</span><br><span class="highlight-line">	newLast <span class="token operator">:=</span> q<span class="token punctuation">.</span>tail<span class="token punctuation">.</span>prev</span><br><span class="highlight-line">	q<span class="token punctuation">.</span>tail <span class="token operator">=</span> newLast</span><br><span class="highlight-line">	oldLast<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> oldLast</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>These are algorithm and code for <code>RemoveNode</code>
<img src="/images/lru-cache/remove-node-0.png" alt="remove node 0">
<img src="/images/lru-cache/remove-node-1.png" alt="remove node 2"></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// remove a node from any position in the queue</span></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">RemoveNode</span><span class="token punctuation">(</span>node <span class="token operator">*</span>Node<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>tail<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// node is first in the queue with following N-nodes</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> node <span class="token operator">==</span> q<span class="token punctuation">.</span>head <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token comment">// new head is the next in the queue</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>head <span class="token operator">=</span> node<span class="token punctuation">.</span>next</span><br><span class="highlight-line">		node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// node is the last in the queue with previos N-nodes</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> node <span class="token operator">==</span> q<span class="token punctuation">.</span>tail <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token comment">// new tail is the one before the node</span></span><br><span class="highlight-line">		q<span class="token punctuation">.</span>tail <span class="token operator">=</span> node<span class="token punctuation">.</span>prev</span><br><span class="highlight-line">		node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// node is in the middle of the queue</span></span><br><span class="highlight-line">	after <span class="token operator">:=</span> node<span class="token punctuation">.</span>next</span><br><span class="highlight-line">	before <span class="token operator">:=</span> node<span class="token punctuation">.</span>prev</span><br><span class="highlight-line">	<span class="token comment">// link the before &amp; after</span></span><br><span class="highlight-line">	before<span class="token punctuation">.</span>next <span class="token operator">=</span> after</span><br><span class="highlight-line">	after<span class="token punctuation">.</span>prev <span class="token operator">=</span> before</span><br><span class="highlight-line">	node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>The code for <code>MoveToFirst</code></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">MoveToFirst</span><span class="token punctuation">(</span>node <span class="token operator">*</span>Node<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token comment">// no need to move, there is one or none in the queue</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> q<span class="token punctuation">.</span><span class="token function">isOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span>head <span class="token operator">==</span> node <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> q<span class="token punctuation">.</span>tail <span class="token operator">==</span> node <span class="token punctuation">{</span></span><br><span class="highlight-line">		beforeTail <span class="token operator">:=</span> node<span class="token punctuation">.</span>prev</span><br><span class="highlight-line">		q<span class="token punctuation">.</span>tail <span class="token operator">=</span> beforeTail</span><br><span class="highlight-line">		beforeTail<span class="token punctuation">.</span>next <span class="token operator">=</span> <span class="token boolean">nil</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">		node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		node<span class="token punctuation">.</span>next <span class="token operator">=</span> q<span class="token punctuation">.</span>head</span><br><span class="highlight-line">		q<span class="token punctuation">.</span>head <span class="token operator">=</span> node</span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	nodeBefore <span class="token operator">:=</span> node<span class="token punctuation">.</span>prev</span><br><span class="highlight-line">	nodeAfter <span class="token operator">:=</span> node<span class="token punctuation">.</span>next</span><br><span class="highlight-line">	nodeBefore<span class="token punctuation">.</span>next <span class="token operator">=</span> nodeAfter</span><br><span class="highlight-line">	nodeAfter<span class="token punctuation">.</span>prev <span class="token operator">=</span> nodeBefore</span><br><span class="highlight-line">	node<span class="token punctuation">.</span><span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	node<span class="token punctuation">.</span>next <span class="token operator">=</span> q<span class="token punctuation">.</span>head</span><br><span class="highlight-line">	q<span class="token punctuation">.</span>head <span class="token operator">=</span> node</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Helper methods for the <code>Queue</code></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> q<span class="token punctuation">.</span>head <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> q<span class="token punctuation">.</span>tail <span class="token operator">==</span> <span class="token boolean">nil</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>q <span class="token operator">*</span>Queue<span class="token punctuation">)</span> <span class="token function">isOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> q<span class="token punctuation">.</span>head <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> q<span class="token punctuation">.</span>head<span class="token punctuation">.</span>next <span class="token operator">==</span> <span class="token boolean">nil</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>The <code>breakLinks</code> method is implemented as follows</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// set next &amp; prev to nil</span></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>n <span class="token operator">*</span>Node<span class="token punctuation">)</span> <span class="token function">breakLinks</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> n <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	n<span class="token punctuation">.</span>next <span class="token operator">=</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">	n<span class="token punctuation">.</span>prev <span class="token operator">=</span> <span class="token boolean">nil</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<h2>Creating LRUCacher</h2>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// LRUCacher not concurrent safe</span></span><br><span class="highlight-line"><span class="token keyword">type</span> LRUCacher <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	queue       <span class="token operator">*</span>Queue</span><br><span class="highlight-line">	hash        <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">*</span>Node</span><br><span class="highlight-line">	MaxSize     <span class="token builtin">int</span></span><br><span class="highlight-line">	count <span class="token builtin">int</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Codes for Put</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token comment">// Put set new or replace existing item</span></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>LRUCacher<span class="token punctuation">)</span> <span class="token function">Put</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">,</span> value <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> l<span class="token punctuation">.</span>MaxSize <span class="token operator">&lt;</span> <span class="token number">1</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		l<span class="token punctuation">.</span>MaxSize <span class="token operator">=</span> DefaultMaxSize</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> l<span class="token punctuation">.</span>queue <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		l<span class="token punctuation">.</span>queue <span class="token operator">=</span> <span class="token function">NewQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">if</span> l<span class="token punctuation">.</span>hash <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		l<span class="token punctuation">.</span>hash <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">*</span>Node<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	item <span class="token operator">:=</span> Item<span class="token punctuation">{</span></span><br><span class="highlight-line">		Key<span class="token punctuation">:</span>   key<span class="token punctuation">,</span></span><br><span class="highlight-line">		Value<span class="token punctuation">:</span> value<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// if key already exist just replace the cache item</span></span><br><span class="highlight-line">	oldNode<span class="token punctuation">,</span> ok <span class="token operator">:=</span> l<span class="token punctuation">.</span>hash<span class="token punctuation">[</span>key<span class="token punctuation">]</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> ok <span class="token punctuation">{</span></span><br><span class="highlight-line">		oldNode<span class="token punctuation">.</span>item <span class="token operator">=</span> item</span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	node <span class="token operator">:=</span> <span class="token operator">&amp;</span>Node<span class="token punctuation">{</span>item<span class="token punctuation">:</span> item<span class="token punctuation">}</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> l<span class="token punctuation">.</span><span class="token function">queueIsFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		last <span class="token operator">:=</span> l<span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">RemoveLast</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		l<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>last<span class="token punctuation">.</span>item<span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">		l<span class="token punctuation">.</span>hash<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> node</span><br><span class="highlight-line">		l<span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">InsertFirst</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	l<span class="token punctuation">.</span>hash<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> node</span><br><span class="highlight-line">	l<span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">InsertFirst</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span></span><br><span class="highlight-line">	l<span class="token punctuation">.</span>count<span class="token operator">++</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>The recently called item, will be move to the first of the queue</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>LRUCacher<span class="token punctuation">)</span> <span class="token function">Get</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> l<span class="token punctuation">.</span>hash <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	val<span class="token punctuation">,</span> ok <span class="token operator">:=</span> l<span class="token punctuation">.</span>hash<span class="token punctuation">[</span>key<span class="token punctuation">]</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	l<span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">MoveToFirst</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">return</span> val<span class="token punctuation">.</span>item<span class="token punctuation">.</span>Value</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Codes for Del</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>LRUCacher<span class="token punctuation">)</span> <span class="token function">Del</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	node<span class="token punctuation">,</span> ok <span class="token operator">:=</span> l<span class="token punctuation">.</span>hash<span class="token punctuation">[</span>key<span class="token punctuation">]</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token keyword">return</span> <span class="token boolean">nil</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	l<span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">RemoveNode</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span></span><br><span class="highlight-line">	l<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>node<span class="token punctuation">.</span>item<span class="token punctuation">)</span></span><br><span class="highlight-line">    l<span class="token punctuation">.</span>count<span class="token operator">--</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> node<span class="token punctuation">.</span>item<span class="token punctuation">.</span>Value</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<h1>Notes on Implement Synchronization for Concurrency</h1>
<p>The previous codes work for non-concurrent usage because when accessing &amp; writing to the hash map or queue, there are needs for lock and synchronization. Also keep in mind, that adding synchronization will impact the performance.</p>
<p>We can use a <code>mutex</code> for synchronization. In Go, there are two types of mutex, <code>Mutex</code> and <code>RWMutex</code>. The <code>Mutex</code> is general purpose for locking only one goroutine that has access to a resource. The <code>RWMutex</code> has two locking mechanisms. The first is <code>RLock</code> that can behold by multiple gorutines and is used for reading. The Second is a <code>Lock</code> that can only behold by one goroutine and is used for writing.</p>
<p>I use two mutexes for <code>LRUCacher</code>, <code>hashMutex</code> for access &amp; mutating <code>hash</code>, and <code>countMutex</code> when mutating the <code>count</code>. Also, to help to detects race condition, I use <code>-race</code> flag when running the go test</p>
<pre><code>go test -race ./...
</code></pre>
<p>The rest of the code can be checked in this repo <a href="https://github.com/fahmifan/lrucache">lrucache</a></p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">type</span> LRUCacher <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	maxSize <span class="token builtin">int64</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	queue      <span class="token operator">*</span>Queue</span><br><span class="highlight-line">	count      <span class="token builtin">int64</span></span><br><span class="highlight-line">	countMutex sync<span class="token punctuation">.</span>RWMutex</span><br><span class="highlight-line"></span><br><span class="highlight-line">	hash      <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">*</span>Node</span><br><span class="highlight-line">	hashMutex sync<span class="token punctuation">.</span>RWMutex</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>The benchmark</p>
<pre><code>go test -benchmem -run=^$ -bench ^(BenchmarkLRUCacher)$ github.com/fahmifan/lrucache

goos: linux
goarch: amd64
pkg: github.com/fahmifan/lrucache
cpu: Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz
BenchmarkLRUCacher/Put-4         	 2813918	       422.4 ns/op	      89 B/op	       4 allocs/op
BenchmarkLRUCacher/Get-4         	 9076047	       131.4 ns/op	      16 B/op	       1 allocs/op
BenchmarkLRUCacher/Del-4         	11179544	       107.6 ns/op	      12 B/op	       1 allocs/op
PASS
ok  	github.com/fahmifan/lrucache	4.228s
</code></pre>
<p>That's the LRU Cache and how you can implement it in Go :)</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Setup Bluetooth Adapter on Linux</title>
    <link href="https://fahmifan.id/posts/2021/jun/setup-bluetooth-adapter-on-linux/"/>
    <updated>2021-06-09T06:52:16+07:00</updated>
    <id>https://fahmifan.id/posts/2021/jun/setup-bluetooth-adapter-on-linux/</id>
    <content type="html"><![CDATA[
      <p>I have a desktop with Linux installed on it and i would like to add bluetooth adapter for it. This is my Linux version</p>
<pre><code>➜ uname -v -r   
5.8.0-55-generic #62~20.04.1-Ubuntu SMP Wed Jun 2 08:55:04 UTC 2021
</code></pre>
<p>So i decided to bought
this &quot;ORICO BTA508 USB Bluetooth 5.0 Dongle BTA 508 BTA-508 Adapter - Hitam&quot; from <a href="https://www.tokopedia.com/clickandgo/orico-bta508-usb-bluetooth-5-0-dongle-bta-508-bta-508-adapter-hitam">Tokopedia</a>. But, the only official driver/firmware is for Windows.</p>
<p>Then, how about Linux ? To solve this question, we need to know which chip the bluetooth uses and install a custom firmware/driver.</p>
<p>Use this command to check what chips the bluetooth adapter use</p>
<pre><code>dmesg | grep -i Bluetooth
</code></pre>
<p>The output should looks like this</p>
<pre><code>[    1.810236] usb 1-4.2: Product: Bluetooth Radio
...
[    3.546498] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761b_fw.bin
[    3.551034] Bluetooth: hci0: RTL: loading rtl_bt/rtl8761b_config.bin
...
</code></pre>
<p>This line <code>hci0: RTL: loading rtl_bt/rtl8761b_fw.bin</code> shows us, that the chip is <code>rtl8761b</code> and it need <code>rtl8761b_fw</code> firmware/driver.
So i google <code>rtl8761b_fw</code> and found an article from <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=294634">raspberry forum</a> with the same question.</p>
<p>But, to be sure i look up to it once again and found this arch linux <a href="https://aur.archlinux.org/packages/rtl8761b-fw/">post</a>. After i read from arch linux post, i decided to follow it. So, i download the driver from the <a href="https://mpow.s3-us-west-1.amazonaws.com/mpow_BH519A_driver+for+Linux.7z">source</a> mention in the article and follow the steps from the raspberry forum article as follows:</p>
<ol>
<li>Extract the driver</li>
<li>Copy the drivers</li>
</ol>
<pre><code>sudo cp -iv 20201202_LINUX_BT_DRIVER/rtkbt-firmware/lib/firmware/rtlbt/rtl8761b_fw /lib/firmware/rtl_bt/rtl8761b_fw.bin

sudo cp -iv 20201202_LINUX_BT_DRIVER/rtkbt-firmware/lib/firmware/rtlbt/rtl8761b_config /lib/firmware/rtl_bt/rtl8761b_config.bin
</code></pre>
<ol start="3">
<li>Reboot</li>
</ol>
<p>Thats it, when i check on bluetooth manager, it works</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Setup Caddy Web Server</title>
    <link href="https://fahmifan.id/posts/2021/may/setup-caddy-web-server/"/>
    <updated>2021-05-08T21:03:22+07:00</updated>
    <id>https://fahmifan.id/posts/2021/may/setup-caddy-web-server/</id>
    <content type="html"><![CDATA[
      <p>Goal:</p>
<ul>
<li>setup caddy web server as user systemd service</li>
</ul>
<p>Steps:</p>
<ul>
<li>create working directory (workdir)<pre><code>mkdir -p ~/admin/caddy
</code></pre>
</li>
<li>download caddy v2 into workdir</li>
<li>Allow non root to listen on port 80 &amp; 443<pre><code>sudo setcap cap_net_bind_service=+ep ./caddy
</code></pre>
</li>
<li>create a <code>Caddyfile</code> in <code>~/admin/caddy</code>. A simple reverse proxy example<pre><code>example.com {
    reverse_proxy localhost:8000
}
</code></pre>
</li>
<li>add this systemd unit file into <code>~/.config/systemd/user/caddy.service</code><pre><code>[Unit]
Description=Caddy Web Server
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=10
ExecStart=/home/deployr/admin/caddy/caddy run
WorkingDirectory=/home/deployr/admin/caddy
LimitNOFILE=4096
PIDFile=/var/run/caddy/caddy.pid

[Install]
WantedBy=default.target
</code></pre>
</li>
<li>make sure your user already <code>enable linger</code> to start the service as user on boot. Login as <code>root</code> then run<pre><code>loginctl enable-linger deployr
</code></pre>
</li>
<li>reload systemd<pre><code>systemctl --user daemon-reload
</code></pre>
</li>
<li>enable caddy on boot<pre><code>systemctl --user enable caddy.service
</code></pre>
</li>
<li>start it<pre><code>systemctl --user start caddy.service
</code></pre>
</li>
<li>check if it running well<pre><code>systemctl --user status caddy.service
</code></pre>
</li>
<li>to check the log use <code>journalctl</code><pre><code>journalctl -f --user-unit=caddy
</code></pre>
</li>
</ul>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Initial Ubuntu Vps Setup</title>
    <link href="https://fahmifan.id/posts/2021/may/initial-ubuntu-vps-setup/"/>
    <updated>2021-05-08T06:52:16+07:00</updated>
    <id>https://fahmifan.id/posts/2021/may/initial-ubuntu-vps-setup/</id>
    <content type="html"><![CDATA[
      <p>Goal:</p>
<ul>
<li>setup user untuk <code>deployr</code></li>
<li>referensi: <a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04">Initial Server Setup with Ubuntu 20.04</a></li>
</ul>
<p>Steps:</p>
<ul>
<li>buat instance di vps provider
<ul>
<li>kalau pakai linode tambahkan ssh laptop biar ga perlu input password pas ssh as <code>root</code></li>
</ul>
</li>
<li>ssh as root <code>ssh root@IP</code></li>
<li>create new <code>deployr</code> with sudo access
<ul>
<li><code>adduser deployr</code></li>
<li>input password</li>
<li>untuk user info, bisa pakai default, tekan enter aja</li>
</ul>
</li>
<li>grant admin privileges
<ul>
<li><code>usermod -aG admin deployr</code></li>
</ul>
</li>
<li>setup basic firewall
<ul>
<li><code>ufw app list</code>, harusnya cuma ada OpenSSH</li>
<li><code>ufw enable</code>, aktifkan ufw</li>
<li>cek status sudah nyala atau belum <code>ufw status</code></li>
</ul>
</li>
<li>tambah ssh untuk user <code>deployr</code>
<ul>
<li>kalau laptop nya sama saat buat instance, bisa pakai ssh user <code>root</code>, tinggal pakai rsync</li>
<li>masih login sebagi <code>root</code> di vps</li>
<li><code>rsync --archive --chown=deployr:deployr ~/.ssh /home/deployr</code></li>
</ul>
</li>
</ul>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Information Overflow</title>
    <link href="https://fahmifan.id/posts/2021/mar/controlling-information/"/>
    <updated>2021-03-21T18:13:57+07:00</updated>
    <id>https://fahmifan.id/posts/2021/mar/controlling-information/</id>
    <content type="html"><![CDATA[
      <p>Like eating, consuming informations should have a portion.
We have limited appetiet, too much eating results into sick stomach, stress.
Fear of Missing Out or FOMO, is a kind of anxity that comes from &quot;too much information&quot;.</p>
<p>Internet might be the source of this. Why ? Open internet, bring massive, free, and
accessible information into socity. Social media, a decendant of internet known as &quot;rich&quot; in information, such as Twitter, Instagram, Tiktok, Youtube. Game, richer than those socmeds combine audio, visual, story telling and interactivity.</p>
<blockquote>
<p>So, what is the root that cause this &quot;Information Overflow&quot; ?</p>
</blockquote>
<p>Is it our behaviour that keep staring at our screen ? Is it the context switching? Socmed has many different context between it tweets. Is it creates low quality in absorbing information ? Is it creating the FOMO ? Do we actually have this &quot;quality&quot; ?</p>
<p>My hunch is yes. Actullay, i barely remember the tweets that i have read. When i found an interesting articel/tweet i save it into &quot;getpocket&quot; app. But, its unlikely that i'll visit them in getpocket. This might be the result of FOMO.</p>
<p>In Software Engineering, there is a phrase You Aren't Gonna Need It or Yagni. It means, you rarely need something that beyond scope. Now, how to identify if something categorized as Yagni ? If it less or insignificant, leave it, put it into Yagni. I think, information around internet is the same, the level of significant will weigh them to falls into Yagni or not.</p>
<p>But, how to make the information a Yagni or not for us, if we have not read or saw it ? I don't know yet. May be, we can hide them behind a software. It is like someone hand picked information for us in digestable size.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Apa Itu Event Bus ?</title>
    <link href="https://fahmifan.id/posts/2020/march/apa-itu-event-bus/"/>
    <updated>2020-04-05T15:43:31+07:00</updated>
    <id>https://fahmifan.id/posts/2020/march/apa-itu-event-bus/</id>
    <content type="html"><![CDATA[
      <p>Event bus adalah sebuah mekanisme yg bisa dipakai untuk berkomunikasi antar komponen tanpa saling tahu satu sama lain. Kalau bisa saya bilang ini juga bagian <em>pub-sub</em> pattern. Lalu, apa kegunaan dari event bus ini?
Kegunaanya adalah untuk <em>decoupled</em> antar komponen sehingga tidak saling bergantung secara langsung.
Keuntungan lainnya adalah, kita bisa membuat <em>monolith</em> rasa <em>microservice</em>.
Dalam arsitektur <em>microservice</em>, salah satu pattern yg sering dipakai adalah <em>pubsub</em>, dan kita bisa menerapkan pubsub ini dalam arsitektur <em>monolith</em> melalui <em>event bus</em>.</p>
<p>Jika digambarkan event bus itu berbentuk seperti gambar berikut
<picture><source type="image/webp" srcset="/images/1586077919152-event-bus-300w.webp 300w, /images/1586077919152-event-bus-640w.webp 640w, /images/1586077919152-event-bus-800w.webp 800w, /images/1586077919152-event-bus-970w.webp 970w" sizes="(min-width: 1024px) 100vw, 50vw"><source type="image/jpeg" srcset="/images/1586077919152-event-bus-300w.jpeg 300w, /images/1586077919152-event-bus-640w.jpeg 640w, /images/1586077919152-event-bus-800w.jpeg 800w, /images/1586077919152-event-bus-970w.jpeg 970w" sizes="(min-width: 1024px) 100vw, 50vw"><img alt="Event Bus" title="Event Bus" loading="lazy" decoding="async" src="/images/1586077919152-event-bus-300w.jpeg" width="970" height="534"></picture></p>
<p>Dimana ada <em>publisher</em> yang dapat mengirim sebuah pesan ke <em>Event Bus</em> dan pesan ini dapat didapatkan oleh banyak <em>subscriber</em>.</p>
<h2>Menggunakan event bus</h2>
<p>Kita akan coba menggunakan event bus dalam program yang akan kita buat. Dan kita akan membuatnya menggunakan bahasa Go atau Golang.</p>
<blockquote>
<p>Jika kalian belum tahu tentang bahasa Golang, bisa cek <a href="https://dasarpemrogramangolang.novalagung.com/">Dasar Pemrograman Golang</a>.</p>
</blockquote>
<p>Yang akan kita jadikan kasus adalah order barang dan payment pada sebuah <strong>Online shop</strong>. Ketika user membuat sebuah order maka akan dibuat sebuah payment.</p>
<pre><code>
+-------------+
|create order +----------+
+-------------+          |
                    +----v----+
                    |         |
                    |   BUS   |
                    |         |
                    +----^----+
                         |
                         |
+--------------+         |
|create payment+---------+
+--------------+

</code></pre>
<h2>Init project</h2>
<p>Oke, pertama kita perlu melakukan ini project. Buat folder project kalian, lalu init module dengan mengetikkan command <code>go mod init shop</code> di folder project. Untuk mempersingkat, saya akan namai module ini sebagai <code>shop</code>.</p>
<blockquote>
<p>Versi Go yang digunakan pada saat pembuatan artikel ini adalah <code>go1.12.17</code>.</p>
</blockquote>
<p>Selanjutnya kita akan buat model nya terlebih dahulu. Buat package <code>model</code>, lalu buat file <code>model.go</code>.</p>
<pre><code>├── model
│   └── model.go
</code></pre>
<p>Di package model ini, kita membuat tiga buah <code>struct</code> yaitu <code>Product</code>, <code>Order</code>, dan <code>Payment</code>.
Sebuah Order dapat memiliki banyak product di dalam nya.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> model</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token string">"fmt"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> Product <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	ID    <span class="token builtin">int64</span></span><br><span class="highlight-line">	Price <span class="token builtin">float64</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> Order <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	ID         <span class="token builtin">int64</span></span><br><span class="highlight-line">	ProductIDs <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Lalu sebuah Payment akan memiliki OrderID berikut <code>PaymentStatus</code> nya.
<code>PaymentStatus</code> ini bisa dibilang adalah sebuah &quot;enum&quot;, yang memiliki tiga tipe yaitu <code>pending</code>, <code>paid</code> dan <code>canceled</code>.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">type</span> Payment <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	ID      <span class="token builtin">int64</span></span><br><span class="highlight-line">	OrderID <span class="token builtin">int64</span></span><br><span class="highlight-line">	Status  PaymentStatus</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> PaymentStatus <span class="token builtin">int</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token comment">// PaymentStatus enum</span></span><br><span class="highlight-line"><span class="token keyword">const</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	PaymentStatusPending  <span class="token operator">=</span> <span class="token function">PaymentStatus</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	PaymentStatusPaid     <span class="token operator">=</span> <span class="token function">PaymentStatus</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	PaymentStatusCanceled <span class="token operator">=</span> <span class="token function">PaymentStatus</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span></code></pre>
<p>Selanjutnya, kita akan membuat package <code>service</code>. Ada tiga buah service yang dibuat yaitu <code>ProductService</code>, <code>OrderService</code> dan <code>PaymentService</code> yang semuanya merupakan <code>interface</code>.</p>
<pre><code>└── service
    └── service.go
</code></pre>
<p><code>ProductService</code> akan memiliki method yaitu <code>List</code>. Lalu, <code>OrderService</code> memiliki method <code>CreateOrder</code>. Terkahir, <code>PaymentService</code> akan memiliki method <code>CreatePayment</code>.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> service</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token string">"shop/model"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	ProductService <span class="token keyword">interface</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>model<span class="token punctuation">.</span>Product</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	OrderService <span class="token keyword">interface</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token function">CreateOrder</span><span class="token punctuation">(</span>productIDs <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span><span class="token punctuation">)</span> <span class="token operator">*</span>model<span class="token punctuation">.</span>Order</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	PaymentService <span class="token keyword">interface</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token function">CreatePayment</span><span class="token punctuation">(</span>orderID <span class="token builtin">int64</span><span class="token punctuation">)</span> <span class="token operator">*</span>model<span class="token punctuation">.</span>Payment</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span></code></pre>
<p>Selanjutnya kita perlu melakukan implementasi dari <code>interface</code> tersebut dengan <code>struct</code>.
Pada package <code>service</code> buat file <code>product_service</code>.</p>
<pre><code>└── service
    ├── product_service.go
</code></pre>
<p>Untuk mempersingkat, data product akan kita simpan di dalam field <code>products</code>. Lalu, dengan fungsi <code>NewProductService</code> kita melakukan instansiasi <code>productService</code> sekaligus mengisi field <code>products</code> dengan data dummy.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> service</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"shop/model"</span></span><br><span class="highlight-line">	<span class="token string">"time"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> productService <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">    products <span class="token punctuation">[</span><span class="token punctuation">]</span>model<span class="token punctuation">.</span>Product</span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token function">NewProductService</span><span class="token punctuation">(</span><span class="token punctuation">)</span> ProductService <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> <span class="token operator">&amp;</span>productService<span class="token punctuation">{</span></span><br><span class="highlight-line">		products<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>model<span class="token punctuation">.</span>Product<span class="token punctuation">{</span></span><br><span class="highlight-line">			model<span class="token punctuation">.</span>Product<span class="token punctuation">{</span>ID<span class="token punctuation">:</span> <span class="token number">111</span><span class="token punctuation">,</span> Price<span class="token punctuation">:</span> <span class="token number">100.0</span><span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			model<span class="token punctuation">.</span>Product<span class="token punctuation">{</span>ID<span class="token punctuation">:</span> <span class="token number">112</span><span class="token punctuation">,</span> Price<span class="token punctuation">:</span> <span class="token number">200.0</span><span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">			model<span class="token punctuation">.</span>Product<span class="token punctuation">{</span>ID<span class="token punctuation">:</span> <span class="token number">113</span><span class="token punctuation">,</span> Price<span class="token punctuation">:</span> <span class="token number">300.0</span><span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		<span class="token punctuation">}</span><span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>ps <span class="token operator">*</span>productService<span class="token punctuation">)</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>model<span class="token punctuation">.</span>Product <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> ps<span class="token punctuation">.</span>products</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Lalu, buat file <code>order_service</code> pada package <code>service</code>.</p>
<pre><code>└── service
    ├── order_service.go
</code></pre>
<p>Pada kode ini, terdapat field <code>bus</code> dengan tipe <code>*bus.Bus</code> yang digunakan untuk mempublish event/topic. pacakge yang digunakan adalah <code>github.com/mustafaturan/bus</code>. Argumen ke dua pada fungsi <code>Emit</code> adalah nama topic yg dipublish, di sini kita gunakan nama <code>order.created</code>.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> service</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"context"</span></span><br><span class="highlight-line">	<span class="token string">"time"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token string">"shop/eventbus"</span></span><br><span class="highlight-line">	<span class="token string">"shop/model"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/bus"</span></span><br><span class="highlight-line">	log <span class="token string">"github.com/sirupsen/logrus"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> orderService <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">    bus            <span class="token operator">*</span>bus<span class="token punctuation">.</span>Bus</span><br><span class="highlight-line">    productService ProductService</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token function">NewOrderService</span><span class="token punctuation">(</span>ps ProductService<span class="token punctuation">,</span> bus <span class="token operator">*</span>bus<span class="token punctuation">.</span>Bus<span class="token punctuation">)</span> OrderService <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> <span class="token operator">&amp;</span>orderService<span class="token punctuation">{</span></span><br><span class="highlight-line">		productService<span class="token punctuation">:</span> ps<span class="token punctuation">,</span></span><br><span class="highlight-line">		bus<span class="token punctuation">:</span>            bus<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>o <span class="token operator">*</span>orderService<span class="token punctuation">)</span> <span class="token function">CreateOrder</span><span class="token punctuation">(</span>productIDs <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span><span class="token punctuation">)</span> <span class="token operator">*</span>model<span class="token punctuation">.</span>Order <span class="token punctuation">{</span></span><br><span class="highlight-line">	order <span class="token operator">:=</span> <span class="token operator">&amp;</span>model<span class="token punctuation">.</span>Order<span class="token punctuation">{</span></span><br><span class="highlight-line">		ID<span class="token punctuation">:</span>         time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">UnixNano</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		ProductIDs<span class="token punctuation">:</span> productIDs<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	log<span class="token punctuation">.</span><span class="token function">Info</span><span class="token punctuation">(</span><span class="token string">"create order, productIDs: "</span><span class="token punctuation">,</span> productIDs<span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// kita publish atau emit "order.created"</span></span><br><span class="highlight-line">	event<span class="token punctuation">,</span> err <span class="token operator">:=</span> o<span class="token punctuation">.</span>bus<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"order.created"</span><span class="token punctuation">,</span> <span class="token operator">*</span>order<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">return</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">return</span> order</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span></code></pre>
<p>Service yang dibuat selanjutnya adalah <code>payment_service</code>. Pada service ini, terdapat satu method <code>CreatePayment</code>.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> service</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"shop/model"</span></span><br><span class="highlight-line">	<span class="token string">"time"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	paymentService <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		orderService OrderService</span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token function">NewPaymentService</span><span class="token punctuation">(</span>os OrderService<span class="token punctuation">)</span> PaymentService <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> <span class="token operator">&amp;</span>paymentService<span class="token punctuation">{</span></span><br><span class="highlight-line">		orderService<span class="token punctuation">:</span> os<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>ps <span class="token operator">*</span>paymentService<span class="token punctuation">)</span> <span class="token function">CreatePayment</span><span class="token punctuation">(</span>orderID <span class="token builtin">int64</span><span class="token punctuation">)</span> <span class="token operator">*</span>model<span class="token punctuation">.</span>Payment <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">return</span> <span class="token operator">&amp;</span>model<span class="token punctuation">.</span>Payment<span class="token punctuation">{</span></span><br><span class="highlight-line">		ID<span class="token punctuation">:</span>      time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">UnixNano</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><br><span class="highlight-line">		OrderID<span class="token punctuation">:</span> orderID<span class="token punctuation">,</span></span><br><span class="highlight-line">		Status<span class="token punctuation">:</span>  model<span class="token punctuation">.</span>PaymentStatusPending<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Kemudian, kita akan membuat instansiasi pacakge <code>bus</code>. Fungsi constructor ini saya ambil dari contoh yang diberikan di repo <code>github.com/mustafaturan/bus</code>.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> eventbus</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/bus"</span></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/monoton"</span></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/monoton/sequencer"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token function">NewBus</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>bus<span class="token punctuation">.</span>Bus <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token comment">// configure id generator (it doesn't have to be monoton)</span></span><br><span class="highlight-line">	node <span class="token operator">:=</span> <span class="token function">uint64</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	initialTime <span class="token operator">:=</span> <span class="token function">uint64</span><span class="token punctuation">(</span><span class="token number">1577865600000</span><span class="token punctuation">)</span> <span class="token comment">// set 2020-01-01 PST as initial time</span></span><br><span class="highlight-line">	m<span class="token punctuation">,</span> err <span class="token operator">:=</span> monoton<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>sequencer<span class="token punctuation">.</span><span class="token function">NewMillisecond</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> node<span class="token punctuation">,</span> initialTime<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// init an id generator</span></span><br><span class="highlight-line">	<span class="token keyword">var</span> idGenerator bus<span class="token punctuation">.</span>Next <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span>m<span class="token punctuation">)</span><span class="token punctuation">.</span>Next</span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// create a new bus instance</span></span><br><span class="highlight-line">	b<span class="token punctuation">,</span> err <span class="token operator">:=</span> bus<span class="token punctuation">.</span><span class="token function">NewBus</span><span class="token punctuation">(</span>idGenerator<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token keyword">return</span> b</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Oke, selanjutnya kita akan membuat package <code>eventhandler</code>.</p>
<pre><code>├── eventhandler
│   └── handler.go
</code></pre>
<p>Event bus ini memiliki sebuah handler yg berupa fungsi. Handler ini gunanya untuk menerima event-event yang diemit ke dalam event bus. Dari event yang diterima kita dapat mengecek jenis topic-nya.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> eventhandler</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"shop/eventbus"</span></span><br><span class="highlight-line">	<span class="token string">"shop/model"</span></span><br><span class="highlight-line">	<span class="token string">"shop/service"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/bus"</span></span><br><span class="highlight-line">	log <span class="token string">"github.com/sirupsen/logrus"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">type</span> EventHandler <span class="token keyword">struct</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	PaymentService service<span class="token punctuation">.</span>PaymentService</span><br><span class="highlight-line"><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token punctuation">(</span>e <span class="token operator">*</span>EventHandler<span class="token punctuation">)</span> <span class="token function">HandleOrder</span><span class="token punctuation">(</span>event <span class="token operator">*</span>bus<span class="token punctuation">.</span>Event<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">switch</span> event<span class="token punctuation">.</span>Topic <span class="token punctuation">{</span></span><br><span class="highlight-line">	<span class="token keyword">case</span> <span class="token string">"order.created"</span><span class="token punctuation">:</span></span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Infof</span><span class="token punctuation">(</span><span class="token string">"recieved event %v"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>ID<span class="token punctuation">)</span></span><br><span class="highlight-line">		order<span class="token punctuation">,</span> ok <span class="token operator">:=</span> event<span class="token punctuation">.</span>Data<span class="token punctuation">.</span><span class="token punctuation">(</span>model<span class="token punctuation">.</span>Order<span class="token punctuation">)</span></span><br><span class="highlight-line">		<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span></span><br><span class="highlight-line">			<span class="token keyword">return</span></span><br><span class="highlight-line">		<span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">		payment <span class="token operator">:=</span> e<span class="token punctuation">.</span>PaymentService<span class="token punctuation">.</span><span class="token function">CreatePayment</span><span class="token punctuation">(</span>order<span class="token punctuation">.</span>ID<span class="token punctuation">)</span></span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Info</span><span class="token punctuation">(</span><span class="token string">"create payment"</span><span class="token punctuation">,</span> payment<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span></span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Sekarang kita akan buat fungsi main, di sini kita akan melakukan wiring service-service yang sudah dibuat.</p>
<pre class="language-go"><code class="language-go"><span class="highlight-line"><span class="token keyword">package</span> main</span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">import</span> <span class="token punctuation">(</span></span><br><span class="highlight-line">	<span class="token string">"os"</span></span><br><span class="highlight-line">	<span class="token string">"os/signal"</span></span><br><span class="highlight-line">	<span class="token string">"syscall"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token string">"shop/eventbus"</span></span><br><span class="highlight-line">	<span class="token string">"shop/eventhandler"</span></span><br><span class="highlight-line">	<span class="token string">"shop/service"</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token string">"github.com/mustafaturan/bus"</span></span><br><span class="highlight-line">	log <span class="token string">"github.com/sirupsen/logrus"</span></span><br><span class="highlight-line"><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">	handler <span class="token operator">:=</span> <span class="token operator">&amp;</span>eventhandler<span class="token punctuation">.</span>EventHandler<span class="token punctuation">{</span><span class="token punctuation">}</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	bbus <span class="token operator">:=</span> eventbus<span class="token punctuation">.</span><span class="token function">NewBus</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	bbus<span class="token punctuation">.</span><span class="token function">RegisterTopics</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">"order.created"</span><span class="token punctuation">}</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	bbus<span class="token punctuation">.</span><span class="token function">RegisterHandler</span><span class="token punctuation">(</span><span class="token string">"order-channel"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>bus<span class="token punctuation">.</span>Handler<span class="token punctuation">{</span></span><br><span class="highlight-line">		Matcher<span class="token punctuation">:</span> <span class="token string">"order.*"</span><span class="token punctuation">,</span> <span class="token comment">// match untuk semua order</span></span><br><span class="highlight-line">		Handle<span class="token punctuation">:</span>  handler<span class="token punctuation">.</span>HandleOrder<span class="token punctuation">,</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	productService <span class="token operator">:=</span> service<span class="token punctuation">.</span><span class="token function">NewProductService</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	orderService <span class="token operator">:=</span> service<span class="token punctuation">.</span><span class="token function">NewOrderService</span><span class="token punctuation">(</span>productService<span class="token punctuation">,</span> bbus<span class="token punctuation">)</span></span><br><span class="highlight-line">	paymentSerivce <span class="token operator">:=</span> service<span class="token punctuation">.</span><span class="token function">NewPaymentService</span><span class="token punctuation">(</span>orderService<span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	handler<span class="token punctuation">.</span>PaymentService <span class="token operator">=</span> paymentSerivce</span><br><span class="highlight-line"></span><br><span class="highlight-line">	products <span class="token operator">:=</span> productService<span class="token punctuation">.</span><span class="token function">List</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	orderService<span class="token punctuation">.</span><span class="token function">CreateOrder</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span><span class="token punctuation">{</span>products<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>ID<span class="token punctuation">}</span><span class="token punctuation">)</span></span><br><span class="highlight-line"></span><br><span class="highlight-line">	<span class="token comment">// kode berikut untuk memblok goroutine utama</span></span><br><span class="highlight-line">	sigCh <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> os<span class="token punctuation">.</span>Signal<span class="token punctuation">)</span></span><br><span class="highlight-line">	done <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	signal<span class="token punctuation">.</span><span class="token function">Notify</span><span class="token punctuation">(</span>sigCh<span class="token punctuation">,</span> os<span class="token punctuation">.</span>Interrupt<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGTERM<span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><br><span class="highlight-line">		<span class="token operator">&lt;-</span>sigCh</span><br><span class="highlight-line">		log<span class="token punctuation">.</span><span class="token function">Info</span><span class="token punctuation">(</span><span class="token string">"exiting..."</span><span class="token punctuation">)</span></span><br><span class="highlight-line">		done <span class="token operator">&lt;-</span> <span class="token boolean">true</span></span><br><span class="highlight-line">	<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><br><span class="highlight-line">	<span class="token operator">&lt;-</span>done</span><br><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre>
<p>Ketika dijalankan maka output dari program akan seperti ini</p>
<pre><code>INFO[0000] create order, productIDs: [1586206522725414000] 
INFO[0000] recieved event 0096Tf1h00000001              
INFO[0000] create payment{id: 1586206522725562000, order_id: 1586206522725417000, status: pending} 
^CINFO[0001] exiting...                                   
</code></pre>
<p><code>0096Tf1h00000001</code> merupakan id dari event yang diemit, dari urutan log yg muncul.</p>
<p>Jadi, begitulah cara kerja dan penggunaan event bus. Mungkin, di artikel selanjutnya akan dibahas implementasi event bus pada sebuah web service.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Background Job Worker</title>
    <link href="https://fahmifan.id/posts/2019/july/background-job-worker/"/>
    <updated>2019-07-09T08:06:42+07:00</updated>
    <id>https://fahmifan.id/posts/2019/july/background-job-worker/</id>
    <content type="html"><![CDATA[
      <p>Dalam pengembangan web, request yang memerlukan process yang lama (long running) dapat memblokir request lain. Kalo seperti ini, maka web kita tidak responsive dan cepat. Process lama ini dapat kita alihkan ke process lain yang berjalan di samping process utama yang disebut worker.</p>
<p>Salah satu pattern umum untuk menggunakan worker adalah ketika ada request ke web servis, maka akan di-reply langsung, lalu akan dijadawlkan task dari request tersebut ke worker. Misalkan kita mendapat requirement sbb:</p>
<blockquote>
<p>Ketika user mengupload gambar, resize terlebih dahulu baru simpan ke storage</p>
</blockquote>
<p>Dari requirement tersebut dapat dibagi menjadi:</p>
<ul>
<li>jalankan worker yang menunggu &quot;tugas&quot; masuk</li>
<li>tunggu user selesai upload</li>
<li>balas dengan status &quot;sedang diproses&quot; ke user dan kode http status 2xx</li>
<li>jadwalkan &quot;tugas&quot; meresize gambar yang diupload ke worker. Bisa dengan memasukkan &quot;tugas&quot; ke dalam process antrian (queue)</li>
<li>worker mengambil tugas dari antrian</li>
<li>worker meresize gambar, lalu simpan ke dalam storage</li>
</ul>
<p>Dengan menggunakan worker aplikasi menjadi lebih cepat dalam memberikan balikan ke user &amp; mengurangi long running request yg menyebabkan bloking.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Domain Driven Design (1)</title>
    <link href="https://fahmifan.id/posts/2019/june/golang-ddd/"/>
    <updated>2019-06-24T08:06:30+07:00</updated>
    <id>https://fahmifan.id/posts/2019/june/golang-ddd/</id>
    <content type="html"><![CDATA[
      <p>Dalam kehidupan, manusia tidak lepas dari pekerjaan. Pekerjaan yang dilakukan pun terkadang berulang dan memiliki pola tersendiri. Ada kalanya bertemu masalah kecepatan dan kapasitas dalam bekerja. Pekerjaan atau proses yang berulang dapat dilakukan otomasi menggunakan software. Selain itu, software dapat digunakan dalam pemecahan masalah.</p>
<p>Dalam membuat software, harus mengerti dulu apa yang dibutuhkan oleh suatu bisnis atau pekerjaan. Untuk dapat membuat software yang tepat guna, diperlukan kolaborasi antara engineer dan stake holder. Kunci dari kolaborasi yang apik adalah komunikasi yang dapat saling dipahami. DDD atau <em>Domain Driven Design</em>, sebuah prinsip pembuatan software dari tahap desain sampai development yang berkolaborasi dengan <em>domain expert</em> (ahli). Tanpa penguasaan yang mendalam tentang suatu permasalahan, maka sulit untuk mengatakan solusi yang dibuat dapat tepat guna. Di sini lah peran seorang domain expert menjadi penting.</p>
<h1>Prinsip DDD</h1>
<h2>Ubiquitous Language</h2>
<p><em>Ubiquitous Language</em>, bahasa yang dapat dimengerti oleh semua orang. Memadukan antara bahasa teknis dengan jargon-jargon di dunia bisnis. Dapat dikatakan juga, membuat desain software yang dimengerti oleh domain expert, jika perlu sampai ke level abstraksi kodingnya.</p>
<h2>Model Driven Design</h2>
<p>Dari permasalahan yang sudah dipahami, perlu dibuat permodelan yang dapat diimplementasikan oleh developer. Beberapa pondasi dari pembuatan model ini adalah:</p>
<h3>Layered Architecture</h3>
<p>Memisahkan bagian-bagian dalam software sesuai dengan peruntukannya. Jika pernah membuat sebuah aplikasi website dinamis, tak jarang berjumpa dengan konsep MVC atau Model View Controller yang merupakan sebuah arsitektur software. Berbeda dengan MVC, Layered Architecture ini lebih kepada mengisolasi kode logik bisnis yang inti dari dependensi luar. Dependensi ini dapat berupa akses ke database, user interface (API), pustaka pihak ketiga, dsb. Bagian yang diisolasi ini disebut sebagai layer aplikasi.</p>
<h2>Refactoring berkelanjutan</h2>
<p>Dalam membuat kodingan, sering kali solusi pertama yang dibuat kurang bagus. Baik dari segi efektif nya atau kejelasan maksud kodingan. Untuk itu, refactoring berkelanjutan menjadi hal yang sering dan perlu dilakukan.</p>
<h2>Bounded Context</h2>
<p>Bagian ini belum penulis baca dan pahami dan akan diupdate di kesempatan berikutnya</p>
<h1>Kesimpulan</h1>
<p>Dari tulisan pendek ini, semoga dapat memicu sedikit rasa penasaran pembaca tentang membuat Software yang andal melalui DDD ini. Ini merupakan bagian satu, selanjutnya penulis akan coba praktik langsung pada proses pembuatan sebuah aplikasi.</p>
<p>Thanks for reading</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Bekraf Developer Conference</title>
    <link href="https://fahmifan.id/posts/2018/desember/bekraf-developer-conference/"/>
    <updated>2018-12-04T08:46:23+07:00</updated>
    <id>https://fahmifan.id/posts/2018/desember/bekraf-developer-conference/</id>
    <content type="html"><![CDATA[
      <!-- 
Setelah membaca artikel berikut, kamu akan mendapatkan:
- resume acara BDC track dicoding
- apa yg penulis dapatkan
- apa yg bisa kamu improve
 -->
<p>Setelah lulus dari program Google Developer Kejar (GDK), saya berkesempatan mengikuti Bekraf Developer Conference atau BDC dari Dicoding.</p>
<p>BDC kali ini diadakan kembali di Bandung, tepatnya di The Papandayan Hotel. Pada BDC tahun ini, terdapat dua track yaitu dari track dari Dicoding dan track dari Asosiasi Game Indonesia.</p>
<p>Track yg saya ikuti adalah Dicoding. Ada 4 sesi dalam track ini. Sesi pertama membahas tentang Hegemoni Jurusan IT. Sesi kedua tentang Mencetak Talenta Digital dari Kampus. Sesi ketiga tentang Melahirkan Mutiara Digital dari Komunitas. Sesi keempat tentang Tantangan Membangun Aplikasi.</p>
<h2>Hegemoni Jurusan IT</h2>
<p>Jurusan IT di kampus bukan menjadi satu-satunya tempat belajar menjadi softawre developer, tapi banyak tempat non-formal yg menyediakan pelatihan baik online maupun offline. Bahkan seseorang driver gojek tanpa pendidikan formal bisa menjadi mendapatkan pekerjaan sebagai software developer setelah mengikuti pelatihan.</p>
<p>Selain itu, software developer juga tidak hanya berasal dari jurusan IT, bahkan dari jurusan lain pun selama memiliki kemampuan bisa memiliki pekerjaan sebagai sebagai software developer.</p>
<h2>Mencetak Talenta Digital dari Kampus</h2>
<p>Sesi ini diisi oleh para dosen jurusan IT. Salah satunya adalah Dr. Inggriani Liem mantan dosen di STEI ITB. Beliau menjelaskan tentang bagaimana menjadi seorang Software Developer yang sukses. Yang dapat saya rangkum adalah: Pelajari Computational Thinking, Algoritma-Struktur Data, dan Fungsional &amp; Object Oriented Paradigm.</p>
<p>Selain itu, dosen lain juga menjelaskan kondisi mahasiswa mereka di kampus. Menurut salah satu dosen, mahsiswanya itu kepingin yang instant-instant, contohnya dikasih tugas pingin yang mudah dan cepat jadi. Lalu, dosen yang lain menjelaskan bahwa mahasiswanya itu kurang minat dalam mempelajari kuliahnya, sehingga beliau sering memberikan motivasi.</p>
<p>Pada sesi ini, datang salah satu murid Dr. Inggriani, beliau menanyakan apakah mungkin mempersingkat waktu mempelajari konsep dasar pemrogramana sampai 3 bulan. Menurut Dr. Inggriani, ini bisa dilakukan asal, lingkungannya sudah mendukung untuk computational thinking. Karena, kendala di Indonesia masih ada saja daerah yang belum memanfaatkan penuh teknologi komputer ini.</p>
<h2>Melahirkan Mutiara Digital dari Komunitas</h2>
<p>Di sesi ini, hadir penggiat komunitas dari GDE Android Indonesia, Lead Jakarta JS, Software Engineer LINE sekaligus dosen Binus, dan co-founder Codepolitan. Mereka bercerita bagaimana mereka tumbuh dari komunitas, peranan komunitas dalam memajukan SDM Software Developer di daerah, bagaimana komunitas bisa membantu LINE dalam mengenalkan fitur API LINE ke developer di Indonesia.</p>
<p><em>WIP ...</em></p>
<h2>Tantangan Membangun Aplikasi</h2>
<p><em>WIP ...</em></p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Download Youtube Mp3 File Using `youtube-dl`</title>
    <link href="https://fahmifan.id/posts/2018/september/download-youtube-mp3/"/>
    <updated>2018-09-15T16:45:48+07:00</updated>
    <id>https://fahmifan.id/posts/2018/september/download-youtube-mp3/</id>
    <content type="html"><![CDATA[
      <p>This is the command to download it</p>
<pre class="language-bash"><code class="language-bash"><span class="highlight-line">youtube-dl -i --extract-audio --audio-format mp3 --audio-quality <span class="token number">0</span> <span class="token operator">&lt;</span>url<span class="token operator">></span></span></code></pre>
<p>if you using <code>zsh</code> or <code>fish</code> wrap the url using quotes <code>'url'</code></p>
<p>Happy downloading</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Adb Meetup 4</title>
    <link href="https://fahmifan.id/posts/2018/juli/05-adb-meetup-4/"/>
    <updated>2018-07-26T05:47:03+07:00</updated>
    <id>https://fahmifan.id/posts/2018/juli/05-adb-meetup-4/</id>
    <content type="html"><![CDATA[
      <p>So last night i attend my first Android Developer Meetup in Bandung from ADB that held in Dicoding Space. The topics are about &quot;A/B Testing Using Firebase Remote Config&quot; &amp; &quot;Make a Android Starterkit using Yeoman Generator&quot;.</p>
<h2>A/B Testing Using Firebase Remote Config</h2>
<p>In this first talk they told us what is A/B testing, how to do it, and the technical part on do A/B testing using the Firebase Remote Config.</p>
<h3>What is A/B Testing</h3>
<p>A/B Testing is used when you want to know what design that works for your users.  It can be different design of button, checkout page, color scheme, fonts, ect.</p>
<h3>How to do A/B Testing</h3>
<p>First, you need to set your goal. What do you want to get from this testing.</p>
<p>Let's say you have an online news/magzine. Your users can read a part of your article, but to read the full article they need to <code>sign in/up</code>. So you want to increase the <code>sign in/up</code> rates from this.</p>
<p>Now you make a hypothesis, the user will sign in if i make the button in capsule instead of rectangle shape.</p>
<p>Then you make two version of it and send the new version you want to test to your sample users.</p>
<p>Then after you collect the data about your test. You can decide now, if the change on the button affect the <code>sign in/up</code> rates to your app.</p>
<h3><em>Comming soon:</em></h3>
<ul>
<li><em>A/B Testing using Firebase Remote Config</em></li>
<li><em>Android Starter Kit Genereator using Yeoman</em></li>
</ul>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Tokopedia Devcamp: Online Test</title>
    <link href="https://fahmifan.id/posts/2018/juli/04-tokopedia-devcamp/"/>
    <updated>2018-07-23T16:01:57+07:00</updated>
    <id>https://fahmifan.id/posts/2018/juli/04-tokopedia-devcamp/</id>
    <content type="html"><![CDATA[
      <p>So, today i just did my online test for Tokopedia Devcamp 2018. This is my second time do online test, and it not that bad. Before, i was always feeling that i woludn't survive on algorithmic test type. The reason for this is because when i take algorithm class in my first year, i did not that good. Sometimes i get overwhelmed to solve a pyramid stars.</p>
<blockquote>
<p><em>&quot;At least I've been trying hard&quot;</em></p>
</blockquote>
<p>That was my motivation to prepared for this online test and keep trying to solve excercises. Just <strong>try it</strong> and feel the struggle, but when you solve it you will get that eureka moment. Even if i can't solve it, <em>at least i've been trying hard</em>.
I hope this test get a good  result, and i can go for interview.</p>
<p>If you want to try or learn algorithm/competitive programming try these</p>
<ul>
<li><a href="http://hackerrank.com/">Hackerrank</a></li>
<li><a href="https://codility.com/programmers/lessons/">Codility</a></li>
</ul>
<p>I used codility to excercise since the online test use codility.</p>
<p>Thank you :D</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>New Project in Android</title>
    <link href="https://fahmifan.id/posts/2018/juli/03-learn-material-design/"/>
    <updated>2018-07-19T16:40:15+07:00</updated>
    <id>https://fahmifan.id/posts/2018/juli/03-learn-material-design/</id>
    <content type="html"><![CDATA[
      <p>I have a project with my friends for MTQMN DAQ. It's an android app with a feature kind of to detect your recitation. It's still WIP and i worked on the android development, while my friends work on Machine Learning and as a project manager. This project is challenging, because i am new to android development and trying to make a good decision about architecture and design is not easy. I need to read more about design pattern, RxJava2, and material design. I hope i can make it on time and qualified to the final round :).</p>
<p>I'd like to post my journey of making this apps in future posts. Well, my english is not that good, so i might use Bahasa Indonesia if it's too difficullt for me to explain it in english. Hahaha!</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Move Blog to Hugo</title>
    <link href="https://fahmifan.id/posts/2018/juli/02-move-blog-to-hugo/"/>
    <updated>2018-07-19T03:29:18+07:00</updated>
    <id>https://fahmifan.id/posts/2018/juli/02-move-blog-to-hugo/</id>
    <content type="html"><![CDATA[
      <p>So, i just tried Hugo and it was super easy to build static web. The installation is faster and easier compare to jekyll. The build time is also fast. Will try to explore later.
The deploy is easy, you only need to write some script there is example from Hugo if you using Unix, and then run the script. If you using Github for User , after the script run then it will push into the master branch and finally updated into your github pages.
But i have bad experience using this, when i trying netlify i just don't know how to make it worked, it keep error when try to fetch <code>submodules</code>.  This is the first time i used <code>git submodules</code> and it was like wasting my time. But i just too curious, and end up hours of googling, but in the end i get what i want.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Make resume from html-css-js.md</title>
    <link href="https://fahmifan.id/posts/2018/juli/01-make-resume-from-html-css-js/"/>
    <updated>2018-07-12T03:29:18+07:00</updated>
    <id>https://fahmifan.id/posts/2018/juli/01-make-resume-from-html-css-js/</id>
    <content type="html"><![CDATA[
      <p>this is the command that does the job. Well for now it only ouput properly in image format. I am still looking for solution to output in pdf format. This is using <a href="https://wkhtmltopdf.org/">Wkhtmltopdf</a> :</p>
<pre><code>wkhtmltoimage --images --javascript-delay 5000 http://localhost:5500/ testcv2.png
</code></pre>
<p>I'm using local server for this and code in vscode :D</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>Trying mobile app development</title>
    <link href="https://fahmifan.id/posts/2018/februari/2018-2-28-develope-mobile-app/"/>
    <updated>2018-02-28T03:29:18+07:00</updated>
    <id>https://fahmifan.id/posts/2018/februari/2018-2-28-develope-mobile-app/</id>
    <content type="html"><![CDATA[
      <p>At school we were told to make a mobile app for android. The teacher said we can use Java, because this is for the lecture of OO Programming 2, the OO Programming 1 was about basic Java SE. For this lecture we will develop mobile app alone not in a team.
I proposed to my teacher if i can used React Native for developing later and he said yes. So, i run into React Native page and set up for local dev. After a while the API and structure was a little bit different to ReactJs. I struggled when trying to connect my phone to my laptop using expo app. It failed several times, but i can figured it out after digging into stack overflow &amp; github issues. The hot reload sometimes failed, i haven't found the answer for this one, after all it was quit fun. Maybe i'll follow for more tutorial about developing mobile app in React Native.
After some reasearch i get a suggestion in youtube about Flutter. It's a framework for bulding android &amp; ios app using Dart language. It was inspired by react they said and after tried it building simple app following their guids, it was really enjoyable develop in Flutter.</p>

    ]]></content>
  </entry>
	
  
  <entry>
    <title>One sprint, One App</title>
    <link href="https://fahmifan.id/posts/2018/februari/2018-2-24-food-app/"/>
    <updated>2018-02-12T03:29:18+07:00</updated>
    <id>https://fahmifan.id/posts/2018/februari/2018-2-24-food-app/</id>
    <content type="html"><![CDATA[
      <p>For the last week I do sprint for making a food app. When i go to college, sometimes i have to stay overnight in my friends house. Doing homework make us hungry and when we want to order food we don't have the menus and it was annoying so i want to make a webapp to display a menus of small restaurants there. It build using ReactJs, tachyons, &amp; styled-components for frontend &amp; lumen for backend api. It's still in development but the core feature is done, it left the login and adding reviews for a restaurant features. This is my first project outside the college tasks and i have a lot of trouble and fun. Still progress to finishing all features and then deploy it to the web.</p>

    ]]></content>
  </entry>
	
</feed>
