<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Tech on Pavan Yara</title><link>https://pavanyara.com/tags/tech/</link><description>Recent content in Tech on Pavan Yara</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><managingEditor>pavan.yara@gmail.com (Pavan Yara)</managingEditor><webMaster>pavan.yara@gmail.com (Pavan Yara)</webMaster><copyright>Pavan Yara</copyright><lastBuildDate>Wed, 21 Sep 2022 14:11:24 +0530</lastBuildDate><atom:link href="https://pavanyara.com/tags/tech/index.xml" rel="self" type="application/rss+xml"/><item><title>Rules of Debugging</title><link>https://pavanyara.com/blog/rules-of-debugging/</link><pubDate>Wed, 21 Sep 2022 14:11:24 +0530</pubDate><author>pavan.yara@gmail.com (Pavan Yara)</author><guid>https://pavanyara.com/blog/rules-of-debugging/</guid><description>&lt;p&gt;Here is a list of David J.Agan&amp;rsquo;s timeless and universal rules of debugging. As the author notes in the book - &lt;strong&gt;Memorize them. Tape them to your wall. Tape them to all of your walls.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Understand the System&lt;/strong&gt;: Read the manual. Read everything in Depth. Know the Fundamentals. Know the road map. Understand your tools. Look up the details&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Make it Fail&lt;/strong&gt;: Do it Again. Start at the Beginning. Stimulate the Failure. Don&amp;rsquo;t Simulate the Failure. Find the uncontrolled condition that makes it intermittent. Record everything and find the signature of intermittent bugs. Don&amp;rsquo;t trust Statistics too much. Know that &amp;ldquo;that&amp;rdquo; can happen. Never throw away a Debugging tool.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Quit Thinking and Look&lt;/strong&gt;: Get Data First. Don&amp;rsquo;t just do Complicated repairs based on guess game. See the Failure. See the Details. Build Instrumentation in. Add Instrumentation on. Don&amp;rsquo;t be afraid to Dive-in. Watch out for Heisenberg. Guess only to focus the Search.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Divide and Conquer&lt;/strong&gt;: Narrow the Search with successive Approximation. Get the Range. Determine which side of the Bug you are on. Use Easy-to-use test patterns. Start with the Bad. Fix the bugs you know about. Fix the noise first.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Change One Thing at a Time&lt;/strong&gt;: Isolate the key factor. Grab the brass bar with both hands (i.e., understand what&amp;rsquo;s wrong before fixing). Change one test at a time. Compare it with a good one. Determine what you changed since the last time it worked.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Keep an Audit Trail&lt;/strong&gt;: Write down what you did in what order and what happened as a result. Understand that any detail could be the important one. Correlate Events. Understand that audit trails for design are also good for testing. Write it Down!&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Check the Plug&lt;/strong&gt;: Question your assumptions. Start at the Beginning. Test the Tool.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Get a Fresh View&lt;/strong&gt;: Ask for Fresh Insights (aka explaining the problem to a mannequin/dummy). Tap expertise. Listen to the voice of Experience. Know that help is all around you. Don&amp;rsquo;t be Proud. Report symptoms (not theories). Realize that you don&amp;rsquo;t have to be Sure.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;If you don&amp;rsquo;t Fix it, it Ain&amp;rsquo;t Fixed&lt;/strong&gt;: Check that it&amp;rsquo;s actually/really fixed. Check that it&amp;rsquo;s really your fix that fixed it. Know that it never just goes away by itself. Fix the Cause. And, fix the Process.&lt;/li&gt;&#10;&lt;/ol&gt;</description><content:encoded><![CDATA[<p>Here is a list of David J.Agan&rsquo;s timeless and universal rules of debugging. As the author notes in the book - <strong>Memorize them. Tape them to your wall. Tape them to all of your walls.</strong></p>
<ol>
<li><strong>Understand the System</strong>: Read the manual. Read everything in Depth. Know the Fundamentals. Know the road map. Understand your tools. Look up the details</li>
<li><strong>Make it Fail</strong>: Do it Again. Start at the Beginning. Stimulate the Failure. Don&rsquo;t Simulate the Failure. Find the uncontrolled condition that makes it intermittent. Record everything and find the signature of intermittent bugs. Don&rsquo;t trust Statistics too much. Know that &ldquo;that&rdquo; can happen. Never throw away a Debugging tool.</li>
<li><strong>Quit Thinking and Look</strong>: Get Data First. Don&rsquo;t just do Complicated repairs based on guess game. See the Failure. See the Details. Build Instrumentation in. Add Instrumentation on. Don&rsquo;t be afraid to Dive-in. Watch out for Heisenberg. Guess only to focus the Search.</li>
<li><strong>Divide and Conquer</strong>: Narrow the Search with successive Approximation. Get the Range. Determine which side of the Bug you are on. Use Easy-to-use test patterns. Start with the Bad. Fix the bugs you know about. Fix the noise first.</li>
<li><strong>Change One Thing at a Time</strong>: Isolate the key factor. Grab the brass bar with both hands (i.e., understand what&rsquo;s wrong before fixing). Change one test at a time. Compare it with a good one. Determine what you changed since the last time it worked.</li>
<li><strong>Keep an Audit Trail</strong>: Write down what you did in what order and what happened as a result. Understand that any detail could be the important one. Correlate Events. Understand that audit trails for design are also good for testing. Write it Down!</li>
<li><strong>Check the Plug</strong>: Question your assumptions. Start at the Beginning. Test the Tool.</li>
<li><strong>Get a Fresh View</strong>: Ask for Fresh Insights (aka explaining the problem to a mannequin/dummy). Tap expertise. Listen to the voice of Experience. Know that help is all around you. Don&rsquo;t be Proud. Report symptoms (not theories). Realize that you don&rsquo;t have to be Sure.</li>
<li><strong>If you don&rsquo;t Fix it, it Ain&rsquo;t Fixed</strong>: Check that it&rsquo;s actually/really fixed. Check that it&rsquo;s really your fix that fixed it. Know that it never just goes away by itself. Fix the Cause. And, fix the Process.</li>
</ol>
]]></content:encoded></item><item><title>The Tech Stack of a One-Man SaaS</title><link>https://pavanyara.com/blog/tech-stack-one-man-saas/</link><pubDate>Mon, 21 Dec 2020 23:21:39 +0530</pubDate><author>pavan.yara@gmail.com (Pavan Yara)</author><guid>https://pavanyara.com/blog/tech-stack-one-man-saas/</guid><description>&lt;p&gt;It&amp;rsquo;s amazing how much complexity one person can wrangle.&lt;/p&gt;&#10;&lt;p&gt;In a post - &lt;a href="https://panelbear.com/blog/tech-stack/"&gt;The Tech Stack of a One-Man SaaS&lt;/a&gt;:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;treat infrastructure as cattle instead of pets&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;choose boring technology&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Moved DigitalOcean to Linode because of stability issues. Then moved to AWS due to a good deal.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Migrations were relatively easy because the infrastructure was described via Terraform and Kubernetes manifests.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Stack&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Python/Typescript&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Django/React/NextJS/Celery/Bootstrap 4&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Clickhouse/PostgreSQL/Redis/RDS&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Terraform/Docker/K8s/GitHub Actions&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;AWS/Cloudflare/Let&amp;rsquo;s Encrypt/Namecheap&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Prometheus/Grafana/Sentry/Loki&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Fastmail/Sendgrid&lt;/p&gt;</description><content:encoded><![CDATA[<p>It&rsquo;s amazing how much complexity one person can wrangle.</p>
<p>In a post - <a href="https://panelbear.com/blog/tech-stack/">The Tech Stack of a One-Man SaaS</a>:</p>
<ul>
<li>
<p>treat infrastructure as cattle instead of pets</p>
</li>
<li>
<p>choose boring technology</p>
</li>
<li>
<p>Moved DigitalOcean to Linode because of stability issues. Then moved to AWS due to a good deal.</p>
</li>
<li>
<p>Migrations were relatively easy because the infrastructure was described via Terraform and Kubernetes manifests.</p>
</li>
<li>
<p>Stack</p>
</li>
</ul>
<ul>
<li>
<p>Python/Typescript</p>
</li>
<li>
<p>Django/React/NextJS/Celery/Bootstrap 4</p>
</li>
<li>
<p>Clickhouse/PostgreSQL/Redis/RDS</p>
</li>
<li>
<p>Terraform/Docker/K8s/GitHub Actions</p>
</li>
<li>
<p>AWS/Cloudflare/Let&rsquo;s Encrypt/Namecheap</p>
</li>
<li>
<p>Prometheus/Grafana/Sentry/Loki</p>
</li>
<li>
<p>Fastmail/Sendgrid</p>
</li>
<li>
<p>GitHub/PyCharm/VS Code/Poetry/Yarn/Invoked</p>
</li>
</ul>
<p>A <a href="https://news.ycombinator.com/item?id=25186342">Hackernews discussion</a> shares similar experiences by other successful one-person SaaS founders.</p>
]]></content:encoded></item><item><title>Notes on API Practices</title><link>https://pavanyara.com/blog/api-practices-1/</link><pubDate>Wed, 18 Dec 2019 22:21:54 +0530</pubDate><author>pavan.yara@gmail.com (Pavan Yara)</author><guid>https://pavanyara.com/blog/api-practices-1/</guid><description>&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Technique&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Treat customers with disdain&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Show customers love&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Don&amp;rsquo;t have an API&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Have an API&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Make signups difficult, users must justify their request&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Self-service onboarding&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Exorbitant fees for the privilege of API access&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Enable API access for free or as part of an &amp;ldquo;enterprise-level&amp;rdquo; package&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;4&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;API documentation behind login page or otherwise hidden from search engines&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;API documentation freely accessible and referenced by public search engines&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;5&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Use a proprietary or terrible protocol&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Use an industry-standard protocol such as JSON:API or gRPC (&lt;a href="https://grpc.io"&gt;https://grpc.io&lt;/a&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;6&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Permit only one API key&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Permit multiple API keys for each rotation&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;7&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Tempt fate by maintaining documentation manually&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Keep documentation in sync with code using automated systems such as Swagger or gRPC&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;8&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ignore the infrastructure as code (IaC) revolution&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Make IaC a top priority: Provide officially supported modules for Terraform, Chef, Puppet, Chocolatey, and similar systems&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;9&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Design APIs to be non-idempotent whenever possible&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Design APIs to be idempotent whenever possible&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;via Thomas A. Limoncelli&amp;rsquo;s excellent &lt;a href="https://queue.acm.org/detail.cfm?id=3375635"&gt;ACM queue column on APIs&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description><content:encoded><![CDATA[<table>
	<thead>
			<tr>
					<th>Technique</th>
					<th>Treat customers with disdain</th>
					<th>Show customers love</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>Don&rsquo;t have an API</td>
					<td>Have an API</td>
			</tr>
			<tr>
					<td>2</td>
					<td>Make signups difficult, users must justify their request</td>
					<td>Self-service onboarding</td>
			</tr>
			<tr>
					<td>3</td>
					<td>Exorbitant fees for the privilege of API access</td>
					<td>Enable API access for free or as part of an &ldquo;enterprise-level&rdquo; package</td>
			</tr>
			<tr>
					<td>4</td>
					<td>API documentation behind login page or otherwise hidden from search engines</td>
					<td>API documentation freely accessible and referenced by public search engines</td>
			</tr>
			<tr>
					<td>5</td>
					<td>Use a proprietary or terrible protocol</td>
					<td>Use an industry-standard protocol such as JSON:API or gRPC (<a href="https://grpc.io">https://grpc.io</a>)</td>
			</tr>
			<tr>
					<td>6</td>
					<td>Permit only one API key</td>
					<td>Permit multiple API keys for each rotation</td>
			</tr>
			<tr>
					<td>7</td>
					<td>Tempt fate by maintaining documentation manually</td>
					<td>Keep documentation in sync with code using automated systems such as Swagger or gRPC</td>
			</tr>
			<tr>
					<td>8</td>
					<td>Ignore the infrastructure as code (IaC) revolution</td>
					<td>Make IaC a top priority: Provide officially supported modules for Terraform, Chef, Puppet, Chocolatey, and similar systems</td>
			</tr>
			<tr>
					<td>9</td>
					<td>Design APIs to be non-idempotent whenever possible</td>
					<td>Design APIs to be idempotent whenever possible</td>
			</tr>
	</tbody>
</table>
<ul>
<li>via Thomas A. Limoncelli&rsquo;s excellent <a href="https://queue.acm.org/detail.cfm?id=3375635">ACM queue column on APIs</a></li>
</ul>
]]></content:encoded></item><item><title>Some AWS EC2 Tips</title><link>https://pavanyara.com/blog/ec2-tips-1/</link><pubDate>Wed, 18 Dec 2019 10:37:41 +0530</pubDate><author>pavan.yara@gmail.com (Pavan Yara)</author><guid>https://pavanyara.com/blog/ec2-tips-1/</guid><description>&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Choosing right instance size&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img src="https://pavanyara.com/img/ec2.png" alt="Choosing Right Ec2 instance size"&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Why is my Linux instance not booting after I changed its type to C5 or&#10;M5?&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;See &lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/boot-error-linux-m5-c5/"&gt;https://aws.amazon.com/premiumsupport/knowledge-center/boot-error-linux-m5-c5/&lt;/a&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Make sure enaSupport instance attribute is enabled&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;aws ec2 describe-instances &amp;ndash;instance-ids instance_id &amp;ndash;query &amp;ldquo;Reservations[].Instances[].EnaSupport“&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Make sure both ENA and NVMe modules are installed&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;modinfo ena&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;lsinitrd /boot/initramfs-$(uname -r).img|grep nvme&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Mount EBS volumes using UUID/Label instead of device name&lt;/strong&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;/dev/sda1 -&amp;gt; UUID=&amp;ldquo;ca774df7-756d-4261-a3f1-76038323e572&amp;rdquo;&lt;/p&gt;&#10;&lt;/blockquote&gt;</description><content:encoded><![CDATA[<ul>
<li><strong>Choosing right instance size</strong></li>
</ul>
<p><img src="/img/ec2.png" alt="Choosing Right Ec2 instance size"></p>
<ul>
<li><strong>Why is my Linux instance not booting after I changed its type to C5 or
M5?</strong></li>
</ul>
<p>See <a href="https://aws.amazon.com/premiumsupport/knowledge-center/boot-error-linux-m5-c5/">https://aws.amazon.com/premiumsupport/knowledge-center/boot-error-linux-m5-c5/</a></p>
<ul>
<li><strong>Make sure enaSupport instance attribute is enabled</strong></li>
</ul>
<blockquote>
<p>aws ec2 describe-instances &ndash;instance-ids instance_id &ndash;query &ldquo;Reservations[].Instances[].EnaSupport“</p>
</blockquote>
<ul>
<li><strong>Make sure both ENA and NVMe modules are installed</strong></li>
</ul>
<blockquote>
<p>modinfo ena</p>
</blockquote>
<blockquote>
<p>lsinitrd /boot/initramfs-$(uname -r).img|grep nvme</p>
</blockquote>
<ul>
<li><strong>Mount EBS volumes using UUID/Label instead of device name</strong></li>
</ul>
<blockquote>
<p>/dev/sda1 -&gt; UUID=&ldquo;ca774df7-756d-4261-a3f1-76038323e572&rdquo;</p>
</blockquote>
]]></content:encoded></item></channel></rss>