<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet href="/static/styles/feed.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
   <title></title>
   <link>https://adihegde.com/</link>
   <description>Recent content on </description>
   <language>en-IN</language>
   <webMaster>Aditya Hegde</webMaster>
   <copyright></copyright>
   <lastBuildDate>Tue, 02 Jun 2026 20:24:09 +0000</lastBuildDate>
   <atom:link href="https://adihegde.com/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GoBlr #86 30 May 2026</title>
      <link>https://adihegde.com/til/goblr-86-30-may-2026.html/</link>
      <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/til/goblr-86-30-may-2026.html</guid>
      <description>&lt;h2 id=&#34;go-routine-and-channel-internals&#34;&gt;Go routine and channel internals&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Understanding the Go Runtime: The Bootstrap &lt;a href=&#34;https://internals-for-interns.com/posts/understanding-go-runtime/&#34;&gt;internals-for-interns.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Paper: Communicating Sequential Processes &lt;a href=&#34;https://www.cs.cmu.edu/~crary/819-f09/Hoare78.pdf&#34;&gt;www.cs.cmu.edu&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Scalable Go Scheduler Design Doc by Dmitry (2012) &lt;a href=&#34;https://docs.google.com/document/u/0/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw/mobilebasic#heading=h.mmq8lm48qfcw&#34;&gt;docs.google.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go&#39;s Concurrency and Channel Internals &lt;a href=&#34;https://blog.bullgare.com/2022/12/gos-concurrency-and-channel-internals/&#34;&gt;blog.bullgare.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Scheduling In Go : Part I - OS Scheduler &lt;a href=&#34;https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html&#34;&gt;www.ardanlabs.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go Scheduler &lt;a href=&#34;https://nghiant3223.github.io/2025/04/15/go-scheduler.html&#34;&gt;nghiant3223.github.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Memory Allocation in Go &lt;a href=&#34;https://nghiant3223.github.io/2025/06/03/memory_allocation_in_go.html&#34;&gt;nghiant3223.github.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Goroutine Scheduler, go-profile notes &lt;a href=&#34;https://datadoghq.dev/go-profiler-notes/mental-model-for-go/goroutine-scheduler.html&#34;&gt;datadoghq.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go Network Programming: How Epoll Powers Performance &lt;a href=&#34;https://binarymusings.org/posts/golang/golang_epoll/&#34;&gt;binarymusings.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Scaling Go to 192 cores for Heavy IO &lt;a href=&#34;https://jazco.dev/2024/01/10/golang-and-epoll/&#34;&gt;jazco.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;GOMAXPROCS, epoll/kqueue, and Scheduler-Level Tuning &lt;a href=&#34;https://goperf.dev/02-networking/a-bit-more-tuning/&#34;&gt;goperf.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;creation of the &lt;code&gt;hchan&lt;/code&gt; struct at channel creation. A heap allocated circular buffer protected by a mutex. &lt;code&gt;sendx&lt;/code&gt; and &lt;code&gt;recvx&lt;/code&gt;. The reference to this &lt;code&gt;hchan&lt;/code&gt; struct is maintained in the goroutine stack&lt;/li&gt;&#xA;&lt;li&gt;We have a &lt;code&gt;sendq&lt;/code&gt; and a &lt;code&gt;recvq&lt;/code&gt; that are doubly linked lists. The data type is a waitq. The buffer points to a circular queue. The each data type in this LL is a sudog type and has an unsafe pointer to an element. This is the memory address of a variable. This also holds g type which is a reference object or the identity of the go routine holding data about waiting, the status of the routine&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Buffered channel&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;our circular queue is the &lt;code&gt;buf&lt;/code&gt; where we write to the circular queue&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;ch &amp;lt;- 3&lt;/code&gt; we push a value into the channel. In the case when its full, we create a &lt;code&gt;sudog&lt;/code&gt; object as we cannot write to the channel buffer. This &lt;code&gt;sudog&lt;/code&gt; object is placed in the &lt;code&gt;sendq&lt;/code&gt; DLL and this is our queue for items that are trying to be written to the buffer.&lt;/li&gt;&#xA;&lt;li&gt;The go routine calls &lt;code&gt;gopark&lt;/code&gt; and the go scheduler changes the state of the go routine to waiting.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;result &amp;lt;- ch&lt;/code&gt; will read from the &lt;code&gt;buf&lt;/code&gt; circular queue.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;ch &amp;lt;- 1&#xA;ch &amp;lt;- 2&#xA;ch &amp;lt;- 3 // this is pushed to sendq&#xA;&#x9;res &amp;lt;- ch // 1&#x9;&#xA;// sendq value of 3 pushed into queue&#xA;&#x9;res &amp;lt;- ch // 2&#xA;&#x9;res &amp;lt;- ch // 3&#xA;&#x9;res &amp;lt;- ch // we now call gopark as there is nothign in the buf. We have a sudog allocated and puhsed into the recvq&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;when a sender now publishes an element into the channel, instead of writing to the &lt;code&gt;buf&lt;/code&gt; we directly do a &lt;code&gt;memcopy()&lt;/code&gt; to the recv. We directly copy to goroutine stack and we do not touch the circular queue &lt;code&gt;buf&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {&#xA;  // snip&#xA;  if c.dataqsiz == 0 {&#xA;    if raceenabled {&#xA;      racesync(c, sg)&#xA;    }&#xA;    if ep != nil {&#xA;      // copy data from sender&#xA;      recvDirect(c.elemtype, sg, ep)&#xA;    }&#xA;    // snip&#xA;  }&#xA;  // snip&#xA;}&#xA;&#xA;func recvDirect(t *_type, sg *sudog, dst unsafe.Pointer) {&#xA;  // dst is on our stack or the heap, src is on another stack.&#xA;  // The channel is locked, so src will not move during this&#xA;  // operation.&#xA;  src := sg.elem.get()&#xA;  typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.Size_)&#xA;  memmove(dst, src, t.Size_)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;strong&gt;Unbuffered channel flow&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;we have direct stack to stack copy. We do not have a circular queue holding elements being sent&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Select statement&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;select {&#xA;  case &amp;lt;-ch1:&#xA;  case &amp;lt;-ch2:&#xA;  default: // default non blocking exit&#xA;}&#xA;&#xA;select { // blocking multi-select&#xA;  case &amp;lt;-ch1:&#xA;  case &amp;lt;-ch2:&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;strong&gt;Patterns&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;actor-styled ownership pattern&lt;/li&gt;&#xA;&lt;li&gt;shared state pattern&lt;/li&gt;&#xA;&lt;li&gt;worker pool pattern for bounded concurrency&lt;/li&gt;&#xA;&lt;li&gt;fan in and out&lt;/li&gt;&#xA;&lt;li&gt;How Go (Golang) Works — A Deep Dive into Runtime Internals &lt;a href=&#34;https://muratdemirci.com.tr/en/go-runtime-internals/&#34;&gt;muratdemirci.com.tr&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go Concurrency Patterns: Context &lt;a href=&#34;https://go.dev/blog/context&#34;&gt;go.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go Concurrency Patterns: Pipelines and cancellation &lt;a href=&#34;https://go.dev/blog/pipelines&#34;&gt;go.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://developer.hashicorp.com/vault&#34;&gt;developer.hashicorp.com&lt;/a&gt; rollback manager for cleanup&lt;/li&gt;&#xA;&lt;li&gt;Leaking goroutines by Karl Seguin &lt;a href=&#34;https://www.openmymind.net/Leaking-Goroutines&#34;&gt;openmymind.net&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Goroutine Leaks - The Forgotten Sender &lt;a href=&#34;https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html&#34;&gt;ardanlabs.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Proposal: Goroutine leak detection via garbage collection &lt;a href=&#34;https://go.googlesource.com/proposal/+/master/design/74609-goroutine-leak-detection-gc.md&#34;&gt;go.googlesource.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;boundary hashicorp architecture&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Controller/Worker Model &lt;a href=&#34;https://www.ibm.com/docs/en/aix/7.2.0?topic=models-controllerworker-model&#34;&gt;www.ibm.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Workers concept in boundary &lt;a href=&#34;https://developer.hashicorp.com/boundary/docs/concepts/workers&#34;&gt;developer.hashicorp.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Control plane vs. data plane &lt;a href=&#34;https://www.ibm.com/think/topics/control-plane-vs-data-plane&#34;&gt;www.ibm.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Different planes (control, data and management plane) in systems &lt;a href=&#34;https://developer.hashicorp.com/well-architected-framework/design-resilient-systems/design-control-data-management-plane&#34;&gt;developer.hashicorp.com&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Having a separate plane for blast radius, network reach, horz scaling, upgrade cadence, multi tenancy of networks&lt;/li&gt;&#xA;&lt;li&gt;Overkill when we have single tenant, stateless apis, when latency to control plane is &lt;em&gt;acceptable&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Designing resilient systems by IBM and Hashicorp &lt;a href=&#34;https://developer.hashicorp.com/well-architected-framework/design-resilient-systems&#34;&gt;developer.hashicorp.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;dbw by hashicorp (https://github.com/hashicorp/go-dbw) as a database wrapper in boundary&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;boundary uses a public key infra (PKI) &lt;a href=&#34;https://www.hashicorp.com/en/blog/what-is-public-key-infrastructure-pki&#34;&gt;www.hashicorp.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Mutual TLS &lt;a href=&#34;https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/&#34;&gt;www.cloudflare.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;What is Mutual Authentication &lt;a href=&#34;https://www.cloudflare.com/learning/access-management/what-is-mutual-authentication/&#34;&gt;www.cloudflare.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;More on Zero Trust security &lt;a href=&#34;https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/&#34;&gt;www.cloudflare.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Atomic pointers in golang &lt;a href=&#34;https://pkg.go.dev/sync/atomic#Pointer&#34;&gt;pkg.go.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Atomic pointer operations and unsafe &lt;a href=&#34;https://groups.google.com/g/golang-dev/c/SBmIen68ys0/m/WGfYQQSO4nAJ?pli=1&#34;&gt;groups.google.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go sync.Map: The Right Tool for the Right Job &lt;a href=&#34;https://victoriametrics.com/blog/go-sync-map/&#34;&gt;victoriametrics.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;io.Copy&lt;/code&gt; in goroutine to prevent blocking &lt;a href=&#34;https://stackoverflow.com/questions/62522276/io-copy-in-goroutine-to-prevent-blocking&#34;&gt;stackoverflow.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Goroutines, Nonblocking I/O, And Memory Usage &lt;a href=&#34;https://eklitzke.org/goroutines-nonblocking-io-and-memory-usage&#34;&gt;eklitzke.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Chapter 8. Goroutines and Channels - Shichao&#39;s Notes &lt;a href=&#34;https://notes.shichao.io/gopl/ch8/&#34;&gt;notes.shichao.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Go I/O Readers, Writers, and Data in Motion &lt;a href=&#34;https://victoriametrics.com/blog/go-io-reader-writer/&#34;&gt;victoriametrics.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;gRPC-Gateway &lt;a href=&#34;https://grpc-ecosystem.github.io/grpc-gateway/&#34;&gt;grpc-ecosystem.github.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Rust Bangalore Meetup 16 May 2026</title>
      <link>https://adihegde.com/til/rust-blr-16-may-2026.html/</link>
      <pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/til/rust-blr-16-may-2026.html</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;Talk on Async Runtimes and async I/O in Linux by &lt;strong&gt;Sanchayan Maity&lt;/strong&gt;. &lt;a href=&#34;https://git.sanchayanmaity.net/sanchayanmaity/presentations/src/branch/master/async-runtimes-may-2026&#34;&gt;Slides&lt;/a&gt; for the talk.&lt;/li&gt;&#xA;&lt;li&gt;Asynchronous I/O programming with &lt;code&gt;io_uring&lt;/code&gt; &lt;a href=&#34;https://unixism.net/loti/&#34;&gt;unixism.net&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Async IO on Linux: select, poll, epoll &lt;a href=&#34;https://jvns.ca/blog/2017/06/03/async-io-on-linux--select--poll--and-epoll/&#34;&gt;jvns.ca&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Notes on epoll and io_uring - OS readiness vs OS completion models &lt;a href=&#34;https://iafisher.com/notes/2025/10/epoll-io-uring&#34;&gt;iafisher.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Notes on io_uring &lt;a href=&#34;https://boats.gitlab.io/blog/post/io-uring/&#34;&gt;boats.gitlab.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Asynchronous IO fundamentals &lt;a href=&#34;https://www.ncameron.org/blog/async-io-fundamentals/&#34;&gt;www.ncameron.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;The Impact of Thread-Per-Core Architecture on Application Tail Latency &lt;a href=&#34;https://penberg.org/papers/tpc-ancs19.pdf&#34;&gt;penberg.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Thread-per core &lt;a href=&#34;https://without.boats/blog/thread-per-core/&#34;&gt;without.boats&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Io Uring &lt;a href=&#34;https://nick-black.com/dankwiki/index.php/Io_uring&#34;&gt;nick-black.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;I/O access and interrupts &lt;a href=&#34;https://linux-kernel-labs.github.io/refs/pull/165/merge/labs/interrupts.html&#34;&gt;linux-kernel-labs.github.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Compio - a thread-per-core async runtime with io_uring &lt;a href=&#34;https://github.com/compio-rs/compio/&#34;&gt;github.com/compio-rs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Compio with executor and dispatcher decoupled that can be swapped &lt;a href=&#34;https://compio.rs/docs/preface&#34;&gt;compio.rs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Scheduling multithreaded computations by work stealing &lt;a href=&#34;https://dl.acm.org/doi/10.1145/324133.324234&#34;&gt;dl.acm.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Completion model makes use of an ownership model. There can be an issue with respect to drop problem on how buffer should be handled when a future is dropped as results will be written back to this buffer. (I&#39; not sure about this, have to research). Complexities wrt in flight future operation cancellations. Dropping future does not stop kernels handling of the memory that it was given ownership to.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;// compio (ownership mode)&#xA;// kernel must have ownership to the buffer that it is writing to&#xA;let buf = [0; 4096];&#xA;// buf is not borrowed&#xA;let (res, buf) = file.read_at(buf, 0).await;&#xA;//        ^^^ buffer returned with data&#xA;&#xA;// tokio (borrowing) model&#xA;file.read(&amp;amp;mut buf).await?; // here buf is borrowed&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Advantages wrt zero-copy optimisations, completion models support batched submission for I/O operations, etc (check slides),&lt;/li&gt;&#xA;&lt;li&gt;Apache Iggy benchmarking &lt;a href=&#34;https://benchmarks.iggy.apache.org/&#34;&gt;benchmarks.iggy.apache.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Apache Iggy: Hyper efficient Message Streaming &lt;a href=&#34;https://github.com/apache/iggy&#34;&gt;github.com/apache&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Platform Engineering Meetup 9 May 2026</title>
      <link>https://adihegde.com/til/platform-eng-9-may-2026.html/</link>
      <pubDate>Sat, 09 May 2026 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/til/platform-eng-9-may-2026.html</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;Guava core lib. concurrent Rate Limiter &lt;a href=&#34;https://guava.dev/releases/19.0/api/docs/index.html?com/google/common/util/concurrent/RateLimiter.html&#34;&gt;guava.dev&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Clockwork: The Backbone of PhonePe’s 2 Billion Daily Jobs &lt;a href=&#34;https://tech.phonepe.com/clockwork-the-backbone-of-phonepes-2-billion-daily-jobs&#34;&gt;tech.phonepe.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Temporal (a scalable and reliable runtime for durable function executions) Docs &lt;a href=&#34;https://docs.temporal.io&#34;&gt;docs.temporal.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Drove - Distributed Container Orchestrator by PhonePe &lt;a href=&#34;https://imgee.s3.amazonaws.com/imgee/97396a27bd0b4d29815d59f6a2bf651b.pdf&#34;&gt;slide deck&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Dover Container Orchestrator docs &lt;a href=&#34;https://phonepe.github.io/drove-orchestrator/index.html&#34;&gt;dover&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Kubernetes Event-driven Autoscaling &lt;a href=&#34;https://keda.sh&#34;&gt;keda.sh&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Oracle &lt;code&gt;ScheduledExecutorService&lt;/code&gt; interface &lt;a href=&#34;https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html&#34;&gt;docs.oracle.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;RabbitMQ docs on Queues &lt;a href=&#34;https://www.rabbitmq.com/docs/queues&#34;&gt;www.rabbitmq.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Bengaluru Systems Meetup 25 April 2026</title>
      <link>https://adihegde.com/til/blrsys-25-apr-2026.html/</link>
      <pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/til/blrsys-25-apr-2026.html</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;Redis/Valkey Replication Internals: The Architecture Behind Zero-Copy Command Propagation by Sourav Singh Rawat &lt;a href=&#34;https://frostzt.com/blog/redis-valkey-replication-internals&#34;&gt;frostzt.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;pgrx&lt;/code&gt; - a framework for developing PostgreSQL extensions in Rust &lt;a href=&#34;https://github.com/pgcentralfoundation/pgrx&#34;&gt;github.com/pgcentralfoundation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Tantivy is a full-text search engine library inspired by Apache Lucene and written in Rust &lt;a href=&#34;https://github.com/quickwit-oss/tantivy&#34;&gt;github.com/quickwit-oss&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;BM25 index&#xA;&lt;ul&gt;&#xA;&lt;li&gt;BM25 article &lt;a href=&#34;https://arpitbhayani.me/blogs/bm25/&#34;&gt;arpitbhayani.me&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;What is BM25? &lt;a href=&#34;https://www.paradedb.com/learn/search-concepts/bm25&#34;&gt;paradedb.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Okapi BM25 &lt;a href=&#34;https://en.wikipedia.org/wiki/Okapi_BM25&#34;&gt;en.wikipedia.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Parade: Simple, Elastic-quality search for Postgres &lt;a href=&#34;https://github.com/paradedb/paradedb&#34;&gt;github.com/paradedb&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Boehm’s curve in life</title>
      <link>https://adihegde.com/posts/inked/2025.html/</link>
      <pubDate>Wed, 31 Dec 2025 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/2025.html</guid>
      <description>&lt;p&gt;This was something I had in mind to write down a year ago, but now that I think of it, that wouldn’t have mattered as I believe that it was this year that has taught me more lessons in life than any other up to this point. It’s really funny how fast life can change and how close things really are.&lt;/p&gt;&#xA;&lt;p&gt;The current position that I am in is fully because of me turning a blind eye to multiple situations, and not having the courage to stand up for myself. And to be transparent, I have never learnt how to give myself respect. For years, I’ve always tried to gain that respect by doing a favour for others, without ever thinking about positioning myself at the same level. Self-respect is something that I’ve lacked which has lead to some poor decisions.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;It is necessary and true that all of the things we say in science, all of the conclusions, are uncertain, because they are only conclusions. They are guesses as to what is going to happen, and you cannot know what will happen, because you have not made the most complete experiments.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Richard Feynman&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Looking at the position I was in about 8-10 months back, I probably would have never expected it to spiral out in the manner it has. If I were to draw out a comparison of the person that I was a year ago, my self esteem, my views on relationships and friendships, my ideal lifestyle, all that seems so different. I always had these idealistic scenarios running in my head for situations to calm myself down and feed into what would be candy to my brain at the cost of hurting others.&lt;/p&gt;&#xA;&lt;h2 id=&#34;you-can-not-have-the-cake-and-eat-it-too&#34;&gt;You can not have the cake and eat it too&lt;/h2&gt;&#xA;&lt;p&gt;I really don’t think I would have been the same person that I’ve tried to grow into today if I sat idle during my summer break. It’s concerning how fast my thoughts back then could take me away to a place that forces me to be someone that isn’t myself. It’s really the people with whom you decide to surround yourself with that mould you into another person, and the people I met over this entire year has taught me one thing - I’ve driven my life to shit with my previous decisions.&lt;/p&gt;&#xA;&lt;p&gt;With these decisions, I’ve hurt a couple of people close to me. I tried standing neutral to arguments thinking that I can be on the “good side” of others and life will get back to what I presumed was stable. It’s never worth it, I made that mistake twice in the same year and I’m still grateful for having a second chance at  realising and admitting to my mistakes. I consciously went ahead with things knowing the possible consequences to it, and went ahead to ensure that I don’t ruin something that I thought I had. While I’ve come to realise them, as a consequence, I’ve lost out on precious time with others.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Listen to others&lt;/strong&gt;, you are probably missing out on a greater perspective of a problem than you might think. If you surround yourself with the right people, they will always be your anchor to reality. If you choose to ignore those people for others in the name of &lt;em&gt;keeping everything in your life in symmetry&lt;/em&gt;, you not only hurt them, you hurt yourself. At one point of the year, all those values that I collected were tossed in a bin to tell myself, “At least someone else is happy”... It’s disrespectful to yourself and the person who gave their time and effort to a problem that isn’t theirs.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Time is never on your side&lt;/strong&gt;. If you trick yourself into thinking it is to keep yourself calm, then you’ve just ruined the chance for something fruitful to happen. It’s weird that I’ve never really realised how limited time is, and everything just seems to fly by. Turning 21 has made me realise...damn I don’t have much time left before I have to settle down in life. It was only 5 years ago that my mother told me as I entered the 11th grade - the next years till you complete your school and college will happen in an instant, and I’ve come to realise now, which feels too late. Holding onto those mistakes without correcting them, shutting yourself down that you will rectify them soon when then noise around you has settled down, you won’t even come to realise the time that you have lost. Seriously, just be straight and apologise. It’s the easiest thing to do, and the best way to get rid of all that stress and guilt that has been collecting up.&lt;/p&gt;&#xA;&lt;p&gt;There are only a couple of people who I can really talk to, being myself, who value honesty and share the same values. These are the people who are your actual friends. Yes, sounds pretty obvious, but when you make the mistake of wearing a mask to please others, you drift apart from these people and hurt them. &lt;strong&gt;Learn to burn bridges&lt;/strong&gt;, sometimes they set you free from a you being a prisoner to your idealistic view of the world. Talk to these people, open up to them, and give them your time as well. Life moves fast, you don’t really know how much more time you have to before you move to a different phase of your life where people have to go in different directions. When you keep yourself surrounded by these type of people, you grow with them and in the right direction. You begin to realise the mistakes that you have made previously and you begin to correct them. &lt;strong&gt;It’s never too late&lt;/strong&gt; to realise them, but sooner the better. Don’t wait for your life to cross paths with others later on to correct your mistake.&lt;/p&gt;&#xA;&lt;h2 id=&#34;lost-a-bit-of-spark&#34;&gt;Lost a bit of spark&lt;/h2&gt;&#xA;&lt;p&gt;Life has been draining. This year has had a lot of personal issues spew up that threw me off guard, consequences of the mistakes I’ve made, assignments and submissions part of my undergrad has almost pushed me off the edge of my sanity. It made me hit the lowest part of my life to come to realise what I’ve done wrong. It’s still embarrassing that my proudest achievements are all back from my first year of my college. The amount of work from college and my lack of interest with the quality of education, made me use it as an excuse for not working and let myself rot into being unproductive. I let this take the better of me and haven’t had anything proud to showcase that I accomplished in my career.&lt;/p&gt;&#xA;&lt;p&gt;Moving into 2026, I need a reset back to when I joined college. With what is essentially my final semester of college, I need to treat it like my first year. I don’t have a job, nothing to back me up with. Make use of that time to learn as much as I can, not aimlessly, but with the same intensions and curiosity that I had back when it all started. It feels cliche to say that, but It’s just a reminder to myself that, I managed to accomplish more with that mindset and I cannot rely on my work from 2 years ago to define my career. While I do have great learnings and outcomes from my internship and several instances during the year, I have not been loyal to myself in learning more and understanding to the depth that I used to try to back then.&lt;/p&gt;&#xA;&lt;h2 id=&#34;things-to-remember&#34;&gt;Things to remember&lt;/h2&gt;&#xA;&lt;p&gt;I’m glad that I’ve come to realise errors in the way I’ve valued my life. Cutting the unnecessary &lt;strong&gt;dead-weights&lt;/strong&gt; out before entering a new year is giving me a cleaner slate to work with. Knowing that I’m surrounded by the right crowd is already a positive step into the unknown next year. Just being more transparent about my mistakes and being more respectful to myself by itself has let my life incrementally move closer back to a better place. I’m no way close to where I should be, but all these experiences has taught me things the hard way.&lt;/p&gt;&#xA;&lt;p&gt;I&#39;ve never actually reflected back on a year, probably doing it now because i&#39;ve come to realise a lot of mistakes i&#39;ve made on my end, and a lot of things that have just bottled up across the year.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Bengaluru Systems 11</title>
      <link>https://adihegde.com/posts/talks/blrsys_250906.html/</link>
      <pubDate>Sat, 06 Sep 2025 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/talks/blrsys_250906.html</guid>
      <description>&lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;&#xA;&lt;p&gt;For those who aren&#39;t aware &lt;a href=&#34;https://hasgeek.com/bengalurusystemsmeetup&#34;&gt;Bengaluru Systems&lt;/a&gt;,&#xA;is a really cool community of systems enthusiasts here in Bengaluru, India.&#xA;The meetups cover insightful talks on distributed systems, databases, compilers,&#xA;and more! It was created back in May 2024 by some amazing folks like&#xA;&lt;a href=&#34;https://nonmonotonic.dev&#34;&gt;Madhav&lt;/a&gt; and &lt;a href=&#34;https://rowjee.com/&#34;&gt;Rowjee&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This edition introduced a lightning talk format where all of us were given the&#xA;opportunity to present what we have been working on or what we found interesting.&lt;/p&gt;&#xA;&lt;p&gt;This event saw several lightning talks including ones given by &lt;a href=&#34;https://navinshrinivas.com&#34;&gt;Navin&lt;/a&gt;&#xA;(who spoke about his Torrent client in Rust) and &lt;a href=&#34;https://anirudhsudhir.com/&#34;&gt;Sudhir&lt;/a&gt; who spoke&#xA;about his findings and research on &lt;a href=&#34;https://abseil.io/about/design/swisstables&#34;&gt;Swiss Tables&lt;/a&gt;,&#xA;which are used by &lt;a href=&#34;https://go.dev/blog/swisstable&#34;&gt;Go 1.24&lt;/a&gt;, &lt;a href=&#34;https://valkey.io/blog/new-hash-table/&#34;&gt;Valkey&lt;/a&gt;,&#xA;and Rust’s port of Google&#39;s Swiss table &lt;a href=&#34;https://github.com/rust-lang/hashbrown&#34;&gt;hashbrown&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-talk-on-quasopostssystemsbee&#34;&gt;My talk on &lt;a href=&#34;posts/systems/bee&#34;&gt;Quaso&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;During the event, I was given the opportunity to present an old project of mine - Quaso&#xA;(a Raft implementation in Rust). During this presentation, I gave a&#xA;basic overview of how Raft leader election works and how new entries to a log&#xA;are replicated across a cluster. The presentation concluded with a short demo on&#xA;leader elections and re-elections, simulating append entries, and a demo with a&#xA;basic Key-Value store.&lt;/p&gt;&#xA;&lt;div class=&#34;video-container&#34;&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34; data-media-max-width=&#34;560&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;After this, we had &lt;a href=&#34;https://twitter.com/nilderef?ref_src=twsrc%5Etfw&#34;&gt;@nilderef&lt;/a&gt; talk about his implementation of Raft in rust + how the raft protocol works in general. We also saw a very cool live demo of leader election and simulated failures, which was a very cool demonstration of fault tolerance in real life. &lt;a href=&#34;https://t.co/RxixiiCXV0&#34;&gt;pic.twitter.com/RxixiiCXV0&lt;/a&gt;&lt;/p&gt;&amp;mdash; Bengaluru Systems (fka Bengaluru Systems Meetup) (@BengaluruSys) &lt;a href=&#34;https://twitter.com/BengaluruSys/status/1968386307375382916?ref_src=twsrc%5Etfw&#34;&gt;September 17, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;I spoke about how my current implementation works, how it can be extended to&#xA;have consensus over any serializable type in Rust. I touched upon my previous&#xA;implementation which made use of Google&#39;s &lt;a href=&#34;https://github.com/google/tarpc&#34;&gt;tarpc&lt;/a&gt;&#xA;crate in Rust, and the issues that came up with it.&lt;/p&gt;&#xA;&lt;p&gt;This was my first individual talk, and my first in a while (the last one being&#xA;my presentation for &lt;a href=&#34;https://github.com/anna-ssg/anna&#34;&gt;anna&lt;/a&gt; at&#xA;&lt;a href=&#34;/posts/talks/gomeet_76.html&#34;&gt;GoLang Bengaluru #76&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;h2 id=&#34;images&#34;&gt;Images&lt;/h2&gt;&#xA;&lt;div class=&#34;image-grid&#34; id=&#34;images&#34;&gt;&#xA;    &lt;img &#xA;        loading=&#34;lazy&#34; &#xA;        alt=&#34;taken by @anirudhsudhir&#34; &#xA;        src=&#34;https://pub-80638b77d65944daaef4025164b79722.r2.dev/blrsys250906/img1.jpg&#34; &#xA;    /&gt;&#xA;    &lt;figcaption&gt;&#xA;    taken by &lt;a href=&#34;https://anirudhsudhir.com/&#34;&gt;@anirudhsudhir&lt;/a&gt;&#xA;    &lt;/figcaption&gt;&#xA;    &lt;img &#xA;        loading=&#34;lazy&#34; &#xA;        alt=&#34;taken by @anirudhrowjee&#34; &#xA;        src=&#34;https://pub-80638b77d65944daaef4025164b79722.r2.dev/blrsys250906/img2.jpg&#34; &#xA;    /&gt;&#xA;    &lt;figcaption&gt;&#xA;    taken by &lt;a href=&#34;https://rowjee.com/&#34;&gt;@anirudhrowjee&lt;/a&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;presentation&#34;&gt;Presentation&lt;/h2&gt;&#xA;&lt;div class=&#34;video-container-1610&#34;&gt;&#xA;    &lt;iframe &#xA;        src=&#34;https://docs.google.com/presentation/d/e/2PACX-1vSIy-xB7m-cwa6W_6BJYGg1EUonjvTBQ8MahpGOfH8vThERCctiauh0nDUwjx7ZdJD1e1QAsCdbaM0P/pubembed?start=false&amp;loop=false&amp;delayms=3000&#34; &#xA;        frameborder=&#34;0&#34; &#xA;        width=&#34;1440&#34; &#xA;        height=&#34;839&#34; &#xA;        allowfullscreen=&#34;true&#34; &#xA;        mozallowfullscreen=&#34;true&#34; &#xA;        webkitallowfullscreen=&#34;true&#34;&#xA;    &gt;&#xA;    &lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;twitter-post&#34;&gt;Twitter Post&lt;/h2&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34; data-conversation=&#34;none&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;After this, we had &lt;a href=&#34;https://twitter.com/nilderef?ref_src=twsrc%5Etfw&#34;&gt;@nilderef&lt;/a&gt; talk about his implementation of Raft in rust + how the raft protocol works in general. We also saw a very cool live demo of leader election and simulated failures, which was a very cool demonstration of fault tolerance in real life. &lt;a href=&#34;https://t.co/RxixiiCXV0&#34;&gt;pic.twitter.com/RxixiiCXV0&lt;/a&gt;&lt;/p&gt;&amp;mdash; Bengaluru Systems (fka Bengaluru Systems Meetup) (@BengaluruSys) &lt;a href=&#34;https://twitter.com/BengaluruSys/status/1968386307375382916?ref_src=twsrc%5Etfw&#34;&gt;September 17, 2025&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;</description>
    </item>
    <item>
      <title>Pes Innovation Lab</title>
      <link>https://adihegde.com/posts/inked/pil25.html/</link>
      <pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/pil25.html</guid>
      <description>&lt;p&gt;Interned at &lt;a href=&#34;https://www.theinnovationlab.in&#34;&gt;PIL&lt;/a&gt; (aka. PES Innovation Lab (prev. Microsoft Innovation Lab (prev. Nokia Innovation Lab))) for 8 weeks during the Summer of 2025. This is a research lab based of in the main PESU Campus. The problem statements we choose to work on are created by seniors and alumni from the lab. My research involved introducing a preemptive task scheduler to MCUs(Microcontroller Units). Our scheduler is built around the Raspberry Pi Pico, which comes with a dual core ARM-Cortex M0+ processor. Our implementation introduces a novel approach in loading compiled programs at runtime via a serial interactive interface which is designed to control the status of the tasks loaded on the board.&lt;/p&gt;&#xA;&lt;p&gt;This project involved several blockers that took weeks to tackle, such as implementing preemptive context switching (which would be the foundation to the entire &amp;quot;&lt;em&gt;operating system&lt;/em&gt;&amp;quot;) proved to be a challenging task. Will be updating more on the implementation when I get the time.&lt;/p&gt;&#xA;&lt;p&gt;These 8 weeks has definitely been an experience to say the least. Learnt several lessons as an outcome of this. This also came up in parallel to my first few weeks as being the part of the core team of &lt;a href=&#34;https://hsp-ec.xyz&#34;&gt;HSP&lt;/a&gt; so managing my time between to things that I am held accountable to, while probably not being my first, has definitely been the bigger challenge for me. This is probably because our results took quite a lot of time compared to the other teams in the lab, which did add to my stress personally, but it was a process I enjoyed.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.adihegde.com/posts/labfrns.JPG&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;figcaption&gt;&#xA;Picture taken with my lab batch and seniors on the last day dinner party :D&#xA;&lt;/figcaption&gt;</description>
    </item>
    <item>
      <title>I purchased a new camera</title>
      <link>https://adihegde.com/posts/inked/sony.html/</link>
      <pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/sony.html</guid>
      <description>&lt;p&gt;Recently purchased my first* camera - Sony α 6700. Theres an asterisk to that first as some of you may be familiar with my unsplash page or the fact that I have been taking pictures for a couple of years. Almost every previous camera that i&#39;ve used was what my mother purchased back when I was a year old. In fact, my widely used Sony Rebel XSi is a year older than me. Hence this makes it my first ever camera.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.adihegde.com/posts/sonya6700.JPG&#34; alt=&#34;&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;Taken on my mom&#39;s Cannon PowerShot SD630, apples retouch tool coming in handy to remove my drivers license from the image!&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;!-- &lt;div class=&#34;cite-block&#34;&gt;&#xA;&lt;p&gt;Taken on my mom&#39;s Cannon PowerShot SD630, apples retouch tool coming in handy to remove my drivers license from the image&lt;/p&gt;&#xA;&lt;/div&gt; --&gt;&#xA;&lt;p&gt;Here are the details of the gear that I currently use&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Camera Body: Sony ILCE-6700 APS-C&lt;/li&gt;&#xA;&lt;li&gt;Lens: Sony E PZ G 18-105 mm F4 G Lens&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.adihegde.com/posts/firstpic.JPG&#34; alt=&#34;&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;First pictures on the SD card are my parents :D&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;div class=&#34;cite-block&#34;&gt;&#xA;&lt;p&gt;This &lt;a href=&#34;/collections/inked.html&#34;&gt;inked&lt;/a&gt; is dated to when I made this purchase. I have however been using the camera for the past 4 months (written on 28th Sep, 2025)&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;So far i&#39;ve taken this camera with me for several trips, one of which was a short summer trip to Pondicherry with my college mates. Besides that i&#39;ve sort of made it a regular thing to carry my camera around. I still find it difficult to take a camera out of my bag and start clicking pictures in the public. This is perhaps only because of how people in my country would perceive using a camera as &amp;quot;professional photography&amp;quot;, and I will save my rant on this for another inked blog.&lt;/p&gt;&#xA;&lt;div class=&#34;cite-block&#34;&gt;&#xA;&lt;p&gt;There are a shit ton of laws that are hidden, or supposed to be &#34;known&#34;. I find these laws on cameras pointless and unfair, just seems like an incorrect opinion on photography in general. You are somehow allowed to take pictures with your phone (modern phones are &lt;b&gt;more&lt;/b&gt; than capable of taking professional grade pictures), but it becomes a problem to use a device which is designed solely for this purpose. Have almost gotten my camera confiscated twice. Once at a metro station and another at a beach. I am very careful with when I make use of the camera and only try taking pictures in an appropriate environment. The same for probably when i make use of my phone.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;I&#39;ve never used a mirrorless camera before. Probably the one downside is loosing out on battery life compared to DSLR. I&#39;ve only had to charge the old Cannon Rebel XSi once during a 10 day Singapore trip (you will probably find an inked blog on this soon, have lots of pictures from here on my &lt;a href=&#34;https://unsplash.com/collections/LLxalVci9vk/sin-24-25&#34;&gt;unsplash&lt;/a&gt; page), with extensive usage. Same cant be said for mirrorless as, well theres no viewfinder (yes there is a viewfinder but it uses a screen, thats the whole point of mirrorless, no mirror).&lt;/p&gt;&#xA;&lt;div class=&#34;image-grid&#34; id=&#34;images&#34;&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/doggo1.JPG&#34; /&gt;&#xA;    &lt;!-- &lt;figcaption&gt;&#xA;        really cute doggo picture&#xA;    &lt;/figcaption&gt; --&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/cloud1.JPG&#34; /&gt;&#xA;    &lt;!-- &lt;figcaption&gt;&#xA;        cloud1.JPG&#xA;    &lt;/figcaption&gt; --&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/learning-colorgrading.JPG&#34; /&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/pondi2.JPG&#34; /&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/pondi3.JPG&#34; /&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/milano-menu.JPG&#34; /&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/cloud2.JPG&#34; /&gt;&#xA;    &lt;!-- &lt;figcaption&gt;&#xA;        cloud2.JPG&#xA;    &lt;/figcaption&gt; --&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/porche.JPG&#34; /&gt;&#xA;    &lt;img loading=&#34;lazy&#34; src=&#34;https://images.adihegde.com/camera/a6700/pondi1.JPG&#34; /&gt;&#xA;    &lt;!-- &lt;figcaption&gt;&#xA;        A picture of the east cost from pondicherry&#xA;    &lt;/figcaption&gt; --&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Another upgrade with the camera is the lens. I&#39;ve never used anything more than a 55mm lens on my older Cannon and i&#39;ve gotta say, 105mm is really handy for a couple of things. Here is me taking pictures of an Air India eXpress plane doing rounds around my sisters place in Bengaluru&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.adihegde.com/posts/plane-zoom.JPG&#34; alt=&#34;&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;Yes theres a bit of digital zoom, but you can see how close you can get to the place in the little left box below!!&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;I&#39;m no expert in these things, I struggle quite a bit in low-light conditions and am yet to truly understand how to color grade my pictures (&lt;a href=&#34;https://www.instagram.com/brendangleberries&#34;&gt;@brendangleberries&lt;/a&gt; instagram page is probably what inspires me/the form of art that I like, but more focused towards photography than cinematography). I love doing this in my free time and trying to find ways that I can improve. Theres something different about the felling of taking pictures on these cameras. I love capturing the moment that I see before my eyes, and keep them forever (always have been known for hoarding memories with myself, my parents love complaining about this). And I hope to share more milestones that i&#39;ve come across here with this little hobby of mine (I&#39;m apparently in the top 25% of contributors in unsplash but thats probably not alot)&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.adihegde.com/posts/almost4L.JPG&#34; alt=&#34;&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;Shameless plug to &lt;a href=&#34;https://unsplash.com/@adihegde&#34;&gt;@adihegde&lt;/a&gt;. Almost 400k views!!!&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Anyways, I have a lot to share, i&#39;ll probably update this inked blog, or make a few more as and when I plan to share more cool pics or things I come across while learning (if I get the time, 3rd year is loaded with too many assignments). Thanks for reading this blog (and please do go like my posts on unsplash :D)&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Studying db hexdumps</title>
      <link>https://adihegde.com/posts/tech/dbdump.html/</link>
      <pubDate>Wed, 16 Apr 2025 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/tech/dbdump.html</guid>
      <description>&lt;p&gt;This post is WIP. Based on my repo &lt;a href=&#34;https://github.com/bwaklog/parsley.py&#34;&gt;parsley.py&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Building systems in rust</title>
      <link>https://adihegde.com/posts/systems/bee.html/</link>
      <pubDate>Sat, 21 Dec 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/systems/bee.html</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;blog updated 21/10/2024&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;a-much-needed-introduction-to-this-blog&#34;&gt;A much needed Introduction to this Blog&lt;/h2&gt;&#xA;&lt;p&gt;As I said, this is work in progress. The stupid reality where I open source my progress and not the repository that I&#39;m working on in shame, definitely working with a &lt;a href=&#34;https://notes.andymatuschak.org/Work_with_the_garage_door_up&#34;&gt;garage door open&lt;/a&gt;. This section is still 🏗️&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-this-project-started-out&#34;&gt;How this project started out&lt;/h2&gt;&#xA;&lt;p&gt;A distributed bit-cask like LS Hash Table KV Store. Or according to my first, definitely not force pushed commit &lt;code&gt;4a141713&lt;/code&gt; on &lt;em&gt;Mon Sep 23 00:31:41 2024 +0530&lt;/em&gt;&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;snowflk is a distributed kv store inspired from bitcask&#39;s implementation of a Log-Structured Hash Table, focusing on replicated storage of persistent data across nodes&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is another shot of me dipping my toes in rust, which was not the initial plan. Go seemed easy, but I wanted to learn something new along the way as well. May not be a &lt;em&gt;log&lt;/em&gt; of progress considering academics and club related work, wanted to try some stuff out :)&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;writing this log right before a test, might be messy&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;sep-23&#34;&gt;SEP 23&lt;/h3&gt;&#xA;&lt;p&gt;Genesis, started of with a go implementation but...want to try rust for no reason, lets see how that goes :P&lt;/p&gt;&#xA;&lt;h3 id=&#34;sep-24&#34;&gt;SEP 24&lt;/h3&gt;&#xA;&lt;p&gt;Making this public, I&#39;m to ashamed of what i have written&lt;/p&gt;&#xA;&lt;h3 id=&#34;sep-30&#34;&gt;SEP 30&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Implemented an abstraction over &lt;a href=&#34;https://docs.rs/yaml-rust2/latest/yaml_rust2/&#34;&gt;yaml_rust2&lt;/a&gt; crate for parsing &lt;code&gt;config.yml&lt;/code&gt; during startups&lt;/li&gt;&#xA;&lt;li&gt;Plans for &lt;a href=&#34;https://msgpack.org/&#34;&gt;messagepack&lt;/a&gt; for persistence of states, i.e. for raft that would include data like &lt;code&gt;current term&lt;/code&gt;, node &lt;code&gt;votedFor&lt;/code&gt; and the &lt;code&gt;log[]&lt;/code&gt; of committed changes&lt;/li&gt;&#xA;&lt;li&gt;Writing tests for raft from scratch will be complicated. Plus, need to decide if I should be just using simple &lt;code&gt;TCPListeners&lt;/code&gt; and &lt;em&gt;move bytes around&lt;/em&gt; or try out &lt;a href=&#34;https://github.com/hyperium/tonic&#34;&gt;Tonic&lt;/a&gt; for gRPC&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;back-at-it-againchanging-everything&#34;&gt;Back at it again...changing everything&lt;/h2&gt;&#xA;&lt;p&gt;With everything basically scrapped, except that one beautiful yaml parser I wrote with the &lt;code&gt;yaml_rust2&lt;/code&gt; and learning a bit more after not finish advent of code once again, I felt it would be a great time to rewrite this for fun during my end semesters...which is still going on as I write this line.&lt;/p&gt;&#xA;&lt;p&gt;So with a lot of undesirable behaviour, and exams this project had to come to a hold. Started the whole thing with a fresh repository and began working on a more generalised raft library. Some small changes included using bincode for serialization instead of message pack showing significantly faster serialization speeds than messagepack.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[tarpc::service]&#xA;trait Server&amp;lt;T&amp;gt; {&#xA;    // ...&#xA;    fn ping_example(&amp;amp;self, req: AppendEntries&amp;lt;T&amp;gt;) -&amp;gt; Response;&#xA;    // ...&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Having a generalized raft library meant serializing bytes and sending generic logs over TCP, which isn&#39;t really that hard. But tarpc didn&#39;t really like doing this as it never really allowed me to write generic traits for a server, which was of course needed. Instead of this, wouldn&#39;t it be easier to just, excuse my words, raw dog the bytes over tcp??&lt;/p&gt;&#xA;&lt;p&gt;If I can write my own &lt;em&gt;rpc like&lt;/em&gt;(definitely not RPC) layer then, I technically have all the flexibility I need to have, couldn&#39;t be that hard considering its all just bytes sent over network, and deserialization works if and only if the types on both the sides are correct. As of now, there is absolutely no type validation on client and server side besides the &lt;code&gt;tokio::task&lt;/code&gt; that has the server running panics out of existence while the task of the application is still running. Of course not desirable but hey, this is still in a toy stage, wont hurt to experiment&lt;/p&gt;&#xA;&lt;p&gt;Just to point out to those who have not seen my other f ups while doing something like this, the last time I tried writing a protocol with pure tcp and marshaled json bytes across a network &lt;a href=&#34;https://hegde.live/posts/systems/inginy12&#34;&gt;did not end very nicely&lt;/a&gt;, in-fact never managed to send bytes across because go never warned me about private fields in a struct don&#39;t get serialized at all, thats really fun to learn about almost a year after a wasted hackathon, but hey you always learn something at the wrong times&lt;/p&gt;&#xA;&lt;p&gt;Why all this, well lets see how elegantly you can now define a naive type in rust and have raft as a consensus layer&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[derive(Debug, Serialize, Deserialize)]&#xA;pub struct Pair&amp;lt;K, V&amp;gt;&#xA;where&#xA;    K: &#39;static + Eq + Hash + Debug + Send + Clone,&#xA;    V: &#39;static + Debug + Send + Clone,&#xA;{&#xA;    pub key: K,&#xA;    pub val: V,&#xA;}&#xA;&#xA;// skipping the necessary implemnetations for Clone,&#xA;// Display, server::log::Entry (which is a necessasry&#xA;// trait of a generic T to be in consensus, more on&#xA;// that later)&#xA;#[derive(Debug)]&#xA;pub struct KVStore&amp;lt;K, V&amp;gt;&#xA;where&#xA;    K: &#39;static + Eq + Hash + Debug + Serialize + DeserializeOwned + Send + Clone,&#xA;    V: &#39;static + Debug + Serialize + DeserializeOwned + Send + Clone,&#xA;{&#xA;    pub map: Mutex&amp;lt;HashMap&amp;lt;K, V&amp;gt;&amp;gt;,&#xA;    pub raft: Raft&amp;lt;Pair&amp;lt;K, V&amp;gt;&amp;gt;,&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Now isnt that neat, atleast to my eyes that has seen a lot worse, now all you need is some async function calls and viola!&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[tokio::main]&#xA;async fn main() {&#xA;    // some config loading&#xA;    let args = Args::parse();&#xA;    let config =&#xA;        parse_config(PathBuf::from(args.conf_path))&#xA;        .expect(&amp;quot;failed to parse config&amp;quot;);&#xA;&#xA;    // A simple KVStore storing keys as strings and values as a string&#xA;    let kv: KVStore&amp;lt;String, String&amp;gt; =&#xA;        KVStore::init_from_conf(&amp;amp;config).await;&#xA;&#xA;    kv.raft.start_raft_server().await;&#xA;    let kv_raft = Arc::new(Mutex::new(kv.raft));&#xA;    let kv_raft_clone = Arc::clone(&amp;amp;kv_raft);&#xA;&#xA;    tokio::spawn(async move {&#xA;        kv_raft_clone.lock().await.tick().await;&#xA;    });&#xA;&#xA;    // our listener for a kv server to listen to clients over&#xA;    // tcp&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Okay now lets get back to what i&#39;ve done to come to this stage. Now how did I define this layer...&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[derive(Debug, Deserialize, Serialize)]&#xA;pub enum RequestPattern&amp;lt;T&amp;gt;&#xA;where&#xA;    T: Entry + Debug + Display + Clone,&#xA;{&#xA;    PingRPC(PingRequest),&#xA;    AppendEntriesRPC(AppendEntriesRequest&amp;lt;T&amp;gt;),&#xA;    RequestVoteRPC(ElectionVoteRequest),&#xA;}&#xA;&#xA;&#xA;pub trait Service&amp;lt;T&amp;gt;&#xA;where&#xA;    T: Entry + Debug + Display + Clone,&#xA;{&#xA;    fn ping_node(&#xA;        node_id: NodeId,&#xA;        state: Arc&amp;lt;Mutex&amp;lt;State&amp;lt;T&amp;gt;&amp;gt;&amp;gt;,&#xA;        req: PingRequest,&#xA;    ) -&amp;gt; impl Future&amp;lt;Output = PingResponse&amp;gt;;&#xA;    fn append_entries(&#xA;        node_id: NodeId,&#xA;        state: Arc&amp;lt;Mutex&amp;lt;State&amp;lt;T&amp;gt;&amp;gt;&amp;gt;,&#xA;        req: AppendEntriesRequest&amp;lt;T&amp;gt;,&#xA;    ) -&amp;gt; impl Future&amp;lt;Output = AppendEntriesResponse&amp;gt;;&#xA;    fn request_vote(&#xA;        node_id: NodeId,&#xA;        state: Arc&amp;lt;Mutex&amp;lt;State&amp;lt;T&amp;gt;&amp;gt;&amp;gt;,&#xA;        req: ElectionVoteRequest,&#xA;    ) -&amp;gt; impl Future&amp;lt;Output = ElectionVoteResponse&amp;gt;;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[derive(Debug, Clone)]&#xA;pub struct Server&amp;lt;T&amp;gt;&#xA;where&#xA;    // why `static, I basicaly enforce that T is always of an owned type,&#xA;    // otherwise the compiler runs in the assumption that T could be of type&#xA;    // &amp;amp;T, &amp;amp;&amp;amp;T, &amp;amp;mut T,... which is obviously never the case&#xA;    T: &#39;static Entry + Debug + Display + Serialize + DeserializeOwned + Clone,&#xA;{&#xA;    // i know this is very redundant, but I did face stupid&#xA;    // issues of my `State&amp;lt;T&amp;gt;` not implementing send across&#xA;    // threads which definitely whent over my head while&#xA;    // trying doing this the first time, so yeah its a bit&#xA;    // messy needs a lot of clean up&#xA;    pub state: Arc&amp;lt;Mutex&amp;lt;State&amp;lt;T&amp;gt;&amp;gt;&amp;gt;,&#xA;    pub node_id: NodeId,&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Now lets have a look of what we can do on the server side for an incoming TCP request&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;if stream.read_buf(&amp;amp;mut buf).is_ok() {&#xA;    let req: RequestPattern&amp;lt;T&amp;gt; = bincode::deserialize(&amp;amp;buf).unwrap();&#xA;&#xA;    match req {&#xA;        RequestPattern::PingRPC(req) =&amp;gt; {&#xA;        &#x9;/* handle resp back here */&#xA;        },&#xA;        RequestPattern::RequestVoteRPC(req) =&amp;gt; {&#xA;        &#x9;/* handle resp back here */&#xA;        },&#xA;        RequestPattern::AppendEntriesRPC(req) =&amp;gt; {&#xA;        &#x9;/* handle resp back here */&#xA;        },&#xA;    }&#xA;} else {&#xA;  warn!(&amp;quot;failed to read stream {:?}&amp;quot;, stream);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;I also went ahead and made some changes on how the raft state is defined, separating its volatile component from the persistent state&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;#[derive(Debug)]&#xA;pub struct State&amp;lt;T: Entry + Debug + Display&amp;gt; {&#xA;    pub persistent_state: PersistentState&amp;lt;T&amp;gt;,&#xA;    pub volatile_state: VolatileState,&#xA;    pub recieved_leader_heartbeat: AtomicBool,&#xA;}&#xA;&#xA;#[derive(Debug)]&#xA;pub struct Raft&amp;lt;T&amp;gt;&#xA;where&#xA;    T: Entry + Debug + Display + Serialize + DeserializeOwned + Clone,&#xA;{&#xA;    pub node_id: NodeId,&#xA;    pub config: Config,&#xA;    pub state: Arc&amp;lt;Mutex&amp;lt;State&amp;lt;T&amp;gt;&amp;gt;&amp;gt;,&#xA;&#xA;    // termination condition for the&#xA;    // server ticker&#xA;    pub stopped: bool,&#xA;&#xA;    // for the &amp;quot;rpc&amp;quot;&#xA;    pub server: Server&amp;lt;T&amp;gt;,&#xA;    pub client: Client,&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;And for anything that I missed out, here is the long commit message that I mostly typed (and definitely have not force pushed to a lot) while I was incredibly sleepy...yeah I&#39;ve gone against all the best practices so far, especially with respect to my commits&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/jycBupX.jpeg&#34; alt=&#34;image of a badly written commit&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;(17/12/24) NOTE: A lot of un deterministic behaviour as it stands. Append Entries only sends empty entries to all nodes, just for the sake of testing for now. The cluster remains stable up till a point, and after that all nodes start fighting over leadership like children. Need to read the TLA spec for raft and the paper carefully. Good progress so far&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;21122024-almost-there&#34;&gt;21/12/2024 Almost There&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;commit 462a4be4&#xA;Author: bwaklog &amp;lt;aditya.mh@outlook.com&amp;gt;&#xA;Date:   Sat Dec 21 02:01:25 2024 +0530&#xA;&#xA;feat: Leader Election&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;So small update, finally finished my exams and have gotten back at this. And looks like we finally have some sort of a leader election working along with replication logs for &lt;em&gt;heart-beats&lt;/em&gt; as I don&#39;t really have a working layer to take in commands from a client...still working on that part and should be up in the next commit&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/w1YVImd.jpeg&#34; alt=&#34;leader election being stable&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Now there isn&#39;t really a proper testing solution for this &lt;em&gt;yet&lt;/em&gt;, but the cluster shows deterministic behaviour. I still believe its not fully up-to the original spec, but that should not take much of a change.&lt;/p&gt;&#xA;&lt;h3 id=&#34;reason-for-the-previous-undefined-behaviour&#34;&gt;Reason for the previous undefined behaviour&lt;/h3&gt;&#xA;&lt;p&gt;The volatile state on server did not hold a separate timer for heartbeats. Each randomised interval for a &lt;code&gt;election_timeout&lt;/code&gt; was from the range $[1, 8]$. The main &lt;code&gt;tick()&lt;/code&gt; method for the raft state kept sleeping for a different randomised time in the range $[1, 8]$, a stupid mistake on my side which made the leader node wait for probably a longer amount of time than what was required.&lt;/p&gt;&#xA;&lt;p&gt;Hence follower nodes that slept for a shorter duration are highly likely to have not recieved a heartbeat from the leader node which force them to move to a candidate state.  $t_{\text{heartbeat}} &amp;lt;&amp;lt; t_{\text{election timeout}}$. I still need to pick a proper ratio to separate out these times which is currently split as $[1, 4)$ for $t_{\text{heartbeat}}$ and $[4, 8]$ for $t_{\text{election timeout}}$ which does cause some issues. The &lt;a href=&#34;https://pdos.csail.mit.edu/6.824/&#34;&gt;MIT 6.5840 Spring 2024&lt;/a&gt; labs do specify a proportion of $1:20 :: t_{\text{heartbeat}}:t_{\text{election timeout}}$, which i haven&#39;t really chosen for the time being. If the max duration for an election timeout were to be $10s$ that would make the max duration for a heartbeat $0.5s$ ish...&lt;/p&gt;&#xA;&lt;br /&gt;&#xA;&lt;p&gt;Now here comes part two of this problem which went over my head. When a &lt;em&gt;server&lt;/em&gt; recieves an &lt;code&gt;AppendEntriesRPC&lt;/code&gt; request, the first condition check is the comparing the &lt;em&gt;node terms&lt;/em&gt;. A server has to reject an append rpc if the request term is lower than the current server term, the condition missing was that it was willing to reject a request regardless of the &lt;code&gt;NodeRole&lt;/code&gt;. So a candidate that goes haywire would keep going to a higher term whilst receiving heartbeats from a Leader in a &lt;em&gt;lower term&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Another minor mistake was not resetting the &lt;code&gt;election_timeout&lt;/code&gt; timer and &lt;code&gt;recieved_heartbeat&lt;/code&gt; boolean value that are a condition for a follower to candidate transition right after voting. Normally you send an empty heartbeat to all followers after receiving a quorum of votes, but as the heartbeats are sent out more frequently and wont give a chance for a server (i.e. a follower) to have its election timer to timeout, no un-necessary transitions will take place. I still feel that i&#39;m overlooking this issue, and it can come and bite me in the back, but it should be a simple fix.&lt;/p&gt;&#xA;&lt;h3 id=&#34;up-next&#34;&gt;Up next&lt;/h3&gt;&#xA;&lt;p&gt;With most of this out of the way, I can start giving some time to working on the KV layer of this project. I want to focus on the internals of databases, so thats a small diversion I don&#39;t want to take for the time being. Besides that, I do need a working client to append to this raft log, so the KV will require some changes.&lt;/p&gt;&#xA;&lt;p&gt;The next challenge lies in defining a proper message delivery system for committed raft entries. How do I deliver an entry to the application once consensus has been reached.&lt;/p&gt;&#xA;&lt;p&gt;The goal of this is to have the consensus layer function as a asynchronous worker thread on a server that acts as a middleman for applying updates to state of an application.&lt;/p&gt;&#xA;&lt;p&gt;When tries to change state of an application, it is first passed onto the consensus layer, so it is the responsibility of the consensus layer to pass this down once it has finished its task of replication as we don&#39;t want the KV to waste time in polling through the log of raft entries and find which of the log entries are &lt;em&gt;freshly&lt;/em&gt; committed and can apply it to the state of its application. Such a system needs to work asynchronously in the background&lt;/p&gt;&#xA;&lt;h2 id=&#34;24122024-130am&#34;&gt;24/12/2024 1:30am&lt;/h2&gt;&#xA;&lt;p&gt;Small update before heading into a Christmas vacation. Partially got log replication to work, no leader commits have been implemented. So what do I mean by partially? I have not fully tested this yet, this is just a very early commit so I don&#39;t loose my progress.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/Cz2mLRO.jpeg&#34; alt=&#34;Partially working log replication&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;You might want to zoom into that image for a better look.&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;In the above image, the third horizontal pane is the only leader in the cluster which has taken set operations in the order &lt;code&gt;set foo baz&lt;/code&gt;, &lt;code&gt;set foo bar&lt;/code&gt;, &lt;code&gt;set apple red&lt;/code&gt;. Do note that there is no current compaction RPC&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;WIP: Insert some hand drawn images here explaining replication&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;The mistake that I made was that I have been following the concept of the base index of being 1 only in some places, because of this mismatch of logic, lots of things went wrong. While basic replication works, I still haven&#39;t tested out replication in leadership changes in a cluster. Ironically have lesser time to work on this during a vacation than my endsems 😵‍💫&lt;/p&gt;&#xA;&lt;p&gt;Whats wrong currently? So a node is able to continue replication even after re-election. But the problem comes when a node disconnects from a cluster. As persistence is somewhat broken at the time being and since a leader expects that all the logs are up to date, a node starting back after a crash will have a completely empty set of logs. What is to be done is, incase if a node rejects an entry, we need to decrease the &lt;code&gt;next_index&lt;/code&gt; on the leaders side and keep retrying until we can successfully replicate the log.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If AppendEntries fails because of log inconsistency: decrement nextIndex and retry (§5.3)&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;24122024-820pm&#34;&gt;24/12/2024 8:20pm&lt;/h2&gt;&#xA;&lt;p&gt;Clocking in just before my break, and finally have some good log replication. Took a few minutes to change all the indices to be logically based off with index 1. Don&#39;t fully like what i&#39;ve written but i&#39;ll focus on optimizing this later.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/NI2gmWB.jpeg&#34; alt=&#34;Log replication with fixed indices&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;Log replication commit &lt;a href=&#34;https://github.com/bwaklog/quaso/commit/ce3fc164f08aee7ce997aee1a66e00de22cb6506&#34;&gt;ce3fc164&lt;/a&gt;&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;In the above image:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Cluster elects node $32$ as the leader for term $1$. Client sends the following commands &lt;code&gt;set foo bar&lt;/code&gt; right before the server is manually stopped and restarted&lt;/li&gt;&#xA;&lt;li&gt;Cluster elects node $64$ as its leader for term $2$. Client sends &lt;code&gt;set bar baz&lt;/code&gt; which is replicated. The server is stopped and restarted&lt;/li&gt;&#xA;&lt;li&gt;Cluster elects $32$ for term 3 after which the client sends &lt;code&gt;set baz foo&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;commit ce3fc164f08aee7ce997aee1a66e00de22cb6506 (HEAD -&amp;gt; main, origin/main)&#xA;Author: bwaklog &amp;lt;aditya.mh@outlook.com&amp;gt;&#xA;Date:   Tue Dec 24 20:27:07 2024 +0530&#xA;&#xA;    feat: Log replication&#xA;&#xA;    Pending&#xA;    - log replication when client has to rewrite over conflicting logs&#xA;    - write leader commit logic&#xA;    - handle a delivery callback to update the underlying state&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;24122024-1107pm&#34;&gt;24/12/2024 11:07pm&lt;/h2&gt;&#xA;&lt;p&gt;Finally can wrap a part of this up. Persistence is working (commit &lt;a href=&#34;https://github.com/bwaklog/quaso/commit/837db316a1b79146bbdce87480eb3e2e05920ea5&#34;&gt;837db316&lt;/a&gt;), so is log replication and leader election. Whats left is leader commits which should not be hard. The tricky part remaining is the deliver function callbacks. Good wrap up before Christmas eve 🎄&lt;/p&gt;&#xA;&lt;p&gt;Here is a small demo i&#39;ve uploaded: &lt;a href=&#34;https://www.youtube.com/embed/yZ80jvBqrOI?si=FifsrEaxUxIVB-1G&#34;&gt;link&lt;/a&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;video-container&#34;&gt;&#xA;    &lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube-nocookie.com/embed/yZ80jvBqrOI?si=gEDy32E4O2iQKinI&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;&lt;!-- &lt;div class=&#34;vide-container&#34;&gt;&#xA;&#x9;&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/yZ80jvBqrOI?si=FifsrEaxUxIVB-1G&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;&#xA;&lt;/div&gt; --&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;04012025&#34;&gt;04/01/2025&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;commit 6a123051e70c2e3c58bc2d30ee8a72b7c2713cd1&#xA;Author: bwaklog &amp;lt;aditya.mh@outlook.com&amp;gt;&#xA;Date:   Sat Jan 4 13:15:35 2025 +0530&#xA;&#xA;    feat(wip): Leader Commits&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Also fixed state persistence where I was initially persisting the entire log length to the disk&lt;/p&gt;&#xA;&lt;h2 id=&#34;08012025&#34;&gt;08/01/2025&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;commit 3b26e5487cabe65290d25630cba5257e0a2ada95&#xA;Author: bwaklog &amp;lt;aditya.mh@outlook.com&amp;gt;&#xA;Date:   Wed Jan 8 21:37:54 2025 +0530&#xA;&#xA;    feat: Message delivery to underlying application&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;This required a bit on how the key value store functions, which needed a change to work with multiple background tasks and also with how the ownership model worked. The solution was basically threads and &lt;code&gt;tokio::select!&lt;/code&gt; is super helpful.&lt;/p&gt;&#xA;&lt;p&gt;What is needed is:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Raft needs to &amp;quot;deliver&amp;quot; messages of a newly committed log to the underlying state&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/mHvYLpj.png&#34; alt=&#34;delivery mechanism&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A separate channel to handle message delivery from incoming clients. This isnt really a decision on how the raft struct is architecture, but does have some influence on how it can be used&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Now on the kv store side, not really optimized but here is a simple switch between a client and raft channel&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;pub async fn generic_handler_interface(&amp;amp;mut self) {&#xA;&#x9;let deliver_rx = Arc::clone(&amp;amp;self.deliver_rx);&#xA;&#x9;let mut deliver_rx = deliver_rx.lock().await;&#xA;&#xA;&#x9;let client_rx = Arc::clone(&amp;amp;self.client_rx);&#xA;&#x9;let mut client_rx = client_rx.lock().await;&#xA;&#xA;&#x9;loop {&#xA;&#x9;&#x9;tokio::select! {&#xA;&#x9;&#x9;&#x9;Some(client_message) = client_rx.recv() =&amp;gt; {&#xA;&#x9;&#x9;&#x9;&#x9;self.handle_client(client_message).await;&#xA;&#x9;&#x9;&#x9;}&#xA;&#x9;&#x9;&#x9;Some(raft_message) = deliver_rx.recv() =&amp;gt; {&#xA;&#x9;&#x9;&#x9;&#x9;self.apply(raft_message).await;&#xA;&#x9;&#x9;&#x9;}&#xA;&#x9;&#x9;}&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping Up&lt;/h2&gt;&#xA;&lt;p&gt;The changes made were now to accommodate the previously mentioned generic handler on the KV store side which selects between a TCP client request or a message delivery via the deliver receiver. The raft state holds the transmitter and keeps pushing down this channel whenever a new log index is committed&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-rust&#34;&gt;if min_match_index &amp;gt; current_commit {&#xA;    for i in current_commit..min_match_index.0 {&#xA;      let deliver_tx = self.deliver_tx.lock().await;&#xA;       let _ = deliver_tx&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;       .send(state.persistent_state.log[i].clone());&#xA;    }&#xA;&#xA;    state.volatile_state.commited_index = min_match_index&#xA;&#x9;&#x9;&#x9;    .clone()&#xA;&#x9;&#x9;&#x9;    .to_owned();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The &lt;code&gt;min_match_index&lt;/code&gt; here refers to the largest log index on all peers/followers till which, all previous log indexes are &lt;em&gt;acknowledged&lt;/em&gt; and ready to be committed. If larger, the state machine delivers &lt;em&gt;via&lt;/em&gt; the channel all the messages from the previous &lt;em&gt;commit index&lt;/em&gt; on the leader up-to the &lt;em&gt;match index&lt;/em&gt;. Once all delivered the commit index shifts updates itself.&lt;/p&gt;&#xA;&lt;p&gt;The same logic goes for a follower receiving &lt;code&gt;AppendEntriesRequest&lt;/code&gt;. The followers must ensure that it discards log entries when its current log length has a mismatch with a verified leaders log length and extend its log by extending its log with the new logs part of the leader request. If the leader’s commit index has shifted ahead of the followers commit index, the follower delivers each leader committed message (which was un delivered on the followers side) to the underlying application.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/bwaklog/quaso/refs/heads/main/resources/docker_cluster.png&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;&lt;strong&gt;QOL&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;To make testing and getting a cluster up easier, all I’ve managed to move the binary to a docker image and run the raft cluster as a network of containers. Another size optimization I’ve learnt as of lately for docker images is having a multistage build bringing the image down to 54MB&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;docker pull bwaklog/quaso:latest&#xA;docker run \&#xA;&#x9;--rm -it \&#xA;&#x9;--network bridge \&#xA;&#x9;--privileged \&#xA;&#x9;bwaklog/quaso:latest&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;script src=&#34;https://asciinema.org/a/AQz82DGPB25kypSBCjw3JT3dG.js&#34; id=&#34;asciicast-AQz82DGPB25kypSBCjw3JT3dG&#34; async=&#34;true&#34;&gt;&lt;/script&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;references&#34;&gt;&lt;em&gt;References&lt;/em&gt;&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Repository: &lt;a href=&#34;https://github.com/bwaklog/quaso&#34;&gt;bwaklog/quaso&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;In Search of an Understandable Consensus Algorithm&#xA;(Extended Version): &lt;a href=&#34;https://raft.github.io/raft.pdf&#34;&gt;paper link&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Phil Eaton’s raft implementation &lt;a href=&#34;https://github.com/eatonphil/raft-rs&#34;&gt;github&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;cite-block&#34;&gt;&#xA;&lt;p&gt;I’d also like to thank &lt;a href=&#34;https://github.com/anirudhrowjee&#34;&gt;@anirudhrowjee&lt;/a&gt; and &lt;a href=&#34;https://github.com/anirudhsudhir&#34;&gt;@anirudhsudhir&lt;/a&gt; who i’ve been in discussions with during this implementation&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Goland Bangalore 76</title>
      <link>https://adihegde.com/posts/talks/gomeet_76.html/</link>
      <pubDate>Sat, 06 Jul 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/talks/gomeet_76.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/anirudhsudhir&#34;&gt;Anirudh&lt;/a&gt;, &lt;a href=&#34;https://www.linkedin.com/in/adhesh-athrey-3a67391b6/&#34;&gt;Adhesh&lt;/a&gt;, &lt;a href=&#34;https://github.com/polarhive&#34;&gt;Nathan&lt;/a&gt; and I recently got the oppourtunity to present our static site generator &lt;a href=&#34;https://anna-docs.netlify.app&#34;&gt;&lt;code&gt;anna&lt;/code&gt;&lt;/a&gt; at the &lt;em&gt;Goland bangalore meetup&lt;/em&gt; &lt;a href=&#34;https://www.meetup.com/golang-bangalore/events/301697429/&#34;&gt;#76&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Lunch with a Pigeon</title>
      <link>https://adihegde.com/posts/inked/pigeon.html/</link>
      <pubDate>Thu, 04 Jul 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/pigeon.html</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;You aren&#39;t allowed to learn who you want aspire to become. Sometimes &amp;quot;experience&amp;quot; is more important even if that means to loose site of yourself&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I&#39;m writing this while sitting all alone in a deserted lab. Where I&#39;m supposed to be interning and simulating some claims made by a paper. And I&#39;m lost. I&#39;ve taken this up only because I missed out on other chances for internships, and I&#39;m afraid I won&#39;t get another shot at them either. And here I am sitting in this lab, and am not able to figure out a single thing. I don&#39;t have a grasp of this depth of knowledge in physics. I don&#39;t have a clue of what I&#39;m doing&lt;/p&gt;&#xA;&lt;p&gt;And now, I&#39;m just in a lab and doing unproductive work. And why, well I&#39;m told its for &amp;quot;experience&amp;quot; to add in that resume. Now I would be eating my own words if this is some internship that I wanted. But it isn&#39;t. I want to learn so many things, and I have just discovered something I&#39;m interested in, but at the same time I&#39;ve missed out on something to fill up in my resume. And out of guilt, I&#39;ve ended up in a lab...a physics lab.&lt;/p&gt;&#xA;&lt;p&gt;It&#39;s probably the &lt;em&gt;100th&lt;/em&gt; time I&#39;ve evaluated what I&#39;m missing out when I sit here. I don&#39;t get to expand my knowledge in the field that concerns me. Instead I&#39;m tied down to a chair and doing something else. While I could have taken my summer at my own pace and covered everything, I&#39;ve lost the luxury of social interaction and doing what I want. And it&#39;s getting frustrating. I&#39;m not getting a benefit for myself, and I feel like I&#39;m letting others down.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Techstack</title>
      <link>https://adihegde.com/posts/tech/dotfiles.html/</link>
      <pubDate>Mon, 10 Jun 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/tech/dotfiles.html</guid>
      <description>&lt;p&gt;I&#39;ve never had my self working on solely the terminal before. It would be only a few occasions when the GUI alternative was simply frustrating to use. I&#39;ve since forced myself to try and venture more, and now I simply can&#39;t work without them. I have even lost count for the number of times i&#39;ve used vim motions accidentally.&lt;/p&gt;&#xA;&lt;p&gt;At first, yes these things were a bit intriguing, but once you leave the learning curve, everything just falls in place. You can find my dotfiles &lt;a href=&#34;https://github.com/bwaklog/dots&#34;&gt;here&lt;/a&gt;&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.imgur.com/miFjoRG.jpg&#34; alt=&#34;My Desk&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h2 id=&#34;text-editor&#34;&gt;Text Editor&lt;/h2&gt;&#xA;&lt;p&gt;This is something that keeps changing once in a while, I like trying new stuff out there. But I always find myself getting back to &lt;a href=&#34;https://neovim.io/&#34;&gt;neovim&lt;/a&gt;. While it took a while to get past that learning curve, I find it quite easy to use, and the motions are something I cant live without.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://zed.dev&#34;&gt;Zed&lt;/a&gt; is another editor I always find myself on. It supports vim motions out of the box, and the editor itself just insanely fast. And can&#39;t go without mentioning the amazing collaboration tool that it offers for free. Been trying emacs recently, and all i&#39;ve experienced is frustration. It just has everything, and is a pain to use at times.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://imgs.xkcd.com/comics/real_programmers.png&#34; alt=&#34;xkcd comic - real programmers&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;xkcd comic 378 - real programmers&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h2 id=&#34;window-manager&#34;&gt;Window Manager&lt;/h2&gt;&#xA;&lt;p&gt;Well first of all I use a Mac. Nothing comes along with it, not even window snapping. So organisation just gets worse as you use it. At first, I got myself to use this app called Rectangle, which provided some neat keybindings to snap windows to a position, but none of it was &lt;em&gt;dynamic&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;While I tried out yabai, which is lightweight and probably the most popular one out there, I just felt lazy to maintain its config. Thats when I discovered Amethyst, which I must say is insanely good. And have been using it for almost 2 complete semesters. There wasn&#39;t any need for setting up a config from scratch and making keybindings with skhd (which I only use to make global hotkeys to open some specific apps) which solves my problem.&lt;/p&gt;&#xA;&lt;h2 id=&#34;terminal-emulator&#34;&gt;Terminal Emulator&lt;/h2&gt;&#xA;&lt;p&gt;When I first started out on Mac, I didnt use anything but the default terminal application, which was restrictive in terms of customisation and basic colour display. iTerm solved most of those solutions for me, but even it couldn&#39;t display those nerd symbols without some weird cuts in the text. The scaling of some of the text and others in neovim weren&#39;t great.&lt;/p&gt;&#xA;&lt;p&gt;Thats when I was introduced to GPU accelerated terminal emulators. &lt;em&gt;Kitty&lt;/em&gt;, &lt;em&gt;Alacritty&lt;/em&gt;, and as of now &lt;em&gt;WezTerm&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Kitty has been great. Probably the most feature rich of the three. However, ever since I&#39;ve messed up the config, I made my way to use wezterm.&lt;/p&gt;&#xA;&lt;p&gt;So far, there hasn&#39;t been any issue, and maintaining the config has been really easy because of Lua. Maintaining my own neovim config before moving to Lazyvim has made me learn it to a decent extent, which makes this much easier.&lt;/p&gt;&#xA;&lt;h2 id=&#34;extras&#34;&gt;Extras&lt;/h2&gt;&#xA;&lt;p&gt;This is something i just pulled out of reddit recently and would love to share it. Thanks to &lt;a href=&#34;https://reddit.com/u/77ilham77&#34;&gt;u/77ilham77&lt;/a&gt;, there is a way to move windows without the title bar and I absolutely love it. It&#39;s just a simple command and viola you are read. This allows you to hold down &lt;code&gt;&amp;lt;C-CMD&amp;gt;&lt;/code&gt; and lets u move the window with your mouse.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;defaults write -g NSWindowShouldDragOnGesture -bool true&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://imgs.xkcd.com/comics/command_line_fu.png&#34; alt=&#34;xkcd 196 - command line fu&#34;&gt;&#xA;&lt;figcaption&gt;&lt;p&gt;xkcd comic 196 - command line fu&lt;/p&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;</description>
    </item>
    <item>
      <title>Meerkat build log</title>
      <link>https://adihegde.com/posts/systems/meerkat.html/</link>
      <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/systems/meerkat.html</guid>
      <description>&lt;p&gt;Meerkat is a p2p distributed application to maintain data synchronisation between all nodes using GRPC. Initially part of a hackathon idea proposed (available in &lt;a href=&#34;https://hegde.live/posts/dist_sys/inginy12&#34;&gt;this&lt;/a&gt; post)&lt;/p&gt;&#xA;&lt;h2 id=&#34;commits&#34;&gt;Commits&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/3f8b029069bff3ce0673b9dda92001a50175ade4&#34;&gt;3f8b029&lt;/a&gt; -&amp;gt; Migrating to GRPC and testing out basic node pinging.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/2291e07e67be6f91067e3bfe13130b58327e6612&#34;&gt;2291e07&lt;/a&gt; -&amp;gt; Implement a basic pool joining protocol.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/e9da45e1bd5b491133b542dc4be6060bb03e472c&#34;&gt;e9da45e&lt;/a&gt; -&amp;gt; Data transmission with failure in edge cases. Using 2 go routines to handle different aspects of the program.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/7a51506e730176bc8e80098e5b4e274f5acd2552&#34;&gt;7a51506&lt;/a&gt; -&amp;gt; Creating mutex locks to fix data race issues persistent in the program.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/6acc241568aaeb9dafe78e638ebb84bc26fcc580&#34;&gt;6acc241&lt;/a&gt; -&amp;gt; Basic graceful exit for simple fault tolerance during signal interrupts&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/bwaklog/meerkat/commit/b8ffb9fad0025447a631367c9c23c45f7524bf58&#34;&gt;b8ffb9f&lt;/a&gt; -&amp;gt; Creating Disk Snapshots to identify events of &lt;code&gt;DELETION&lt;/code&gt;, &lt;code&gt;ADDITION&lt;/code&gt; (updates and addition are broadcasted as the same type of event for now).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;issues&#34;&gt;Issues&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/7&#34;&gt;#7&lt;/a&gt;: &lt;em&gt;Streaming file contents as chunks&lt;/em&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Current method passes all bytes in one go through a stream. This is an issue with larger files&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/6&#34;&gt;#6&lt;/a&gt;: &lt;em&gt;fix: file deletion broadcasting&lt;/em&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; file deletions&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; folder operations are shadowed&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/5&#34;&gt;#5&lt;/a&gt;: _ Handle unexpected disconnects from nodes_&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Handle interrupts&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Handle fatal erros&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/4&#34;&gt;#4&lt;/a&gt;: &lt;em&gt;Dealing with merging 2 network pools&lt;/em&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Focus on this issue is to work with network partitions.&lt;/li&gt;&#xA;&lt;li&gt;Current system only deals with how a node can enter an existing network pool.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/3&#34;&gt;#3&lt;/a&gt;: &lt;em&gt;Move towards a gossip protocol&lt;/em&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Broadcast of changes happes to all nodes&lt;/li&gt;&#xA;&lt;li&gt;Move to gossip to reduce network overload, the goal is that data propagates to all nodes eventually.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/2&#34;&gt;#2&lt;/a&gt;: &lt;em&gt;Handshakes and Disconnects not going through&lt;/em&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Duplicate addition of nodes in the client list&lt;/li&gt;&#xA;&lt;li&gt;Safe node leaving boradcast doesn&#39;t propagate across the nodes&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Issue &lt;a href=&#34;https://github.com/bwaklog/meerkat/issues/1&#34;&gt;#1&lt;/a&gt;: &lt;em&gt;Attempt to connect to client twice&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;research-for-future-improvements&#34;&gt;Research for future improvements&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://raft.github.io/raft.pdf&#34;&gt;Raft Consensus Algorithm Paper&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Distributed Systems lecture by &lt;a href=&#34;https://martin.kleppmann.com/&#34;&gt;Martin Kleppmann&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;video-container&#34;&gt;&#xA;    &lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube-nocookie.com/embed/videoseries?si=4qyZinhJjrAFyn2w&amp;amp;controls=0&amp;amp;list=PLeKd45zvjcDFUEv_ohr_HdUFe97RItdiB&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Taking a few messy leaps in a hackathon</title>
      <link>https://adihegde.com/posts/systems/inginy12.html/</link>
      <pubDate>Sun, 21 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/systems/inginy12.html</guid>
      <description>&lt;h2 id=&#34;initial-problem-statement&#34;&gt;Initial Problem Statement&lt;/h2&gt;&#xA;&lt;p&gt;The proposed idea for the hackathon was way different compared to what our final product was supposed to be. What was planned was a live database collaboration implementation where one host, who has the data, allows a few collaborators who all connect together and modify the data. They would communicate through a &lt;em&gt;centralized&lt;/em&gt; log server and maintain data correctness.&lt;/p&gt;&#xA;&lt;p&gt;The approach taken to handle a request coming in, would be single threaded. The host node would work on two separate threads. One to process transaction in memory, and persist changes to the disk. The other thread would be how the host would contribute to the data. All the clients would simply send its operations to the log server (so would the host), and its action would be executed by the host. So this collaboration model followed more of a &lt;em&gt;client-server&lt;/em&gt; communication where &lt;em&gt;the host could also contribute to modification of data.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;The host would deal with the incoming requests through a TCP listener. This is similar to IO multiplexing. Host handles multiple TCP connections concurrently. It then executes these operations sequentially, ensuring data correctness which would need a different approach using locks when the process is multi threaded.&lt;/p&gt;&#xA;&lt;h2 id=&#34;creating-a-a-simple-echo-server&#34;&gt;Creating a a simple echo server&lt;/h2&gt;&#xA;&lt;p&gt;Just to test this connection mechanism, we tried out communication with all the connected peers using a simple echo server. A simple tcp listener was set up in go and all our nodes tapped into this connection.&lt;/p&gt;&#xA;&lt;p&gt;For now, an array in the host would hold the connection addresses of all the connections to the listener&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;var connectionChan = []net.Conn{}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Here is a basic sketch of the listener&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;func TCPActiveListener() {&#xA;  tcp, err := net.Listen(&amp;quot;tcp&amp;quot;, &amp;quot;:8080&amp;quot;)&#xA;&#xA;  for {&#xA;    // a go routine to accept multiple connections to the&#xA;    // tcp server&#xA;    go func() {&#xA;&#xA;      conn, err := tcp.Accept()&#xA;      connectionChan = append(connectionChan, conn)&#xA;&#xA;      for {&#xA;        connResp, err := readBlock(&amp;amp;conn)&#xA;&#xA;        if err == io.EOF {&#xA;          log.Printf(&amp;quot;[%s] DISCONNECT {EOF}&amp;quot;, conn.RemoteAddr())&#xA;        }&#xA;&#xA;        if err != nil {&#xA;          conn.Close()&#xA;          // remove connection from client list&#xA;          log.Printf(&amp;quot;[%s] DISCONNECT&amp;quot;, conn.RemoteAddr())&#xA;          break&#xA;        }&#xA;&#xA;        echoResponse(message string)&#xA;      }&#xA;    }()&#xA;  }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The response is echoed to all connections part of the client list. Building onto this, what was now needed, was to share some kind of instruction from a node to the listener. Decode this instruction and keep the operation in queue for execution.&lt;/p&gt;&#xA;&lt;p&gt;This initial idea, had a lot of bottle necks.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;If the data doesn&#39;t reach a log server. The data would be lost. There would be no reflection to a local contribution for a node in the connection.&lt;/li&gt;&#xA;&lt;li&gt;Data being sent to a centralized server and back to the primary host with the data would be a slow process. Having all commands executed move through this stream would be &lt;em&gt;inefficient&lt;/em&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;changes-made-to-the-problem-statement&#34;&gt;Changes made to the problem statement&lt;/h2&gt;&#xA;&lt;p&gt;On advice of our seniors, we changed the basis of the project. Instead of having a centralized log server handling all the &amp;quot;operation logs&amp;quot; that were to be forwarded to the host, we shifted it to a &lt;em&gt;peer to peer&lt;/em&gt; connection where all the data would be distributed and remain in memory. Every local contribution should reflect in the final synced up data across all the node sin this connection pool.&lt;/p&gt;&#xA;&lt;h2 id=&#34;proof-of-concept&#34;&gt;Proof of concept&lt;/h2&gt;&#xA;&lt;p&gt;Creating this &lt;em&gt;decentralized&lt;/em&gt; p2p connection, there would need to be a way to figure out how to set up the connection with peers and have the data. There needs to be at least one node who initiates the connection. During this the &amp;quot;host&amp;quot; would act as a server.&lt;/p&gt;&#xA;&lt;p&gt;Each client in the node would associate a set of data that identifies its existence in the network pool.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;┌─────────────┐&#xA;│ Client List │ -&amp;gt;  This is a list of clients connected to in the&#xA;└─────────────┘     network pool.&#xA;┌─────────────┐&#xA;│  Local in   │ -&amp;gt;  this is the data that is to be synced up&#xA;│   memory    │     when a node in a network has been changed&#xA;│    data     │     data persisted to memory is not the priority&#xA;└─────────────┘&#xA;┌─────────────┐&#xA;│   Lamport   │ -&amp;gt;  This is the logical clock associated to the&#xA;│    Clock    │     the node in the network&#xA;└─────────────┘&#xA;┌─────────────┐&#xA;│   Command   │ -&amp;gt;  Commands executed by that node. Could be used&#xA;│    Head     │     to trace back and help in rebuilding, incase&#xA;└─────────────┘     discrepancy during data syncing.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Each client in the connection must maintain such data for validity of connection and also to assist the node to communicate with other connections.&lt;/p&gt;&#xA;&lt;p&gt;Initial implementation of the communication was built with a TCP server. All data needs to be sent through this. Sending raw instructions cant be possible. Hence a payload was designed assist the receiving node. It would contain appropriate data for processing and also assist the node in what kind of process it would need to execute&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;┌─────────────┐&#xA;│   Header    │ -&amp;gt;  An integer representing the operation to be performed&#xA;└─────────────┘     • 0 -&amp;gt;  handle a new connection into network pool&#xA;                    • 1 -&amp;gt;  handle a new connection into a pool,&#xA;                            (this is when a client is part of a pool&#xA;                             and is connecting with the client part of&#xA;                             the client list it received)&#xA;                    • 2 -&amp;gt;  handle any sort of operation command&#xA;┌─────────────┐&#xA;│   Lamport   │ -&amp;gt;  The value of lamport clock of the node&#xA;│  Clock val  │&#xA;└─────────────┘&#xA;┌─────────────┐&#xA;│   Command   │ -&amp;gt;  Nodes command head at the time&#xA;│    Head     │&#xA;└─────────────┘&#xA;┌─────────────┐&#xA;│    Data     │ -&amp;gt;  Data sent over when trying to bring a node to the current&#xA;└─────────────┘     synced up version. Primarily when a node enters a pool.&#xA;┌─────────────┐&#xA;│ Client List │&#xA;└─────────────┘&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Not all these fields need to be filled up. Only the necessary ones would be filled up and sent over through the connection.&lt;/p&gt;&#xA;&lt;p&gt;Before sending any data over the connection, we would need to send it over in a way where data can be understandable on the other end. For this, data was marshaled to bytes using the json methods provided go&#39;s standard library &lt;code&gt;encoding/json&lt;/code&gt;. On the receiving end it would be decoded and would follow the instructions.&lt;/p&gt;&#xA;&lt;h2 id=&#34;initilizing-a-network-pool&#34;&gt;Initilizing a network pool&lt;/h2&gt;&#xA;&lt;p&gt;When two clients want to start a p2p connection, for initialization, either one of them would start the connection as a server. The client would then connect to this and send over a payload asking for the nodes client list and data. You would imagine it as two individuals exchanging each others contacts. Along with this the data would get shared over as well. This forms a p2p connection with 2 nodes.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/ingny12/forming-net-pool.png&#34; alt=&#34;Formation of a network pool&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Suppose there exists a network pool and another peer is trying to enter this. As there would be no leader in this connection, they should be able to connect using either one of the nodes. The procedure would follow the same steps as before with an additional one&lt;/p&gt;&#xA;&lt;p&gt;The entering node requests for the client list of its peers and the data. We assume that in a network, all the nodes have a synced up data. With this in mind the data is sent over to the node entering the network. They add each other to their client lists.&lt;/p&gt;&#xA;&lt;p&gt;The node goes through the client list and attempts to connect to each one of its clients. It shares it client list, which would be the latest one, and informs them to add them to their client list, hence a connection is formed with each of the remaining clients in the pool. Again an assumption would be all the data would be in sync, hence there wouldn&#39;t be a need of sharing that part. In case of any inconsistency, we would rely on reconstructing the data during any other operation communication.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/ingny12/client-connecting-to-others.png&#34; alt=&#34;Connecting with clients part of the client list&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h2 id=&#34;handling-data&#34;&gt;Handling data&lt;/h2&gt;&#xA;&lt;p&gt;The proposed concept was that we would be implementing a basic model of CRDT to make sure all the context of the data is retained when there could be concurrent executions.&lt;/p&gt;&#xA;&lt;p&gt;With the lamport clocks and the head commands, we could identify if any version of data was behind, and handle the cases accordingly. For example, if there is some sort of mis match regarding the version, the receiver would send its set of instructions to the sender and try brining both versions up to date.&lt;/p&gt;&#xA;&lt;h2 id=&#34;big-roadblock&#34;&gt;Big roadblock&lt;/h2&gt;&#xA;&lt;p&gt;Like said before, we didn&#39;t test out any of the connections. After finishing the first iteration of the client connection system. While testing this, we realized while the data was getting serialized correctly locally, the data seemed to disappear after the receiver node tried unlashing these bytes. We weren&#39;t able to get 2 nodes in consensus.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/ingny12/broken-communication-payload.png&#34; alt=&#34;Demonstration of the connection system where the data didn&#39;t pass through the TCP connection&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;Ignoring the nil value in the image, which was later fixed where instead of adding the connection object to the client list, we were only appending the value of the connection remote address as a string. Even this didn&#39;t go through.&lt;/p&gt;&#xA;&lt;h2 id=&#34;mistakes&#34;&gt;Mistakes&lt;/h2&gt;&#xA;&lt;p&gt;We made quite a few mistakes while working with this project. To list out - using TCP as our protocol, using json for serialization of the data. Throughout this hackathon, everything implemented was from scratch. While having premed modules available, we hesitated from using them.&lt;/p&gt;&#xA;&lt;p&gt;Considering this hackathon was 24 hours long, making everything from scratch set us back compared to our competition. Our initial problem statement being complex, made us work on the &lt;em&gt;theory&lt;/em&gt; of the implementation alone for about 4 hours. While the hack began at 5pm, from 8-11pm, we were still unsure about what we wanted to achieve, and where this could be applied.&lt;/p&gt;&#xA;&lt;p&gt;Only after a few reviews with our seniors, we then began working on the first implementation of this model.&lt;/p&gt;&#xA;&lt;p&gt;Another big mistake that we made was writing the code for the network connections without testing a single line. While our concept was robust and no apparent roadblock was visible, we didn&#39;t test crucial parts of our code.&lt;/p&gt;&#xA;&lt;p&gt;Our current model of how the nodes communicate with each other and rely on logical clocks would immediately fail, when there is any sort of network partition that occurs.&lt;/p&gt;&#xA;&lt;h2 id=&#34;learnings&#34;&gt;Learnings&lt;/h2&gt;&#xA;&lt;p&gt;This is something that I&#39;m really eager to work on. Of course, it was a long shot for a 24-hour hackathon. The plan that I put forward was messy to begin with but it was leading us to something. Looking back at it after a day of sleep, it seemed rather foolish that we were trying to reinvent this system. Again we tried doing this all in a few hours.&lt;/p&gt;&#xA;&lt;p&gt;Thanks to the help of all the seniors, the&#39;ve been helpful in showing new ways to approach this idea. Our goal set by our senior was to implement this basic distributed p2p connection with synced up data and implement a small text editor to show that such a connection is indeed possible. We weren&#39;t able to finish the first part.&lt;/p&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;It&amp;#39;s such a beautiful thing to see systems-oriented projects back at hackathons: (all 1st year students!) one team is attempting to add primitive gc to C, one team is attempting to implement a p2p collaborative text editor... This kinda stuff puts a smile on my face&lt;/p&gt;&amp;mdash; Anirudh Rowjee @ override.bsky.social (@AnirudhRowjee) &lt;a href=&#34;https://twitter.com/AnirudhRowjee/status/1781404565822165482?ref_src=twsrc%5Etfw&#34;&gt;April 19, 2024&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A few kind words from my senior Anirudh Rowjee :)&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Keeping all the points of failure in mind and also some other technologies and theories suggested by our seniors, I&#39;m planning to take another shot at this. This live data sharing architecture has been bugging my mind for the past few months. Especially since i&#39;ve been working on with my friend on our project, where we used the &lt;a href=&#34;zed.dev&#34;&gt;Zed, a text editor written in rust&lt;/a&gt;, which uses CRDT as a method of maintaining data correctness and allowing live sharing to take place. Ever since, i&#39;ve been more intrigued to work on something.&lt;/p&gt;&#xA;&lt;p&gt;The mentors and judges i&#39;ve spoken to have all been of great help. Just to be a part of the top 10 of this hackathon, definitely made me happy that with such a project theory, we were able to make it recognisable to some people. The mentors have backed us up the hackathon, providing us with great suggestions, and i&#39;m gonna keep these and move forward, work more on this theory. I definitely feel there is something that is possible with it and cannot leave it as another un-finished project.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Link Stash</title>
      <link>https://adihegde.com/stash.html/</link>
      <pubDate>Fri, 19 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/stash.html</guid>
      <description>&lt;p&gt;Here is a collection of links and articles that I found interesting. Also a mini book marking place for myself to remember trying out tools.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;homebrew-formulas-&#34;&gt;homebrew formulas 🍺&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://formulae.brew.sh/formula/mailsy&#34;&gt;mailsy&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;brew install mailsy&#xA;mailsy g&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Generates an email. We can use this for mailing lists or something. And access the emails sent over to the email with &lt;code&gt;mailsy m&lt;/code&gt; and opens the email in a local webserver.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;taskell&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;brew install taskell &#xA;brew info taskell&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;wifi-password&lt;/li&gt;&#xA;&lt;li&gt;mas : mac app store&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Notes from Goland Bangalore 75</title>
      <link>https://adihegde.com/posts/talks/gomeet_13apr.html/</link>
      <pubDate>Sat, 13 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/talks/gomeet_13apr.html</guid>
      <description>&lt;p&gt;This post contains a few notes from the Go Blore meetup on 13th April 2024. The speakers covered a few points on profiling in go, hands on demonstrations on it, dependency injection and a talk on how to use go with android.&lt;/p&gt;&#xA;&lt;h1 id=&#34;profiling-with-go&#34;&gt;Profiling with Go&lt;/h1&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;by &lt;a href=&#34;&#34;&gt;Swapnil Nakade&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;points-covered&#34;&gt;Points covered&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Using &lt;a href=&#34;https://pkg.go.dev/net/http/pprof&#34;&gt;net/http/pprof&lt;/a&gt; with go to profile either the CPU, memory or block profiling&lt;/li&gt;&#xA;&lt;li&gt;Visualisation of profiling using either the CLI, web flow diagram or flame graph&lt;/li&gt;&#xA;&lt;li&gt;Breaking down the code with profiling and finding places to improve performance&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Implementing Zettelkasten in Anna</title>
      <link>https://adihegde.com/posts/tech/zettel_impl.html/</link>
      <pubDate>Wed, 10 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/tech/zettel_impl.html</guid>
      <description>&lt;h1 id=&#34;proof-of-concept&#34;&gt;Proof of concept&lt;/h1&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://notes.andymatuschak.org/&#34;&gt;Andy Matuschak&#39;s&lt;/a&gt; working notes is the key inspiration for this concept.&#xA;We are trying to deviate from the &amp;quot;general idea&amp;quot; of a blog site and focus more on this niche use case.&#xA;By integrating this feature, we are letting users to create a space to store there &amp;quot;zettels&amp;quot; and share their short notes as well.&lt;/p&gt;&#xA;&lt;p&gt;We aren&#39;t trying to re-invent the process of making an editor that helps users maintain these zettels as there are already some fantastic applications,&#xA;namely &lt;a href=&#34;https://obsidian.md/&#34;&gt;Obsidian&lt;/a&gt;, &lt;a href=&#34;https://app.gingkowriter.com&#34;&gt;Ginko Writer&lt;/a&gt; and &lt;a href=&#34;https://evergreennotes.com/&#34;&gt;Evergreen Notes&lt;/a&gt;.&#xA;Our application as a rather needs to provide a generator to stitch these notes&#xA;together to make it accessible on the site.&lt;/p&gt;&#xA;&lt;h2 id=&#34;stages-of-generations-of-notes&#34;&gt;Stages of Generations of Notes&lt;/h2&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;10-figuring-out-the-named-links&#34;&gt;1.0 Figuring out the named links.&lt;/h3&gt;&#xA;&lt;p&gt;All notes usually have titles as a phrase that can be referred to in a certain note. Our job as the SSG is to link these two notes together. For example&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-md&#34;&gt;Sed ut velit ante. Suspendisse ac porta urna, eget iaculis dui. Lorem ipsum&#xA;dolor sit amet, consectetur adipiscing elit. Donec vel enim dolor.&#xA;[[Nunc ullamcorper]] neque ut mattis commodo. Morbi bibendum sem accumsan mi&#xA;imperdiet, id egestas nulla posuere. Morbi sodales justo euismod nulla&#xA;porttitor lobortis sed ut sem.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The above md file is referencing a note namely &lt;code&gt;Nunc ullamcorper&lt;/code&gt;. What needs to be done is, this &amp;quot;callout&amp;quot; is to be replaced by a link to that specific &amp;quot;note&amp;quot;.&lt;/p&gt;&#xA;&lt;h4 id=&#34;11-basic-working-model&#34;&gt;1.1 Basic Working Model&lt;/h4&gt;&#xA;&lt;p&gt;The parser must search through the &lt;code&gt;Body&lt;/code&gt; section of these &lt;em&gt;notes&lt;/em&gt;.&#xA;There are supposed to be &amp;quot;user defined&amp;quot; references to notes, which the parser must identify and add.&#xA;The specific reference to the &lt;code&gt;template data&lt;/code&gt; of that specific post is appended with the information of all the links that it has found during parsing of the file.&#xA;This can be utilised later by the templating engine.&lt;/p&gt;&#xA;&lt;h4 id=&#34;a-namelinking-automationa12-automation-of-linking-process&#34;&gt;&lt;a name=&#34;linking-automation&#34;&gt;&lt;/a&gt;1.2 Automation of linking process&lt;/h4&gt;&#xA;&lt;p&gt;The previous method suggests the user has to manually link posts.&#xA;With automation, the goal is to remove the need for manually entering these links.&#xA;Instead we plan to use the &lt;code&gt;[[]]&lt;/code&gt; callouts to the note name.&#xA;For example, &lt;code&gt;[[Nunc ullamcorper]]&lt;/code&gt; will reference the markdown file which contains &amp;quot;Nunc ullamcoper&amp;quot; as the &lt;em&gt;Title&lt;/em&gt;.&#xA;These callouts to other notes are to be picked out by the parser and replaced with a proper markdown reference in the buffer, so that the acutal file remains untouched.&#xA;For example &lt;code&gt;[[Nunc ullamcorper]]&lt;/code&gt; will be updated to &lt;code&gt;[Nunc ullamcorper](/notes/zettel_name/123782734234)&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h4 id=&#34;13-automation-of-file-creation&#34;&gt;1.3 Automation of file creation&lt;/h4&gt;&#xA;&lt;p&gt;This is a step forward from from &lt;a href=&#34;#linking-automation&#34;&gt;Automation of linking process&lt;/a&gt;. As we are not a text editing application, this feature will make the process of creating subnotes simpler.&lt;/p&gt;&#xA;&lt;p&gt;Other than just the parser identifying the &lt;code&gt;[[]]&lt;/code&gt; callouts, during the live reload process, an additional file will be created under the same &lt;em&gt;zettel&lt;/em&gt;, provided a name is mentioned in the &lt;em&gt;callout&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;20-restructuring&#34;&gt;2.0 Restructuring&lt;/h3&gt;&#xA;&lt;p&gt;As of now, our content directory looks somewhat like this:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;|— pages markdown files&#xA;|— /posts : post dir containing markdown files for all posts&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;To this, we plan to add an extra directory named &lt;code&gt;notes&lt;/code&gt; that will handle all of our zettles.&#xA;Each zettel (related notes) can be organised in its own sub directories.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Reference:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://zettelkasten.de/posts/create-zettel-from-reading-notes/&#34;&gt;Zettelkasten creation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://notes.andymatuschak.org/Evergreen_notes_should_be_atomic&#34;&gt;Evergreen Notes should be Atomic&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;We expect users users to specify the head of these zettels by themseves in the frontmatter explicitly&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;---&#xA;title: Note taking can be fun&#xA;date: 2024-04-08&#xA;type: zettel&#xA;head: true&#xA;---&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h4 id=&#34;21-concept-of-the-mega-struct--deep-data-merge&#34;&gt;2.1 Concept of the &lt;code&gt;Mega Struct&lt;/code&gt; &amp;amp; Deep Data Merge&lt;/h4&gt;&#xA;&lt;p&gt;As each zettel must have access to the information of all other zettels, the implementation of a Deep Data Merge is quite necessary.&#xA;Each page is rendered by passsing a &lt;code&gt;Mega Struct&lt;/code&gt; that the entire data of the notes section.&#xA;This struct will have the following fields:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;type NotesMerged struct {&#xA;    //Stores all the notes&#xA;    Notes map[template.URL]Note&#xA;&#xA;    //Stores the links of each note to other notes&#xA;    LinkStore map[string][]*NoteStruct&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;code&gt;LinkStore&lt;/code&gt; is a map which contains a slice of pointers to the &lt;em&gt;linked notes&lt;/em&gt; which eliminates data redundancy to certain extent.&#xA;This is an essential feature as Zettel emphasises on dense linking of notes.&lt;/p&gt;&#xA;&lt;p&gt;This &lt;code&gt;LinkStore&lt;/code&gt; Map is the second step of generation after all the notes in the &lt;code&gt;notes&lt;/code&gt; directory have been successfully parsed.&#xA;Once the link maps have been generated, we use a similar render note function to produce the linked html files.&lt;/p&gt;&#xA;&lt;p&gt;Each Note can is a struct that stores all of the data of a particular note, including the frontmatter.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;type Note struct {&#xA;    // Note data including frontmatter and content&#xA;    LinkedNotes   []string&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;todo-for-zettelkasten-impl&#34;&gt;TODO for zettelkasten impl&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Generation of Linked Notes&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Implement 1.1 version of linking (user defined references to notes)&lt;/li&gt;&#xA;&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Implement automation for the process of linking. Using &lt;code&gt;[[]]&lt;/code&gt; callouts to file names.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Tests:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; unit tests for parsing parocess of the package rendering processes of package&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Presenting anna at fireside</title>
      <link>https://adihegde.com/posts/talks/fireside_anna.html/</link>
      <pubDate>Thu, 04 Apr 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/talks/fireside_anna.html</guid>
      <description>&lt;p&gt;There are several amazing SSGs out there, like &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; and&#xA;&lt;a href=&#34;https://www.11ty.dev/&#34;&gt;11ty&lt;/a&gt;. Building your own SSG is an amazing learning&#xA;experience. It also motivates one to maintain and improve their personal site.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Presented and written by Adhesh, Anirudh, Aditya and Nathan&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Building personal blogs from the ground up can be a &lt;em&gt;tedious process&lt;/em&gt;. Some of us&#xA;have had our hands deep in vanilla HTML and CSS, which isn&#39;t fun to maintain. We&#xA;all want to get to the point and share our thoughts on the web. But, there is a&#xA;small bump that stops us from doing so.&lt;/p&gt;&#xA;&lt;p&gt;Maintaining your personal site is like working with your own Neovim&#xA;configuration. Every issue fixed would lead to an entirely unrelated bug. There&#xA;is a lot of time spent fixing things rather than getting productive work done.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A static site generator is an immensely useful application&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;!-- ![Lighthouse scores of the anna-docs page](https://raw.githubusercontent.com/acmpesuecc/anna/main/site/static/images/posts/fireside-anna/lighthouse.png) --&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/fireside-anna/lighthouse.png&#34; alt=&#34;Lighthouse scores of the anna-docs page&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;p&gt;It can simplify the whole process: allowing you to spend time and energy&#xA;on quality content. Keep reading to find out how we designed anna &lt;code&gt;v1.0.0&lt;/code&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;ACM-PESU ECC conducts the ACM Industrial Experience Program (AIEP), an annual program that spans six weeks.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;It involves students working as a team to develop an industrial-level&#xA;project. AIEP intends to give students hands-on experience with real-world&#xA;projects. It is an excellent opportunity to interact with like-minded&#xA;individuals.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Our AIEP team consisted of &lt;a href=&#34;https://github.com/DedLad&#34;&gt;Adhesh&lt;/a&gt;, &lt;a href=&#34;https://github.com/bwaklog&#34;&gt;Aditya&lt;/a&gt;,&#xA;&lt;a href=&#34;https://github.com/polarhive&#34;&gt;Nathan&lt;/a&gt;, and &lt;a href=&#34;https://github.com/anirudhsudhir&#34;&gt;Anirudh&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Our mentors (cool ass senior names!) gave us some great ideas for a team of us&#xA;four freshers.&#xA;We were puzzled whether to build a distributed Postgres clone or a load balancer.&lt;/p&gt;&#xA;&lt;p&gt;Deep discussions over a week got us to the topic of making&#xA;blog sites and how tiring it is to work with, which only gets worse as you&#xA;write more and more content for your internet home.&lt;/p&gt;&#xA;&lt;p&gt;This and inspirations from &lt;a href=&#34;https://github.com/anirudhRowjee/saaru&#34;&gt;Saaru&lt;/a&gt; and&#xA;&lt;a href=&#34;https://github.com/NavinShrinivas/sapling&#34;&gt;Sapling&lt;/a&gt; pushed us to tackle this&#xA;problem with our own SSG.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;    ___&#xA;   /   |  ____  ____  ____ _&#xA;  / /| | / __ \/ __ \/ __ `/&#xA; / ___ |/ / / / / / / /_/ /&#xA;/_/  |_/_/ /_/_/ /_/\__,_/&#xA;&#xA;A static site generator in Go&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;the-small-but-big-decision&#34;&gt;The small but big decision!&lt;/h2&gt;&#xA;&lt;p&gt;Anna is written in &lt;a href=&#34;https://go.dev&#34;&gt;Go&lt;/a&gt;. We considered writing it in Rust, but&#xA;that came with a steep learning curve.&#xA;Go is a powerful language and has excellent concurrency support, which suited our requirements to build a performant application.&lt;/p&gt;&#xA;&lt;h3 id=&#34;whats-in-a-name&#34;&gt;What&#39;s in a name?&lt;/h3&gt;&#xA;&lt;p&gt;Probably the first thing that us four came across when joining ACM and HSP was the famous Saaru repository.&#xA;&lt;a href=&#34;https://github.com/anirudhRowjee/saaru&#34;&gt;Saaru&lt;/a&gt;,&#xA;one of the projects that inspired our ssg, is derived from a &lt;a href=&#34;https://en.wikipedia.org/wiki/Kannada&#34;&gt;Kannada&lt;/a&gt; word.&#xA;Saaru is a thin lentil soup, usually served with rice.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;In Kannada, rice is referred to as &#39;anna&#39;(ಅನ್ನ) pronounced &lt;i&gt;/ɐnːɐ/&lt;/i&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This was just a playful stunt that we played. We plan on beating Saaru at&#xA;build times, optimizing at runtime.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;genesis&#34;&gt;Genesis&lt;/h2&gt;&#xA;&lt;p&gt;We began the project in a unique manner, with each of us creating our own&#xA;prototype of the SSG. This was done to familiarize everyone with the Go&#xA;toolchain.&lt;/p&gt;&#xA;&lt;p&gt;The first version of the SSG did just three things. It rendered markdown&#xA;(stored in files in a content folder in the project directory) to HTML. This&#xA;HTML was injected into a layout.html file and served over a local web server.&#xA;Later, we implemented a front matter YAML parser to retrieve page metadata&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;what-made-us-develop-this-to-a-great-extent&#34;&gt;What made us develop this to a great extent?&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Beginner-friendly: An easy setup wizard, easy and ready to use layouts, and themes. We want the&#xA;process of typing out a blog and putting it up on your site to be short and&#xA;simple.&lt;/li&gt;&#xA;&lt;li&gt;Speed: Be fast (hugo – written in Go, is remarkably fast)&lt;/li&gt;&#xA;&lt;li&gt;Maintainable: This ssg will be used by us, hence it should be easy to fix&#xA;bugs and add new features&lt;/li&gt;&#xA;&lt;li&gt;Learning curve: None of us have really shipped a production ready&#xA;application. Since AIEP is all about making industry-ready projects, we chose&#xA;to use go: so we could spend more &lt;em&gt;&lt;strong&gt;writing&lt;/strong&gt; code&lt;/em&gt; and not worrying about our&#xA;toolchain or escaping dependency hell.&lt;/li&gt;&#xA;&lt;li&gt;Owning a piece of the internet: Aditya and Anirudh registered their own&#xA;domain names. Now their anna sites live on [hegde.live] and [sudhir.live]&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;benchmarks-can-anna-lift&#34;&gt;Benchmarks! Can anna lift??&lt;/h2&gt;&#xA;&lt;p&gt;In simple terms, to beat Saaru&#39;s render time (P.S. we did!). Something you&#xA;probably never notice while deploying, but it is what pushed us to spend hours&#xA;on this.&lt;/p&gt;&#xA;&lt;p&gt;Adhesh was pretty excited to pick up Go and implement profiling, shaving&#xA;milliseconds off-of build times, when he implemented parallel rendering using&#xA;goroutines.&lt;/p&gt;&#xA;&lt;h2 id=&#34;prototype&#34;&gt;Prototype&lt;/h2&gt;&#xA;&lt;p&gt;The initial prototype built by Adhesh consisted of a multi-goroutine system.&#xA;A new goroutine would be spawned to walk the required directories.&#xA;If the current path being walked was a file, the path would be passed to another function along with its current modification time.&lt;/p&gt;&#xA;&lt;p&gt;The previous mod time of the file would then be retrieved from a map holding the mod times of all the files:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;If the given file was freshly created, its modification time would be added to the map.&lt;/li&gt;&#xA;&lt;li&gt;If there was no change in the mod time, no changes would be made.&lt;/li&gt;&#xA;&lt;li&gt;If there was a change between the current and previous mod times, another function would be called.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The new function checks if a child process is running:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;For the first render, when a process has not been created, a new process is created that runs anna (&amp;quot;go run main.go --serve&amp;quot;)&lt;/li&gt;&#xA;&lt;li&gt;For successive renders, the existing process is killed and a new process is spawned once again that runs anna.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This prototype was not very efficient as it created and killed processes for every change.&#xA;It had multiple goroutines attempting to walk the directories at the same time.&#xA;It also used multiple mutual exclusion locks to prevent data races.&#xA;Integrating this into the project also proved to be challenging.&lt;/p&gt;&#xA;&lt;h2 id=&#34;improved-version&#34;&gt;Improved version&lt;/h2&gt;&#xA;&lt;p&gt;The live reload feature was improved by Anirudh.&#xA;The updated version utilised two goroutines.&lt;/p&gt;&#xA;&lt;p&gt;The main goroutine used the earlier file walker, with one important change: it sequentially traversed the directory without spawning new goroutines.&#xA;For any modification to a file in the current traversal, a vanilla render of the entire site would be performed.&#xA;The goroutine would then sleep for a specified duration (currently 1 second) before attempting the next directory traversal.&lt;/p&gt;&#xA;&lt;p&gt;The secondary goroutine ran a local web server that served the rendered/ directory.&lt;/p&gt;&#xA;&lt;p&gt;This eliminated all locks and avoided the creation and destruction of any child processes.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;we-cook-&#34;&gt;We cook! 🍳&lt;/h2&gt;&#xA;&lt;p&gt;Here are some screenshots out of our group chats, that demonstrate build times, profiling et-al when having thousands of markdown files or in this case&#xA;just copy-pasting a single markdown file en-mass!&lt;/p&gt;&#xA;&lt;!-- ![Hyperfine benchmarks comparing the render times of anna, Saaru and 11ty](https://raw.githubusercontent.com/acmpesuecc/anna/main/site/static/images/posts/fireside-anna/bench.png) --&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/fireside-anna/bench.png&#34; alt=&#34;Hyperfine benchmarks comparing the render times of anna, Saaru and 11ty&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;After about 2 weeks of training (&lt;em&gt;ahem&lt;/em&gt;) coding, we had a (merge) bringing parallel rendering and profiling to the table&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3 id=&#34;profiling&#34;&gt;Profiling&lt;/h3&gt;&#xA;&lt;p&gt;Heres the CPU profile of anna, generated using pprof.&#xA;This profile was generated while rendering this site.&lt;/p&gt;&#xA;&lt;p&gt;Here&#39;s an SVG showing how much time each sys-call / process takes and how each block adds-up to render / build times&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/fireside-anna/cpu_prof.svg&#34; alt=&#34;CPU profile of an anna render generated using pprof&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;!-- ![CPU profile of an anna render generated using pprof](/static/images/posts/fireside-anna/cpu_prof.svg) --&gt;&#xA;&lt;p&gt;You may wanna zoom-in about 3-4x times to get to see how our ssg works&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;a-big-rewrite-when-we-went-for-a-tdd-approach&#34;&gt;A big rewrite (when we went for a TDD approach)&lt;/h2&gt;&#xA;&lt;p&gt;Starting off this project, we kept adding functionality without optimization.&#xA;We didn’t have a proper structure; PRs would keep breaking features and overwriting functions written by fellow team-mates.&lt;/p&gt;&#xA;&lt;h3 id=&#34;a-new-proposed-rendering-system&#34;&gt;A new proposed rendering system&lt;/h3&gt;&#xA;&lt;p&gt;We proceeded to restructure our SSG into: modules previously part of &lt;code&gt;cmd/anna/utils.go&lt;/code&gt; and &lt;code&gt;cmd/anna/main.go&lt;/code&gt; were to be split between &lt;code&gt;pkg/parsers/&lt;/code&gt;, &lt;code&gt;pkg/engine/&lt;/code&gt; and &lt;code&gt;pkg/helper&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;pkg&#xA;├─── helpers&#xA;│   ├─── helpers.go&#xA;│   └─── helper_test.go&#xA;├─── engine&#xA;│   ├─── anna_engine.go&#xA;│   ├─── anna_engine_test.go&#xA;│   ├─── engine.go&#xA;│   ├─── engine_test.go&#xA;│   ├─── user_engine.go&#xA;│   ├─── user_engine_test.go&#xA;│   └─── engine_integration_test.go&#xA;└─── parsers&#xA;&#x9;├── parser.go&#xA;&#x9;├── parser_test.go&#xA;&#x9;└── parser_integration_test.go&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Currently there are two separate types of files that have to be rendered. One set includes user-defined files such as &lt;code&gt;index.md&lt;/code&gt;, &lt;code&gt;docs.md&lt;/code&gt; and various posts. These are specific to a user.&lt;/p&gt;&#xA;&lt;p&gt;The second set of files that are rendered include &lt;code&gt;tags.html&lt;/code&gt;, &lt;code&gt;sub-tags.html&lt;/code&gt; and &lt;code&gt;posts.html&lt;/code&gt;&#xA;Now, the generator/engine has a method to render &amp;quot;anna specific&amp;quot; pages and another method to render &amp;quot;user defined&amp;quot; pages which include all the user pages and posts&lt;/p&gt;&#xA;&lt;p&gt;Here&#39;s some of Anirudh and Hegde&#39;s work written during week-2&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Refactored main.go to only handle flags&lt;/li&gt;&#xA;&lt;li&gt;Wrote unit and integration tests for the parser and engine package&lt;/li&gt;&#xA;&lt;li&gt;Split the rendering system to make parallelisation easier by switching to a three method system.&lt;/li&gt;&#xA;&lt;li&gt;Render &amp;quot;user defined&amp;quot; pages which include all markdown files and posts (This method has been parallelised)&lt;/li&gt;&#xA;&lt;li&gt;Render tags and tag-sub pages separately, which could be parallelised in the future&lt;/li&gt;&#xA;&lt;li&gt;Wrote a benchmark for main.go that times the entire application&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;to-search-or-not-to-search-&#34;&gt;To search or not to search? 🤔&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;That is the question &amp;gt; Is our &lt;em&gt;static site&lt;/em&gt; becoming and at what cost?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;We were wondering if we’d need a search function on our site since Google and&#xA;any other web-crawler index our site anyway. If we needed to implement it, we&#xA;had a constraint: we cannot use an API. It had to be static and local to be&#xA;user-friendly to work with.&#xA;Aditya and Anirudh implemented a JSON index generator that uses &amp;quot;Deep Data Merge&amp;quot; to index posts on our site.&lt;/p&gt;&#xA;&lt;p&gt;This index is built at runtime and works without any lag or noticeable delay when searching across posts.&#xA;We mean to re-write it using WASM if necessary and if it costs us time when performing searches.&lt;/p&gt;&#xA;&lt;!-- ![anna-search](https://raw.githubusercontent.com/acmpesuecc/anna/main/site/static/images/posts/fireside-anna/search.gif) --&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/fireside-anna/search.gif&#34; alt=&#34;Demonstration of the search feature in anna&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h2 id=&#34;js-integration-as-plugins&#34;&gt;JS integration as plugins&lt;/h2&gt;&#xA;&lt;p&gt;Aditya added a field to our frontmatter which lets you pick and add certain JS&#xA;based snippets to your site.&#xA;This way, you get to add &lt;code&gt;highlight.js&lt;/code&gt; support, analytics scripts and donation page widgets; that you can source from the &lt;code&gt;static/scripts&lt;/code&gt; folder and toggle as needed per-markdown page.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wizard&#34;&gt;Wizard&lt;/h2&gt;&#xA;&lt;p&gt;Nathan proceeded to work on a GUI; a web-based wizard that let&#39;s a new user&#xA;setup anna along with a couple of easter eggs along the way 🍚&lt;/p&gt;&#xA;&lt;p&gt;The wizard lets a user pick a theme, enter your name, pick navbar elements, and&#xA;validates fields using regex checks so you don’t need to worry about relative&#xA;paths in baseURLs, canonical links, and sitemaps. After successfully completing&#xA;the setup, the wizard launches a live preview of your site in a new tab.&lt;/p&gt;&#xA;&lt;!-- ![anna-search](https://raw.githubusercontent.com/acmpesuecc/anna/main/site/static/images/posts/fireside-anna/wizard.gif) --&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;/static/images/posts/fireside-anna/wizard.gif&#34; alt=&#34;Demonstration of the GUI wizard in anna&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;h3 id=&#34;raw-html&#34;&gt;Raw HTML&lt;/h3&gt;&#xA;&lt;p&gt;What if you&#39;d want to add a contact form to your site? or embed YouTube videos or iframes of your choosing?&lt;/p&gt;&#xA;&lt;p&gt;Anna let&#39;s us do that! Although, the point of a static site generator is to&#xA;quickly get to writing and focusing on the content.&#xA;You can still embed js elements and iframe as needed to showcase any interesting YouTube videos or to just rickroll people!&lt;/p&gt;&#xA;&lt;h2 id=&#34;tags&#34;&gt;Tags&lt;/h2&gt;&#xA;&lt;p&gt;You can tag posts by hand, at the start of each markdown file and you get a&#xA;nice sub-page on your site so readers can discover similar content or browser&#xA;by category.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;changelog-showcasing-important-additions-----as-the-weeks-proceeded&#34;&gt;changelog: showcasing important additions --- as the weeks proceeded&lt;/h3&gt;&#xA;&lt;p&gt;Nathan:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;feat: implement sitemap.xml by @polarhive in #17&lt;/li&gt;&#xA;&lt;li&gt;feat: ogp tags and atom feed by @polarhive in #33&lt;/li&gt;&#xA;&lt;li&gt;feat: bootstrap site and import stylesheets by @polarhive in #73&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Adhesh:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;feat: cobra (cli), yaml rewrite for baseURL by @DedLad in #2&lt;/li&gt;&#xA;&lt;li&gt;feat: profiling (--prof) by @DedLad in #44&lt;/li&gt;&#xA;&lt;li&gt;feat: live-reload and file watch by @DedLad #27&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Anirudh:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Tags&lt;/li&gt;&#xA;&lt;li&gt;Organizing posts into collections based on tags&lt;/li&gt;&#xA;&lt;li&gt;Reverse search for posts of a certain category&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Aditya:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;fix: enable unsafeHTML by @bwaklog in #45&lt;/li&gt;&#xA;&lt;li&gt;feat: implement drafts by @bwaklog in #9&lt;/li&gt;&#xA;&lt;li&gt;feat: chronological feed, js plugins (eg: light.js, prism.js) by @bwaklog in #32&lt;/li&gt;&#xA;&lt;li&gt;feat: json generator implementation along with a site wide search bar by @bwaklog in #70&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;We are at week: 3/6 and have a lot of things in store and bugs to squash!&lt;/p&gt;&#xA;&lt;p&gt;Today &lt;a href=&#34;https://github.com/acmpesuecc/anna/releases/latest&#34;&gt;anna&lt;/a&gt; is tagged at v1.0.0 and we use it on our personal sites:&#xA;&lt;a href=&#34;https://hegde.live&#34;&gt;hegde.live&lt;/a&gt; // &lt;a href=&#34;https://sudhir.live&#34;&gt;sudhir.live&lt;/a&gt; // &lt;a href=&#34;https://polarhive.net&#34;&gt;polarhive.net&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Quality of work</title>
      <link>https://adihegde.com/posts/inked/work.html/</link>
      <pubDate>Sat, 09 Mar 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/work.html</guid>
      <description>&lt;h2 id=&#34;parallax-in-approach&#34;&gt;Parallax in approach&lt;/h2&gt;&#xA;&lt;p&gt;A few thoughts off of my mind, my perspective on effort. It&#39;s something I&#39;m a bit particular about. For me, there is a wall separating work achieved from hard work and work done for the sake of it. A wall that no one can pass through unless you change your approach or perspective of a situation.&lt;/p&gt;&#xA;&lt;p&gt;I&#39;m a person who is particular about my job. I tend to put myself down and set unrealistic expectations at times. Now people would say, I&#39;m crazy for it. But, it&#39;s that mindset for me that makes me want to do more.&lt;/p&gt;&#xA;&lt;p&gt;Every second part of your effort on something counts, it makes a difference. For me, the end result must showcase that effort. You can&#39;t spend hours together working on something, only for the end result to be garbage. If it doesn&#39;t go in hand with the effort that pooled in.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;navigating-perspectives&#34;&gt;Navigating perspectives&lt;/h2&gt;&#xA;&lt;p&gt;Being true to your work is one more thing that is very important. Set your margins high, as not everyone has the same perspective. Don&#39;t ever make assumptions about whether the other party is on the same wavelength as you are. Things break down real quick the moment that happens. You never expect it and then it hits you, had in the back. All that effort, gone down the drain, and now you&#39;re at square one.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;figure&gt;&#xA;&lt;img alt=&#34;xkcd comic 1658 - estimating time&#34; loading=&#34;lazy&#34; src=&#34;https://imgs.xkcd.com/comics/estimating_time_2x.png&#34;&gt;&#xA;&lt;figcaption&gt;xkcd comic 1658 - estimating time&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;</description>
    </item>
    <item>
      <title>Snapshots</title>
      <link>https://adihegde.com/clicks.html/</link>
      <pubDate>Sat, 24 Feb 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/clicks.html</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;Camera gear: Cannon EOS Rebel XSi (no idea about the lens) and Sony a6700 with a Sony E PZ G 18-105 mm F4 G Lens&lt;/p&gt;&#xA;&lt;p&gt;Click on any image for the &lt;em&gt;high resolution version&lt;/em&gt;. You can find my other stills on &lt;a href=&#34;https://unsplash.com/@adihegde&#34;&gt;unsplash&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;div class=&#34;image-grid&#34; id=&#34;image-grid&#34;&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.unsplash.com/photo-1771554818662-a073af33a80e?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzMzUxMDh8MHwxfGFsbHx8fHx8fHx8fDE3NzIzNDY4MzR8&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1440&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.unsplash.com/photo-1772130531402-01d2d3ec2ecc?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzMzUxMDh8MHwxfGFsbHx8fHx8fHx8fDE3NzIzNDY2MjR8&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1440&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.unsplash.com/photo-1766831958762-8ffb5a3d86a9?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzMzUxMDh8MHwxfGFsbHx8fHx8fHx8fDE3NzIzNDY5Njl8&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1440&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.unsplash.com/photo-1766831960791-b26d4314a86c?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzMzUxMDh8MHwxfGFsbHx8fHx8fHx8fDE3NzIzNDcwMDF8&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1440&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://images.unsplash.com/photo-1739971567855-0d17a6f8dafb?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzMzUxMDh8MHwxfGFsbHx8fHx8fHx8fDE3NzIzNDcwNTN8&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1440&#34; alt=&#34;&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Aditya Hegde</title>
      <link>https://adihegde.com/index.html/</link>
      <pubDate>Sat, 24 Feb 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/index.html</guid>
      <description>&lt;div style=&#34;display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: var(--style-body-font); --pfp-size: calc(2.5 * var(--style-body-font));&#34;&gt;&#xA;  &lt;img loading=&#34;lazy&#34; src=&#34;https://codeberg.org/bwaklog.png&#34; style=&#34;background-color: var(--inline-code-bg); height: var(--pfp-size); width: var(--pfp-size) !important; margin: 0 !important; flex-shrink: 0; object-fit: cover;&#34; alt=&#34;Aditya Hegde pfp&#34;&gt;&#xA;  &lt;h1 style=&#34;margin: 0; overflow-wrap: break-word; word-break: break-word;&#34;&gt;Aditya Hegde&lt;/h1&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Hello world! I&#39;m Aditya Hegde. Currently interning at &lt;a href=&#34;https://www.akamai.com/&#34;&gt;Akamai&lt;/a&gt;. Prev. research intern at &lt;a href=&#34;https://www.theinnovationlab.in/&#34;&gt;PES Innovation Lab&lt;/a&gt; (prev. Microsoft Innovation Lab).&lt;/p&gt;&#xA;&lt;p&gt;Currently pursuing my bachelors degree in CSE at &lt;a href=&#34;https://pes.edu&#34;&gt;PESU&lt;/a&gt;. I have a fond interest in building systems and storage. Outside of my work, I spend my time &lt;em&gt;trying&lt;/em&gt; to play the Guitar, am a &amp;quot;hobby photographer&amp;quot; and love rock and coffee.&lt;/p&gt;&#xA;&lt;!-- ![Vintage at Mels Drive In, Universal Studios Singapore](https://images.adihegde.com/camera/singapore/aditya-hegde-7HwnXgoLYuM-unsplash.jpg)&#xA;Vintage at Mels Drive In, Universal Studios Singapore --&gt;&#xA;&lt;p&gt;I&#39;m part of a small community called &lt;a href=&#34;https://hsp-ec.xyz&#34;&gt;HSP&lt;/a&gt; in my university and together run a the FOSS team &lt;a href=&#34;https://homebrew.hsp-ec.xyz&#34;&gt;homebrew&lt;/a&gt; where we try to grow and network beyond our university in different meetups and workshops. Since my internship at PIL (PES Innovation Lab), I am part of the research lab as a member where we maintain the infra for events and mentor the incomming intern batches.&lt;/p&gt;&#xA;&lt;p&gt;This site came about after my frustrations of maintaining a simple webpage without moving to a JS framework. A couple of my friends and I built &lt;a href=&#34;https://github.com/anna-ssg/anna&#34;&gt;anna&lt;/a&gt;, which is what is used to build this site.&lt;/p&gt;&#xA;&lt;p&gt;This site has a bunch of semi-organised &lt;a href=&#34;/collections/post.html&#34;&gt;posts&lt;/a&gt; that I try writing once in a while and TIL&#39;s (huge inspiration from Simon Willson&#39;s TIL page at &lt;a href=&#34;https://til.simonwillison.net/&#34;&gt;til.simonwillison.net&lt;/a&gt;), where I will be dumping links and other side notes that I take while learning and when I attend talks.&lt;/p&gt;&#xA;&lt;p&gt;Connect with me on &lt;a href=&#34;https://github.com/bwaklog&#34;&gt;Github&lt;/a&gt;, &lt;a href=&#34;https://www.linkedin.com/in/adityamhegde/&#34;&gt;Linkedin&lt;/a&gt;, &lt;a href=&#34;https://unsplash.com/adihegde&#34;&gt;Unsplash&lt;/a&gt;, &lt;a href=&#34;https://x.com/bwaklog&#34;&gt;𝕏&lt;/a&gt; or mail me at &lt;a href=&#34;mailto:mail@adihegde.com&#34;&gt;mail@adihegde.com&lt;/a&gt;&lt;/p&gt;&#xA;&lt;!-- &lt;div id=&#34;lastfm&#34; aria-live=&#34;polite&#34;&gt;Trying to fetch what i&#39;m listening to 🤘&lt;/div&gt; --&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The design on this site derives its inspiration from these folks: &lt;a href=&#34;https://eatonphil.com&#34;&gt;eatonphil.com&lt;/a&gt;, &lt;a href=&#34;https://matklad.github.io&#34;&gt;matklad.github.io&lt;/a&gt;,&lt;a href=&#34;https://polarhive.net&#34;&gt;polarhive.net&lt;/a&gt;, &lt;a href=&#34;https://rowjee.com&#34;&gt;rowjee.com&lt;/a&gt;, &lt;a href=&#34;https://icyphox.sh&#34;&gt;icyphox.sh&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;</description>
    </item>
    <item>
      <title>par moi</title>
      <link>https://adihegde.com/par moi.html/</link>
      <pubDate>Sat, 24 Feb 2024 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/par moi.html</guid>
      <description>&lt;div class=&#34;image-grid&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - fuji&#34; src=&#34;https://i.imgur.com/tsf7hpA.png&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - swords&#34; src=&#34;https://i.imgur.com/uCECThX.png&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - vinyl&#34; src=&#34;https://i.imgur.com/UeRy28k.png&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - karot&#34; src=&#34;https://i.imgur.com/u0W4Y7G.png&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - kaffee cappuchino&#34; src=&#34;https://i.imgur.com/LH5ENBX.png&#34;&gt;&#xA;&lt;img loaing=&#34;lazy&#34; alt=&#34;piece - relaxx&#34; src=&#34;https://i.imgur.com/nbgm8Qy.png&#34;&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>My first HSP talk</title>
      <link>https://adihegde.com/posts/talks/xkcd-grab-presentation.html/</link>
      <pubDate>Sat, 09 Dec 2023 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/talks/xkcd-grab-presentation.html</guid>
      <description>&lt;p&gt;I recently got the opportunity to take part in the project expo hosted by the club HSP part of PESU ECity campus. As part of this expo, I presented one of my on going projects &lt;a href=&#34;http://github.com/bwaklog/xkcd-grab&#34;&gt;xkcd-grab&lt;/a&gt; in-front of an amazing crowd. So lets get to the actual part of the blog, what this presentation was all about.&lt;/p&gt;&#xA;&lt;p&gt;This relatively small project is somewhat of a playground for me to explore different searching algorithms and querying techniques. While this might have a niche target, I want to build this tool into a more robust API client. The roadmap of this current is to make a smart cli tool to find the most relevant comic based on a search query. The CLI itself is a minimal working tool I wrote with python. Besides using the api, i&#39;ve created several extra features that completely changed original idea of the app.&lt;/p&gt;&#xA;&lt;p&gt;This project begun in 2021, during my college entrance preparations. It started off as a basic API tool that worked with the xkcd api to fetch a comic based on a derised number. Looked cool at the time but was still pretty clunky. Why would you want to search something based on a number. Thats horrible. Well, the cli tool couldn&#39;t do that initially. This is when decided to implement some cool way you can interact with the cli, and find the comic right from your terminal.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fuzzy-finding-with-levenshtine-distance&#34;&gt;Fuzzy finding with levenshtine distance&lt;/h2&gt;&#xA;&lt;p&gt;Once i&#39;ve got my hands on all the data needed, now was the time that I find a way to give the user the queried comic. My goal was to retrieve a comic based on a string, probably a mini description and use vector searching to find the most relevant comic. Seems good on paper, problem was the data. The api didn&#39;t provide any sort of description for over 1000+ comics. And with the limited time of 3 days, along with hours of college work, this approach wasn&#39;t feasible. The only way I could scrape out data would be using and OCR. The images of these comics have far better insight about whats happening thatn the description...mostly because there was nothing available. I will bring this up in a bit while talking about the little easter egg feature.&lt;/p&gt;&#xA;&lt;p&gt;Now the only other option would be to use the titles of the comic. What the task was now is to achieve the best string approximation and provide the user with the 10 best matches. Levenshtein distance out of all the options was the simplest to implement given the time. Thing is I couldn&#39;t get this to work with an implementation that I craeted from defnition of the method to determine the levenshtine ratio. While getting the distance was a simple formula. Finding the ratio of kept me stuck for a while. It worked just fine, but the results didn&#39;t seem to align with premade modules that are supposed to do the same thing. While my results for the ratio were somewhat right, they were off by around 0.2 to 0.3. Turns out, the way fuzzywuzzy calculates the ratio is by using a slightly modified version of this formula.&lt;/p&gt;&#xA;&lt;p&gt;By definition, if &lt;code&gt;l&lt;/code&gt; is the Levenshtein distance, and &lt;code&gt;m&lt;/code&gt; is the length of the longest of the two words, the ratio is given by &lt;code&gt;1-(l/m)&lt;/code&gt;. However in the modified version, the sum of the lengths of the words were used for getting the value.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;def Levi_ratio(a: str, b: str) -&amp;gt; int:&#xA;    d = levi_distance(a, b)&#xA;    l = len(a) + len(b)&#xA;    return 1 - (d/l)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;This was womething that I found out hours before the final presentation. So I had to go ahead with using the prebuilt module, which im not so proud. The results were good but not fully upto my expectation.&lt;/p&gt;&#xA;&lt;p&gt;Here is a small demo of all of these things together. I appologise for the shitty quality of the gif. I yanked them from the presentation, and google slides doesn&#39;t like you downloading concents from a slide :P.&lt;/p&gt;&#xA;&lt;h2 id=&#34;problems-encountered&#34;&gt;Problems encountered&lt;/h2&gt;&#xA;&lt;p&gt;This project would have been a smooth sail if it werent for the big obstacle that I encountered where the data was simply insufficient. As a solution to this, I created a simple web scraper that works neatly along with the pre existing system that I made for the fuzzy finder. Instead of iteracting with the xkcd api, a neat google search querry along with some web scrappign gave some of the best output...I mean what else would I expect. Each xkcd url is in the following format.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;https://xkcd.com/&amp;lt;some number&amp;gt;/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Here is the basic structure of a &lt;code&gt;Comic&lt;/code&gt; class.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;class Comic:&#xA;    self.num        # comic number&#xA;    self.url        # comci url (not the api endpoint)&#xA;    self.title      # comic title&#xA;    self.trans      # comic transcript (missing for over 1000+ comics)&#xA;    self.alt        # comic alt text&#xA;    self.img        # comic image url&#xA;    self.content    # comic content&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The &lt;code&gt;content&lt;/code&gt; is stripped out from the images using googles tessaract OCR engine, which has been made available to python.&lt;/p&gt;&#xA;&lt;p&gt;How this app works is it dumps all the data locally in a csv for quick access in effort to use the api as less as possible. Ofcourse there a ton of comics that need to be retrived. In addition to the api call, running a sequential task of using an OCR to get the data from the comics is way too time consuming, especially when you are handling with anything over 1000s in number. Hence there was a need for a simple parallelisation operation&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;def get_session():&#xA;    if not hasattr(thread_local, &amp;quot;session&amp;quot;):&#xA;        thread_local.session = requests.Session()&#xA;    return thread_local.session&#xA;&#xA;# Returns a list of data in the same order as the csv file&#xA;def get_comic_data(comic_num):&#xA;    comic_data = Comic(num=comic_num) # this neatly give me a Comic object that i can handle&#xA;    # ...&#xA;    print(f&amp;quot;Data for comic {comic_num} fetched sucessfully&amp;quot;)&#xA;    comic_data_nlist.append(data)&#xA;&#xA;&#xA;# Threading function to get all comcis&#xA;def fetch_all_comics(nums_list):&#xA;    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:&#xA;        executor.map(get_comic_data, nums_list)&#xA;&#xA;    print(&amp;quot;++++++ APPENDING &amp;amp; UPDATING COMICS +++++++&amp;quot;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;What was supposed to be a 2 hour job of sequentially handling all the tasks got reduced down to 5 minutes (5 minutes and 23 seconds to be exact :P). This function is automatically called when any operation is called for using the CLI tool. Hence making data available for latest queries as well as for the fuzzy finder.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Hello World</title>
      <link>https://adihegde.com/posts/inked/hello-world.html/</link>
      <pubDate>Fri, 08 Dec 2023 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/posts/inked/hello-world.html</guid>
      <description>&lt;p&gt;I&#39;m not usually great at these things, but I want to give it a try. So here it goes.&lt;/p&gt;&#xA;&lt;p&gt;Hey There! My name is Aditya Hegde and this is my small space on such a vast land of the web. What about me? Well, I&#39;m a &lt;a href=&#34;https://www.urbandictionary.com/define.php?term=College%20Freshman&#34;&gt;freshman&lt;/a&gt; at PES University. Parts of some cool clubs such as &lt;a href=&#34;https://homebrew.hsp-ec.xyz/&#34;&gt;HSP&lt;/a&gt; and &lt;a href=&#34;https://acmpesuecc.github.io/&#34;&gt;ACM&lt;/a&gt; which was my first little family here in college. Besides the stressful parts of it, just the first 6 months alone have shown me a whole new world.&lt;/p&gt;&#xA;&lt;!--[pic of me](https://i.imgur.com/ppTDKQv.jpg)--&gt;&#xA;&lt;p&gt;It&#39;s been a whole semester since I&#39;ve joined college, and I could just go on and on about the number of amazing people I&#39;ve met. It&#39;s like a whole new wave I&#39;ve never experienced. Been part of one of the coolest mentoring teams, mentored in some amazing workshops, and even had the opportunity to have my presentation on one of my projects.&lt;/p&gt;&#xA;&lt;p&gt;This site is special to me. Not only it is the place where I would like to share my work but also it is being generated by &lt;a href=&#34;https://github.com/acmpesuecc/anna&#34;&gt;anna&lt;/a&gt;, which is one of the first big projects I&#39;ve worked on with an amazing team &lt;a href=&#34;https://github.com/anirudhsudhir&#34;&gt;Anirudh&lt;/a&gt;, &lt;a href=&#34;https://github.com/DedLad&#34;&gt;Adhesh&lt;/a&gt; and &lt;a href=&#34;https://github.com/polarhive&#34;&gt;Nathan&lt;/a&gt;. As of now, it&#39;s still a work in progress, and working on it has been great.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;failure doesn&#39;t define a person&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I love learning new stuff. And at the same time, I don&#39;t know what to focus on. So as of now, I&#39;d be lying if I said I&#39;m specifically into some system-level stuff or networking concepts... Whatever it is I&#39;d like to share it, and what better place to do so other than my page. I believe failure does make someone stronger. There are so many physicists out there, great ones who tried but failed to read some conclusions, but ended up with something new, sometimes something revolutionary. There&#39;s so much more to learn.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>404</title>
      <link>https://adihegde.com/404.html/</link>
      <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
      <author>Aditya Hegde</author>
      <guid>https://adihegde.com/404.html</guid>
      <description>&lt;h1 id=&#34;woops-you-seem-to-be-lost-&#34;&gt;Woops, you seem to be lost :)&lt;/h1&gt;&#xA;&lt;figure&gt;&#xA;&lt;img src=&#34;https://i.giphy.com/Ju7l5y9osyymQ.webp&#34; alt=&#34;fun&#34;&gt;&#xA;&lt;/figure&gt;&#xA;</description>
    </item>
  </channel>
</rss>
