<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Home on</title><link>http://kaiwern.com/</link><description>Recent content in Home on</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 15 May 2019 00:00:00 +0000</lastBuildDate><atom:link href="http://kaiwern.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Debugging HTTP traffic with tcpdump and tshark</title><link>http://kaiwern.com/posts/2026/03/22/debugging-http-traffic-with-tcpdump-and-tshark/</link><pubDate>Sun, 22 Mar 2026 16:30:27 +0800</pubDate><guid>http://kaiwern.com/posts/2026/03/22/debugging-http-traffic-with-tcpdump-and-tshark/</guid><description>There are times when you need to debug an issue in your HTTP service and realize that your logs don&amp;rsquo;t have enough information. One way to troubleshoot is to capture network traffic and peek into request and response data.
Sounds hard? It isn&amp;rsquo;t. You can do that with tcpdump, then analyze it with Wireshark or its CLI tool, tshark.</description></item><item><title>Run Qwen3.5 locally on your Mac</title><link>http://kaiwern.com/posts/2026/03/01/run-qwen3.5-locally-on-your-mac/</link><pubDate>Sun, 01 Mar 2026 13:16:53 +0800</pubDate><guid>http://kaiwern.com/posts/2026/03/01/run-qwen3.5-locally-on-your-mac/</guid><description>Recently, Qwen3.5 has been one of the hottest models in the community. It&amp;rsquo;s a vision language model that&amp;rsquo;s relatively small and performs well in coding benchmarks. This means I can host it locally on my M-series Mac and use it with opencode.
I didn&amp;rsquo;t find many resources online about setting it up, so here&amp;rsquo;s a short guide.</description></item><item><title>Unblock 0.0.0.0 Connections on macOS via CLI</title><link>http://kaiwern.com/fragments/unblock-0-0-0-0-connections-on-macos-via-cli/</link><pubDate>Fri, 20 Feb 2026 22:12:20 +0800</pubDate><guid>http://kaiwern.com/fragments/unblock-0-0-0-0-connections-on-macos-via-cli/</guid><description>You are running a web server on a remote machine, binding to 0.0.0.0. You tried to access it through tailscale, but it takes forever to load.
This happens because, the first time you bind your server to 0.0.0.0, it is blocked by the MacOS Application Firewall by default.
If you have access to the GUI, there&amp;rsquo;ll be a popup to prompt you to allow the connections.</description></item><item><title>Converting Fujifilm RAW files to JPEG with CLI</title><link>http://kaiwern.com/posts/2026/01/22/converting-fujifilm-raw-files-to-jpeg-with-cli/</link><pubDate>Thu, 22 Jan 2026 20:50:37 +0800</pubDate><guid>http://kaiwern.com/posts/2026/01/22/converting-fujifilm-raw-files-to-jpeg-with-cli/</guid><description>I have been shooting with a Fujifilm camera for a while. There are times where I need to quickly convert my RAW files to JPEG.
In macOS, you can quickly convert RAW file to JPEG through the Right Click -&amp;gt; Quick Actions -&amp;gt; Convert Image.
You can also select all of the RAW files and convert them to JPEG in bulk.</description></item><item><title>CORS issue using Phoenix LiveView to direct upload to Backblaze or Cloudflare R2</title><link>http://kaiwern.com/fragments/cors-issue-for-file-upload-to-backblaze-and-cloudflare-r2-with-phoenix-liveview/</link><pubDate>Sat, 29 Jul 2023 23:41:20 +0800</pubDate><guid>http://kaiwern.com/fragments/cors-issue-for-file-upload-to-backblaze-and-cloudflare-r2-with-phoenix-liveview/</guid><description>Phoenix LiveView has an amazing documentation on implementing direct upload to S3 in the official documentation. It works well when you use AWS S3. However, you might also use it with AWS S3 alternatives like Backblaze and Cloudflare R2 that is S3 API compatible.
When attempting to follow the guide above in the Phoenix LiveView documentation, you&amp;rsquo;ll quickly realize following the steps doesn&amp;rsquo;t end up with a working solution.</description></item><item><title>Some useful psql commands to know</title><link>http://kaiwern.com/fragments/some-useful-psql-commands-to-know/</link><pubDate>Mon, 24 Oct 2022 23:06:38 +0800</pubDate><guid>http://kaiwern.com/fragments/some-useful-psql-commands-to-know/</guid><description>General If there&amp;rsquo;s only one thing you can takeaway, is the below 2 commands.
\?: Show help for backslash commands. \h [name]: Show help on SQL commands. Knowing the frst command, will allow you to quickly find the other commands you&amp;rsquo;ll need. The second command will basically show the documentation of any SQL commands.</description></item><item><title>How can I write more consistently</title><link>http://kaiwern.com/fragments/how-can-i-write-more-consistently/</link><pubDate>Wed, 07 Sep 2022 21:28:28 +0800</pubDate><guid>http://kaiwern.com/fragments/how-can-i-write-more-consistently/</guid><description>Recently, I have not been able to write as productively as I can as before. I have a couple of topics I can write about. It is just hard for me to sit down and write.
Sometimes, when I came across a particular topic that I&amp;rsquo;m excited about, I might end up finish the first draft in a single sitting.</description></item><item><title>Benchmarking HTTP server stuck at 16k requests</title><link>http://kaiwern.com/posts/2022/08/11/benchmarking-http-server-stuck-at-16k-requests/</link><pubDate>Thu, 11 Aug 2022 16:48:23 +0800</pubDate><guid>http://kaiwern.com/posts/2022/08/11/benchmarking-http-server-stuck-at-16k-requests/</guid><description>A couple of weeks ago I was working through the article: Request coalescing in async Rust and faced a weird issue when reaching the benchmark section of the article.
Here&amp;rsquo;s the core code snippet of our HTTP server:
asyncfn run_server()-&amp;gt; Result&amp;lt;(),Box&amp;lt;dynError&amp;gt;&amp;gt;{letaddr: SocketAddr=&amp;#34;0.0.0.0:3779&amp;#34;.parse()?;letlistener=TcpListener::bind(addr).await?;loop{let(stream,addr)=listener.accept().await?;handle_connection(stream,addr).await?;}}In the article, the author managed to have the server perform up to 400k over 10 seconds:</description></item><item><title>About</title><link>http://kaiwern.com/about/</link><pubDate>Fri, 29 Jul 2022 10:37:11 +0800</pubDate><guid>http://kaiwern.com/about/</guid><description>Hi, I am Kai, a Senior Software Engineer at Ditto.
Now Nowadays, I try to maintain a good work life balance.
Abandoned Projects During my time in Recurse Center, I worked on the following projects to learn about system programming:
Writing a simple database in Rust, inspired by Let&amp;rsquo;s Build a Simple Database.</description></item><item><title>Last 6 weeks in the Recurse Center</title><link>http://kaiwern.com/posts/2022/07/29/last-6-weeks-in-the-recurse-center/</link><pubDate>Fri, 29 Jul 2022 08:18:00 +0800</pubDate><guid>http://kaiwern.com/posts/2022/07/29/last-6-weeks-in-the-recurse-center/</guid><description>I first wrote about my first 6 weeks in the Recurse Center (RC) around 2 months ago. In a blink of an eye, I have &amp;ldquo;never graduated&amp;rdquo; from my RC batch.
I closed up my previous post with the things I wanted to achieve on my last 6 weeks in RC.</description></item><item><title>Writing PostgreSQL extension in Rust With pgrx</title><link>http://kaiwern.com/posts/2022/07/20/writing-postgresql-extension-in-rust-with-pgx/</link><pubDate>Wed, 20 Jul 2022 10:07:46 +0800</pubDate><guid>http://kaiwern.com/posts/2022/07/20/writing-postgresql-extension-in-rust-with-pgx/</guid><description>pgx has renamed to pgrx in around April 2023. The following post has also been updated to replace pgx with pgrx instead.
Recently, I came across how to write a PostgreSQL extension in Rust with pgrx from this article by pganalyze. I decided to play around with it. It turns out to be very straightforward to learn and write a PostgreSQL extension!</description></item><item><title>Expose new port in iptables</title><link>http://kaiwern.com/fragments/expose-new-port-in-iptables/</link><pubDate>Sat, 02 Jul 2022 13:50:46 +0800</pubDate><guid>http://kaiwern.com/fragments/expose-new-port-in-iptables/</guid><description>A while ago, I was trying to deploy a ngrok liked reverse proxy I implemented during my time in the Recurse Center to my DigitalOcean droplet.
Since my implementation require listening to different ports for different client, I&amp;rsquo;ll need to expose those ports in my remote server in DigitalOcean. Long story short, it took me a while to figure out that the server is using iptables to block any incoming traffic from other ports.</description></item><item><title>Handy `lsof` options to know</title><link>http://kaiwern.com/posts/2022/06/20/handy-lsof-options-to-know/</link><pubDate>Mon, 20 Jun 2022 16:32:46 +0800</pubDate><guid>http://kaiwern.com/posts/2022/06/20/handy-lsof-options-to-know/</guid><description>When working with lower level network programming, we often want to know the information about our OS network connections. There are a couple of command line that can help us to achieve that like netstat, ss and lsof.
netstat is one of the commonly used command line, available on almost every OS, however, it&amp;rsquo;s really hard to learn it.</description></item><item><title>Implementing tests rerun in `ExUnit.run` in Elixir</title><link>http://kaiwern.com/posts/2022/05/26/implementing-tests-rerun-in-exunit.run-in-elixir/</link><pubDate>Thu, 26 May 2022 17:27:19 +0800</pubDate><guid>http://kaiwern.com/posts/2022/05/26/implementing-tests-rerun-in-exunit.run-in-elixir/</guid><description>TLDR: Read the diff of the PR. It&amp;rsquo;s just 3 files changes, 65 lines of addition and 2 lines of deletion. Half of the addition is probably test.
One of the challenges I faced when I&amp;rsquo;m writing the Livebook for my Writing a simple Redis Protocol parser in Elixir post is to rerun test that has been written.</description></item><item><title>Things I learn while testing files in Rust</title><link>http://kaiwern.com/fragments/things-i-learn-while-testing-files-in-rust/</link><pubDate>Fri, 20 May 2022 21:09:09 +0800</pubDate><guid>http://kaiwern.com/fragments/things-i-learn-while-testing-files-in-rust/</guid><description>Dealing with files while running tests in Rust can be tricky, namely running the tests concurrently and dealing with file clean up when a test fail or panic halfway.
Concurrency By default, cargo test run your Rust tests in multiple threads. Depending on your tests, if you&amp;rsquo;re using the same filename in multiple test cases, it might caused unexpected failures.</description></item><item><title>First 6 weeks in the Recurse Center</title><link>http://kaiwern.com/posts/2022/05/12/first-6-weeks-in-the-recurse-center/</link><pubDate>Thu, 12 May 2022 10:47:06 +0800</pubDate><guid>http://kaiwern.com/posts/2022/05/12/first-6-weeks-in-the-recurse-center/</guid><description>For the past 6 weeks, I have been attending the Recurse Center (RC). The Recurse Center is:
an educational retreat for programmers who want to become dramatically better with a community of peers doing the same.
The journey has been fascinating. Hence, I want to share my experience and challenges in RC so far and plan for my remaining 6 weeks in RC.</description></item><item><title>Logging Thread ID in Rust</title><link>http://kaiwern.com/fragments/logging-thread-id-in-rust/</link><pubDate>Sat, 07 May 2022 15:14:16 +0800</pubDate><guid>http://kaiwern.com/fragments/logging-thread-id-in-rust/</guid><description>Recently, I am working on implementing concurrent operations for B+ Tree index in Rust. Dealing with concurrency bugs can be pain in the ass and and being able to print the thread ID along with by my debug message definitely help me understand the interleaving operations better.
Here&amp;rsquo;s how I learn to do it using env_logger crate and tracing crate.</description></item><item><title>Decomposition</title><link>http://kaiwern.com/fragments/decomposition/</link><pubDate>Wed, 04 May 2022 19:23:13 +0800</pubDate><guid>http://kaiwern.com/fragments/decomposition/</guid><description>Decomposition is the process of breaking down a complex problem into smaller parts. It is also one of the most widely applicable Computer Science (CS) concept in our lives.
If a system you&amp;rsquo;re learning is too complex to understand/implement, break it down into manageable parts. Writing your own programming language is complex, but writing a lexer is probably not.</description></item><item><title>Writing a custom Vim Command</title><link>http://kaiwern.com/posts/2022/04/28/writing-a-custom-vim-command/</link><pubDate>Thu, 28 Apr 2022 14:40:35 +0800</pubDate><guid>http://kaiwern.com/posts/2022/04/28/writing-a-custom-vim-command/</guid><description>Recently I have been implementing B+ Tree on disk in Rust, and require to inspect the data structure a lot while debugging. So a lot of time, I&amp;rsquo;ll be print debugging:
println!(&amp;#34;{:?}&amp;#34;,node);Since B+ Tree operations often involve several phases, I have to do this a lot of time. Depending on which operation I&amp;rsquo;m implementing, I might need to print at different line.</description></item><item><title>Solutions I'm trying to have a productive day</title><link>http://kaiwern.com/fragments/solutions-im-trying-to-have-a-productive-day/</link><pubDate>Wed, 27 Apr 2022 09:55:02 +0800</pubDate><guid>http://kaiwern.com/fragments/solutions-im-trying-to-have-a-productive-day/</guid><description>I&amp;rsquo;m currently attending a 12 weeks retreats in Recurse Center (RC). Since it&amp;rsquo;s self directed and I&amp;rsquo;m constantly working at the edge of my abilities, I do face some challenges during my time here that affect my productivity. Some of the challenges I faced are:
I felt tired/demotivated to do anything after working intensely through a problem.</description></item><item><title>Benchmarking and writing a concurrent mini Redis in Elixir</title><link>http://kaiwern.com/posts/2022/04/05/benchmarking-and-writing-a-concurrent-mini-redis-in-elixir/</link><pubDate>Tue, 05 Apr 2022 20:33:16 +0800</pubDate><guid>http://kaiwern.com/posts/2022/04/05/benchmarking-and-writing-a-concurrent-mini-redis-in-elixir/</guid><description>In our previous post of this series, we wrote a mini Redis integrated with our own RESP parser and a KV store.
In this post, we are going to benchmark it and make changes along the way to make our mini Redis more performant!
This post consists of the following sections:</description></item><item><title>Writing a mini Redis server in Elixir</title><link>http://kaiwern.com/posts/2022/04/04/writing-a-mini-redis-server-in-elixir/</link><pubDate>Mon, 04 Apr 2022 20:32:56 +0800</pubDate><guid>http://kaiwern.com/posts/2022/04/04/writing-a-mini-redis-server-in-elixir/</guid><description>In the previous post, we wrote a simple Redis Protocol specification (RESP) parser. That&amp;rsquo;s just a small part towards to build a mini Redis. Let&amp;rsquo;s continue writing the other parts needed for our mini Redis server.
Here&amp;rsquo;s how the overall architecture looks like:
Redis CLI &amp;lt;-&amp;gt; Redis Server (TCP) &amp;lt;-&amp;gt; RESP Parser ↓ Key Value Store We will use redis-cli as the Redis client and write the following parts:</description></item><item><title>Writing a simple Firefox Extension</title><link>http://kaiwern.com/posts/2022/02/12/writing-a-simple-firefox-extension/</link><pubDate>Sat, 12 Feb 2022 20:30:11 +0800</pubDate><guid>http://kaiwern.com/posts/2022/02/12/writing-a-simple-firefox-extension/</guid><description>Every now and then, I want to build something that I would use. Coming from a web developer background, I&amp;rsquo;m under the impression that I have to build a web application.
One day I have this &amp;ldquo;a ha&amp;rdquo; moment:
Actually most of the time, I can just build a web extension instead of a web application for my needs!</description></item><item><title>Writing a simple Redis Protocol parser in Elixir</title><link>http://kaiwern.com/posts/2022/01/04/writing-a-simple-redis-protocol-parser-in-elixir/</link><pubDate>Tue, 04 Jan 2022 21:01:05 +0800</pubDate><guid>http://kaiwern.com/posts/2022/01/04/writing-a-simple-redis-protocol-parser-in-elixir/</guid><description>Today, we are going to write a parser that parse Redis Protocol in Elixir.
There are tons of supported commands in Redis. Since this is our first attempt on implementing it, we will only be focusing on the GET and SET.
At the end of this post, you should be able to write a simple parser to parse request/response by Redis client/server.</description></item><item><title>2021 in Review</title><link>http://kaiwern.com/posts/2021/12/13/2021-in-review/</link><pubDate>Mon, 13 Dec 2021 21:52:06 +0800</pubDate><guid>http://kaiwern.com/posts/2021/12/13/2021-in-review/</guid><description>I thought 2021 will great as usual for me. Turn out it didn&amp;rsquo;t. Who knows, it haven&amp;rsquo;t really end yet.
Here&amp;rsquo;s how this review will layout:
Achievements Failures Key Takeaways Let&amp;rsquo;s focus on the positive side of things and talk about what I have achieved this year first.</description></item><item><title>What you need to know about PostgreSQL timezone</title><link>http://kaiwern.com/posts/2021/07/20/what-you-need-to-know-about-postgresql-timezone/</link><pubDate>Tue, 20 Jul 2021 20:30:00 +0800</pubDate><guid>http://kaiwern.com/posts/2021/07/20/what-you-need-to-know-about-postgresql-timezone/</guid><description>How many time have you been bitten up by timezone in PostgreSQL?
I&amp;rsquo;m not sure about you but every time I work with timezone, I get f*cked by it. Every single time, I have to reread certain resources and google search again to make sure I am understanding the behavior of it correctly.</description></item><item><title>Debugging with tracing in Elixir with recon_trace</title><link>http://kaiwern.com/posts/2021/06/27/debugging-with-tracing-in-elixir-with-recon_trace/</link><pubDate>Sun, 27 Jun 2021 18:42:02 +0800</pubDate><guid>http://kaiwern.com/posts/2021/06/27/debugging-with-tracing-in-elixir-with-recon_trace/</guid><description>In my previous blog post, Debugging with Tracing in Elixir, I mentioned about using recon_trace from recon to trace your function calls in your live system.
After using recon_trace a few times and always needing to going back to the documentation to figure out how to use it correctly, I decided to write this post to document the common usage I came across.</description></item><item><title>The one simple trick to accomplish your (so many) goals</title><link>http://kaiwern.com/posts/2021/06/15/the-one-simple-trick-to-accomplish-your-so-many-goals/</link><pubDate>Tue, 15 Jun 2021 22:00:00 +0800</pubDate><guid>http://kaiwern.com/posts/2021/06/15/the-one-simple-trick-to-accomplish-your-so-many-goals/</guid><description>Lately, I have been struggling to accomplish anything I set out to do.
I want to do a lot of things. Yet, I accomplished nothing.
Do you have the similar experience and struggling as well?
Let me tell you the single trick I use to get better.
Focus on one thing at a time.</description></item><item><title>Blue Green Deployment with Nginx for Elixir/Phoenix Release</title><link>http://kaiwern.com/posts/2021/05/15/blue-green-deployment-with-nginx-for-elixir-phoenix-release/</link><pubDate>Sat, 15 May 2021 19:30:41 +0800</pubDate><guid>http://kaiwern.com/posts/2021/05/15/blue-green-deployment-with-nginx-for-elixir-phoenix-release/</guid><description>In this post today, I&amp;rsquo;ll share about how I setup blue green deployment for my Phoenix application using nginx running on a single machine. This post is made possible thanks to this article about Custom Blue Green Deployment with Nginx And Gitlab CI.
The core idea to make blue green deployment possible for Elixir releases with nginx is through:</description></item><item><title>Don't Be Too Hard on Yourself</title><link>http://kaiwern.com/posts/2021/03/23/dont-be-too-hard-on-yourself/</link><pubDate>Tue, 23 Mar 2021 22:54:52 +0800</pubDate><guid>http://kaiwern.com/posts/2021/03/23/dont-be-too-hard-on-yourself/</guid><description>Lately, I have been working overtime to meet the expectation I set out to achieve in work.
I achieve majority of the goals I set out at the cost of losing something that is more precious than anything else.
I almost reach the point of burning out. And here&amp;rsquo;s what I do next.</description></item><item><title>2020 in Review</title><link>http://kaiwern.com/posts/2021/01/19/2020-in-review/</link><pubDate>Tue, 19 Jan 2021 22:33:41 +0800</pubDate><guid>http://kaiwern.com/posts/2021/01/19/2020-in-review/</guid><description>This is my first attempt to reflect upon a year of my life, writing it down and publishing it publicly. Hopefully, sometime in the future, this post will remind my future self how I lived through 2020, one of the toughest year of most people life.
Year 2020, has been great for me.</description></item><item><title>Debugging With Tracing in Elixir</title><link>http://kaiwern.com/posts/2020/11/02/debugging-with-tracing-in-elixir/</link><pubDate>Mon, 02 Nov 2020 20:45:48 +0800</pubDate><guid>http://kaiwern.com/posts/2020/11/02/debugging-with-tracing-in-elixir/</guid><description>If you are a video person, and have 24 minutes to spend with, just jump over to this ElixirConf 2020 - Debugging Live Systems on the BEAM talk by Jeffery Utter.
This article is a downgraded version of the video 😂.
I wrote this before the video is published. Then, I came across it and learn a lot more from there.</description></item><item><title>Identify and specify Identity File used by SSH</title><link>http://kaiwern.com/posts/2020/08/20/identify-and-specify-identity-file-used-by-ssh/</link><pubDate>Thu, 20 Aug 2020 21:02:01 +0800</pubDate><guid>http://kaiwern.com/posts/2020/08/20/identify-and-specify-identity-file-used-by-ssh/</guid><description>Recently, I have been looking into improving our access management to our EC2 instances in Naluri and came across EC2 Instance Connect features. While experementing with it, I have learn a thing or two about ssh.
In this post, we are going to cover the following topics:
Which private keys ssh is using?</description></item><item><title>Deploying Elixir/Phoenix Release to Production</title><link>http://kaiwern.com/posts/2020/07/20/deploying-elixir/phoenix-release-to-production/</link><pubDate>Mon, 20 Jul 2020 20:09:01 +0800</pubDate><guid>http://kaiwern.com/posts/2020/07/20/deploying-elixir/phoenix-release-to-production/</guid><description>Updates (12th August 2020): Fix my mistake on using bin/app restart.
Updates (7th October 2020): Include the reason why bin/app restart doesn&amp;rsquo;t work
In my previous post &amp;ldquo;Building Elixir/Phoenix Release With Docker&amp;rdquo;, I wrote about how I build Elixir release with Docker and extract the tarball. Today, I am going to share how I deploy Elixir release to the production server.</description></item><item><title>Building Elixir/Phoenix Release With Docker</title><link>http://kaiwern.com/posts/2020/06/20/building-elixir/phoenix-release-with-docker/</link><pubDate>Sat, 20 Jun 2020 14:17:08 +0800</pubDate><guid>http://kaiwern.com/posts/2020/06/20/building-elixir/phoenix-release-with-docker/</guid><description>This is a short post about how I build my Elixir/Phoenix releases with Docker and extract the tarball that will be deployed to production. In this approach, we are just building the release with Docker. We are not building the image to run our application in a Docker container.
This post assume that you have the basic knowledge of Docker, building Elixir release and using Elixir 1.</description></item><item><title>What you might want to know about GenServer</title><link>http://kaiwern.com/posts/2020/05/21/what-you-might-want-to-know-about-genserver/</link><pubDate>Thu, 21 May 2020 19:21:59 +0800</pubDate><guid>http://kaiwern.com/posts/2020/05/21/what-you-might-want-to-know-about-genserver/</guid><description>I once gave a talk about GenServer in a local Elixir meet up in 2019. To prepare for the talk, I have done a lot of research and readings. With additional experience working with GenServer in a production environment, I have come to realize that there are a lot of caveats when using GenServer.</description></item><item><title>Essential Date Functions for Grouping in PostgreSQL</title><link>http://kaiwern.com/posts/2020/04/14/essential-date-functions-for-grouping-in-postgresql/</link><pubDate>Tue, 14 Apr 2020 18:43:08 +0800</pubDate><guid>http://kaiwern.com/posts/2020/04/14/essential-date-functions-for-grouping-in-postgresql/</guid><description>The past months, I have been working on a feature which deal with grouping records by date and summing up values.
I have learn a couple of date functions in PostgreSQL that are very useful when it comes to grouping records together based on datetime column.
In this post, we will go through a bit of the context of the feature I work on, and we will walk through the process of implementing it.</description></item><item><title>AWS EC2 Disk Space Full</title><link>http://kaiwern.com/posts/2020/03/16/aws-ec2-disk-space-full/</link><pubDate>Mon, 16 Mar 2020 20:59:55 +0800</pubDate><guid>http://kaiwern.com/posts/2020/03/16/aws-ec2-disk-space-full/</guid><description>Updates (4th June, 2020): Adding in another potential causes: logs
The company I am currently working for, uses AWS infrastructure extensively. For instance, we build our Elixir/Phoenix application release on a seperate EC2 instance.
Sometimes, if our engineers are unlucky, their build process will failed because of the lack of disk space in our build server.</description></item><item><title>Ignoring file instead of folder with the same name in .gitignore</title><link>http://kaiwern.com/posts/2020/02/23/ignoring-file-instead-of-folder-with-the-same-name-in-.gitignore/</link><pubDate>Sun, 23 Feb 2020 17:30:54 +0800</pubDate><guid>http://kaiwern.com/posts/2020/02/23/ignoring-file-instead-of-folder-with-the-same-name-in-.gitignore/</guid><description>While migrating this website from Jekyll of Hugo, I faced an issue where my /tags resulting in a 404 Not Found after deployment. It turned out that /tags is ignored by git when I build my site.
I then found out the following line in my ~/.gitignore_global:
tags This is the file that I ignore after start using ctags in vim.</description></item><item><title>Using Tesseract OCR in Elixir/Phoenix</title><link>http://kaiwern.com/posts/2019/06/03/using-tesseract-ocr-in-elixir/phoenix/</link><pubDate>Mon, 03 Jun 2019 18:04:00 +0800</pubDate><guid>http://kaiwern.com/posts/2019/06/03/using-tesseract-ocr-in-elixir/phoenix/</guid><description>Lately, I am exploring the use of OCR in Expendere (my expense tracking application) and came across Tesseract OCR.
At the time of writing this blog post, there is no native binding of Tesseract OCR in Elixir. However, there are two Elixir wrapper available on GitHub:
tesseract-ocr-elixir tesseract-elixir Both wrapper use System.</description></item><item><title>Send temporary file in Phoenix</title><link>http://kaiwern.com/posts/2019/05/28/send-temporary-file-in-phoenix/</link><pubDate>Tue, 28 May 2019 20:59:00 +0800</pubDate><guid>http://kaiwern.com/posts/2019/05/28/send-temporary-file-in-phoenix/</guid><description>TLDR: Use Phoenix.Controller.send_download/3 to send binary as download to your users.
In Phoenix, there are a couple ways of to send file to your users. The most straightforward one is to programmatically create a file and send it to user using Plug.Conn.send_file/5.
For example:
def export(conn, _params) do # Create file filename = &amp;#34;test.</description></item><item><title>How I keep track of tasks for multiple side projects</title><link>http://kaiwern.com/posts/2019/03/31/how-i-keep-track-of-tasks-for-multiple-side-projects/</link><pubDate>Sun, 31 Mar 2019 20:51:00 +0800</pubDate><guid>http://kaiwern.com/posts/2019/03/31/how-i-keep-track-of-tasks-for-multiple-side-projects/</guid><description>If you are like me, having countless side projects and jumping from one to another from time to time, you might also experience ending up losing track of what you should do on each side projects.
Keeping track of tasks in all of your side projects isn&amp;rsquo;t easy without using any project management software.</description></item><item><title>TIL: Indexing `NULL` in Oracle Database</title><link>http://kaiwern.com/posts/2019/02/18/til-indexing-null-in-oracle-database/</link><pubDate>Mon, 18 Feb 2019 21:32:00 +0800</pubDate><guid>http://kaiwern.com/posts/2019/02/18/til-indexing-null-in-oracle-database/</guid><description>Oracle database does not index a row if all the indexed columns are NULL
For instance, let say we have a users table where we index role column to improve the query performance.
SELECT*fromusersWHEREroleISNULLThe index does not work for such query in Oracle database. This is because when Oracle database is inserting the new record of user where the role is NULL, it does not add the created row to the index.</description></item><item><title>Advent of Code 2018: Day 1 Part 2, How I improve my solution by 34x faster</title><link>http://kaiwern.com/posts/2018/12/01/advent-of-code-2018-day-1-part-2-how-i-improve-my-solution-by-34x-faster/</link><pubDate>Sat, 01 Dec 2018 22:10:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/12/01/advent-of-code-2018-day-1-part-2-how-i-improve-my-solution-by-34x-faster/</guid><description>In the previous post, we had briefly discuss about the solution of Part 1. It is fairly straightforward. I thought Part 2 is going to be easy too. But man, I was wrong. It is a bit tricky.
My initial solution takes around 17 seconds to compute the answer. I made it 34x faster by changing the data structure.</description></item><item><title>Advent of Code 2018: Day 1 Part 1</title><link>http://kaiwern.com/posts/2018/12/01/advent-of-code-2018-day-1-part-1/</link><pubDate>Sat, 01 Dec 2018 21:47:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/12/01/advent-of-code-2018-day-1-part-1/</guid><description>Advent of Code (AOC) 2018 has finally arrived. This is the first time I participate in AOC. Last year, when I first heard of AOC, I wanted to participate in it. But due to heavy workload from university, I just give up on doing it.
This year, it&amp;rsquo;s different, I had graduated and working remotely.</description></item><item><title>Using Markdown for Static Pages in Rails</title><link>http://kaiwern.com/posts/2018/11/27/using-markdown-for-static-pages-in-rails/</link><pubDate>Tue, 27 Nov 2018 22:04:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/11/27/using-markdown-for-static-pages-in-rails/</guid><description>Markdown is great for formatting our writing to be publish as HTML. If you&amp;rsquo;re a developer, you probably used Markdown before. README of GitHub repositories are mostly written in Markdown.
While developing web applications, there will be static pages such as about page and FAQ page. Most of the time, we have to write it in HTML, which can be unpleasant.</description></item><item><title>Minimal Elixir Web Application with Plug and Cowboy</title><link>http://kaiwern.com/posts/2018/10/14/minimal-elixir-web-application-with-plug-and-cowboy/</link><pubDate>Sun, 14 Oct 2018 15:32:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/10/14/minimal-elixir-web-application-with-plug-and-cowboy/</guid><description>It is interesting to learn things from scratch. Coming from Ruby background, I was curious what is the equivalent of Sinatra in Elixir. It&amp;rsquo;s called Plug. It is what Phoenix build on top of.
Using Sinatra, we can write a quick and simple web server with the following code:
require &amp;#39;sinatra&amp;#39; require &amp;#39;json&amp;#39; get &amp;#39;/&amp;#39; do content_type :json JSON({message: &amp;#34;Hello World&amp;#34;}) end How can we achive that in Elixir?</description></item><item><title>A note on`application` in mix.exs starting from Elixir 1.4</title><link>http://kaiwern.com/posts/2018/10/03/a-note-onapplication-in-mix.exs-starting-from-elixir-1.4/</link><pubDate>Wed, 03 Oct 2018 21:45:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/10/03/a-note-onapplication-in-mix.exs-starting-from-elixir-1.4/</guid><description>Starting from Elixir 1.4, we don&amp;rsquo;t need to specify our application lists in application. It is automatically inferred from our dependencies. (Check the release notes here)
Do note that it only automatically infer the application lists if the :applications key is empty. If you had already declared your it in your mix.</description></item><item><title>Using AWK to extract generated file from jekyll-compose</title><link>http://kaiwern.com/posts/2018/09/09/using-awk-to-extract-generated-file-from-jekyll-compose/</link><pubDate>Sun, 09 Sep 2018 22:25:00 +0800</pubDate><guid>http://kaiwern.com/posts/2018/09/09/using-awk-to-extract-generated-file-from-jekyll-compose/</guid><description>Recently, I have been using jekyll to make notes. I use jekyll-compose gem to create post using command line. However, the auto open generated file features isn&amp;rsquo;t working in my machine after the setup.
After a few times on manually opening the generated files in vim, I decided to write a quick shell script to solve this issue.</description></item><item><title>A note about using 'fetch' in JS</title><link>http://kaiwern.com/posts/2018/04/11/a-note-about-using-fetch-in-js/</link><pubDate>Wed, 11 Apr 2018 22:43:41 +0800</pubDate><guid>http://kaiwern.com/posts/2018/04/11/a-note-about-using-fetch-in-js/</guid><description>Another story about fixing bug. This story is related to the native web API fetch, which is used to make request.
Backstory After serveral days of having my first production application online, my client inform me that, the application has a bug, again. The button was not working as expected for one of the users.</description></item><item><title>Using Ruby next in map</title><link>http://kaiwern.com/posts/2018/03/28/using-ruby-next-in-map/</link><pubDate>Wed, 28 Mar 2018 22:43:41 +0800</pubDate><guid>http://kaiwern.com/posts/2018/03/28/using-ruby-next-in-map/</guid><description>While I was refactoring the code base of my client application, I came accross a code block, similar to this:
arr = [] data.each do |d| status = d[&amp;#39;status&amp;#39;] next if IGNORED_STATUS.include? status arr &amp;lt;&amp;lt; d[&amp;#39;value&amp;#39;] end I think, &amp;ldquo;Ha, I can replace each with map here.&amp;rdquo;
I go ahead, and make the changes.</description></item><item><title>Ruby fetch</title><link>http://kaiwern.com/posts/2017/11/04/ruby-fetch/</link><pubDate>Sat, 04 Nov 2017 22:43:41 +0800</pubDate><guid>http://kaiwern.com/posts/2017/11/04/ruby-fetch/</guid><description>Today, when I am refactoring a CLI I wrote, I came across a code block where I check whether an index exists in an array (turns out I don&amp;rsquo;t actually need it, I can just access the array and check if the value is nil). I went to search of Ruby Array documentation to see if such method exists.</description></item><item><title>Register in Vim</title><link>http://kaiwern.com/posts/2017/10/24/register-in-vim/</link><pubDate>Tue, 24 Oct 2017 22:05:00 +0800</pubDate><guid>http://kaiwern.com/posts/2017/10/24/register-in-vim/</guid><description>For the past months, I have started to use vim in some occasions. One day, I came across a vim video, &amp;ldquo;Let Vim Do the Typing&amp;rdquo;{:target=&amp;quot;_blank&amp;quot;}, and discover the use of register in vim. Basically, the concept of register in vim is very similar to the register in our computer. It is a temporary memory space for vim to store text.</description></item><item><title>Vue.js: Add component on click</title><link>http://kaiwern.com/posts/2017/10/17/vue.js-add-component-on-click/</link><pubDate>Tue, 17 Oct 2017 23:00:00 +0800</pubDate><guid>http://kaiwern.com/posts/2017/10/17/vue.js-add-component-on-click/</guid><description>I have been working on a project which uses Vue.js for front end. I came across a scenario where we need to allow user to add more entry in their form.
Initial Approach The first thought that come to my mind will be get the div#id of the element and append it dynamically through javascript</description></item><item><title>Ruby .() notation</title><link>http://kaiwern.com/posts/2017/10/15/ruby-.-notation/</link><pubDate>Sun, 15 Oct 2017 18:12:19 +0800</pubDate><guid>http://kaiwern.com/posts/2017/10/15/ruby-.-notation/</guid><description>In Ruby, .() is a syntatic sugar for call method.
class Person def call &amp;#34;Hello World&amp;#34; end end Person.new.() #=&amp;gt; Hello World In this example, we declare a Person class and call method in the class. With this, we can later execute Person.new.() to call the call method.
Note that, we need to initialize the Person object first by calling new, since the call is a instance method.</description></item></channel></rss>