<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akshit Zatakia</title>
    <description>The latest articles on DEV Community by Akshit Zatakia (@akshitzatakia).</description>
    <link>https://dev.to/akshitzatakia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F632682%2Fb13c9050-9ab6-4681-bbf3-a26c48d50c8c.png</url>
      <title>DEV Community: Akshit Zatakia</title>
      <link>https://dev.to/akshitzatakia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akshitzatakia"/>
    <language>en</language>
    <item>
      <title>🚀 From Manual Builds to Multi-Platform Magic: How GoReleaser Transformed My OpenTelemetry Sandbox</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sat, 23 Aug 2025 05:49:39 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/from-manual-builds-to-multi-platform-magic-how-goreleaser-transformed-my-opentelemetry-sandbox-h36</link>
      <guid>https://dev.to/akshitzatakia/from-manual-builds-to-multi-platform-magic-how-goreleaser-transformed-my-opentelemetry-sandbox-h36</guid>
      <description>&lt;p&gt;Ever spent hours wrestling with manual builds, creating release archives by hand, and maintaining complex CI/CD pipelines just to ship your Go application? I did too, until I discovered GoReleaser. Let me show you how it transformed my &lt;a href="https://github.com/Akshit-Zatakia/otel-sandbox" rel="noopener noreferrer"&gt;otel-sandbox&lt;/a&gt; project from a maintenance nightmare into a one-command release machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Release Hell 😤
&lt;/h2&gt;

&lt;p&gt;My &lt;strong&gt;&lt;a href="https://github.com/Akshit-Zatakia/otel-sandbox" rel="noopener noreferrer"&gt;otel-sandbox&lt;/a&gt;&lt;/strong&gt; project needed to support multiple platforms - developers use Linux, macOS (both Intel and Apple Silicon), and Windows. My original GitHub workflow was a monster:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;130+ lines of complex matrix builds&lt;/li&gt;
&lt;li&gt;Manual archive creation for each platform&lt;/li&gt;
&lt;li&gt;Inconsistent naming across releases&lt;/li&gt;
&lt;li&gt;Missing Windows support (oops!)&lt;/li&gt;
&lt;li&gt;No checksums or verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every release meant babysitting the CI pipeline and praying nothing broke.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter GoReleaser: The Game Changer 🎯
&lt;/h2&gt;

&lt;p&gt;GoReleaser promised to replace all this complexity with a single configuration file. Skeptical but desperate, I gave it a shot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before vs After
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (GitHub Actions only):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 130+ lines of matrix builds, manual archiving, artifact juggling...&lt;/span&gt;
&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;
        &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;amd64&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux-amd64&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;  
        &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux-arm64&lt;/span&gt;
      &lt;span class="c1"&gt;# ... and so on&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (GoReleaser + GitHub Actions):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Just 30 lines total!&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run GoReleaser&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;goreleaser/goreleaser-action@v5&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;distribution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;goreleaser&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;~&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;v2'&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release --clean&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Real-World Success Stories 🌟
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Hugo - Static Site Generator&lt;/strong&gt;&lt;br&gt;
Challenge: Hugo needed to support 20+ platforms including exotic architectures. Solution: GoReleaser builds for Linux, Windows, macOS, FreeBSD, OpenBSD across amd64, 386, ARM variants. Result: Single goreleaser release creates 40+ platform-specific binaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Hugo's approach&lt;/span&gt;
&lt;span class="na"&gt;builds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;linux&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;darwin&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;windows&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;freebsd&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;openbsd&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;amd64&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;386&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;arm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;arm64&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;darwin&lt;/span&gt;
        &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;386&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Terraform - Infrastructure as Code&lt;/strong&gt;&lt;br&gt;
Challenge: Enterprise users across diverse cloud environments and local machines. Solution: GoReleaser + HashiCorp's signing infrastructure. Result: Secure, verified releases for 15+ platforms with GPG signatures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Kubernetes CLI Tools (kubectl, helm)&lt;/strong&gt;&lt;br&gt;
Challenge: Developers need consistent tooling across laptop, CI, and production environments. Solution: GoReleaser ensures identical behavior across all platforms. Result: "Works on my machine" becomes "works everywhere."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Prometheus Node Exporter&lt;/strong&gt;&lt;br&gt;
Challenge: Monitor diverse server architectures (x86, ARM, MIPS). Solution: GoReleaser builds for embedded systems, servers, and containers. Result: Single monitoring solution across entire infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Docker CLI&lt;/strong&gt;&lt;br&gt;
Challenge: Container orchestration across development and production environments. Solution: GoReleaser creates consistent CLI experience everywhere. Result: Seamless Docker experience from laptop to datacenter.&lt;/p&gt;


&lt;h2&gt;
  
  
  My GoReleaser Configuration
&lt;/h2&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/Akshit-Zatakia/otel-sandbox/blob/main/.goreleaser.yaml" rel="noopener noreferrer"&gt;.goreleaser.yaml&lt;/a&gt; that powers my releases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

&lt;span class="na"&gt;before&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;go mod tidy&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;go generate ./...&lt;/span&gt;

&lt;span class="na"&gt;builds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CGO_ENABLED=0&lt;/span&gt;
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./cmd&lt;/span&gt;
    &lt;span class="na"&gt;binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;otel-sandbox&lt;/span&gt;
    &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;windows&lt;/span&gt;  
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;darwin&lt;/span&gt;

&lt;span class="na"&gt;archives&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tar.gz&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;{{ .ProjectName }}_&lt;/span&gt;
      &lt;span class="s"&gt;{{- title .Os }}_&lt;/span&gt;
      &lt;span class="s"&gt;{{- if eq .Arch "amd64" }}x86_64&lt;/span&gt;
      &lt;span class="s"&gt;{{- else if eq .Arch "386" }}i386&lt;/span&gt;
      &lt;span class="s"&gt;{{- else }}{{ .Arch }}{{ end }}&lt;/span&gt;
      &lt;span class="s"&gt;{{- if .Arm }}v{{ .Arm }}{{ end }}&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;assets/**&lt;/span&gt;  &lt;span class="c1"&gt;# Include config files!&lt;/span&gt;
    &lt;span class="na"&gt;format_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;windows&lt;/span&gt;
        &lt;span class="na"&gt;formats&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;zip&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;changelog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asc&lt;/span&gt;
  &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^docs:"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^test:"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Results:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What GoReleaser generates for each release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;otel-sandbox_Linux_x86_64.tar.gz&lt;/li&gt;
&lt;li&gt;otel-sandbox_Linux_arm64.tar.gz&lt;/li&gt;
&lt;li&gt;otel-sandbox_Darwin_x86_64.tar.gz (macOS Intel)&lt;/li&gt;
&lt;li&gt;otel-sandbox_Darwin_arm64.tar.gz (macOS Apple Silicon)&lt;/li&gt;
&lt;li&gt;otel-sandbox_Windows_x86_64.zip&lt;/li&gt;
&lt;li&gt;otel-sandbox_Windows_arm64.zip&lt;/li&gt;
&lt;li&gt;checksums.txt (SHA256 verification)&lt;/li&gt;
&lt;li&gt;Auto-generated changelog&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Advanced Real-World Patterns
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Multi-Binary Projects&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example: Kubernetes-style project with multiple tools&lt;/span&gt;
&lt;span class="na"&gt;builds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server"&lt;/span&gt;
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./cmd/server&lt;/span&gt;
    &lt;span class="na"&gt;binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-server&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client"&lt;/span&gt; 
    &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./cmd/client&lt;/span&gt;
    &lt;span class="na"&gt;binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used by: Kubernetes (kubectl, kubeadm, kubelet), Istio (istioctl, pilot)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Integration&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example: Container-first deployment&lt;/span&gt;
&lt;span class="na"&gt;dockers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;
    &lt;span class="na"&gt;goarch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;amd64&lt;/span&gt;
    &lt;span class="na"&gt;image_templates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myregistry/myapp:{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Tag&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myregistry/myapp:latest"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used by: Prometheus, Grafana, Jaeger&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Package Managers&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example: Homebrew integration&lt;/span&gt;
&lt;span class="na"&gt;brews&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
    &lt;span class="na"&gt;homepage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/user/myapp"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;awesome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CLI&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tool"&lt;/span&gt;
    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;homebrew-tap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used by: Hugo, Terraform, kubectl&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Benchmarks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Real project comparisons:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Before GoReleaser&lt;/th&gt;
&lt;th&gt;After GoReleaser&lt;/th&gt;
&lt;th&gt;Build Time&lt;/th&gt;
&lt;th&gt;Platforms&lt;/th&gt;
&lt;th&gt;Maintenance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hugo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;45min manual builds&lt;br&gt;6 platforms&lt;br&gt;Custom scripts&lt;/td&gt;
&lt;td&gt;8min automated&lt;br&gt;40+ platforms&lt;br&gt;Single config&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;82% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6→40+&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;90% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Terraform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex matrix builds&lt;br&gt;15+ platforms&lt;br&gt;Manual signing&lt;/td&gt;
&lt;td&gt;One-command release&lt;br&gt;15+ platforms&lt;br&gt;Auto-signed&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;70% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Same coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;kubectl&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Platform-specific CI&lt;br&gt;Manual archives&lt;br&gt;Inconsistent naming&lt;/td&gt;
&lt;td&gt;Unified build process&lt;br&gt;Auto-generated archives&lt;br&gt;Consistent naming&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;65% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8→12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;80% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prometheus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Docker-only releases&lt;br&gt;Limited platforms&lt;br&gt;Manual checksums&lt;/td&gt;
&lt;td&gt;Multi-platform binaries&lt;br&gt;15+ platforms&lt;br&gt;Auto-checksums&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;60% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3→15&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;75% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;My otel-sandbox&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;130 lines CI config&lt;br&gt;6 platforms&lt;br&gt;Manual Windows builds&lt;/td&gt;
&lt;td&gt;30 lines total&lt;br&gt;8 platforms&lt;br&gt;Auto Windows support&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;77% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6→8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;77% less code&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Jaeger&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Separate build scripts&lt;br&gt;Docker-focused&lt;br&gt;Complex release process&lt;/td&gt;
&lt;td&gt;Unified GoReleaser&lt;br&gt;Binaries + Docker&lt;br&gt;Single command&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;55% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4→12&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;70% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Grafana Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-repo complexity&lt;br&gt;Platform inconsistencies&lt;br&gt;Manual coordination&lt;/td&gt;
&lt;td&gt;Single-repo builds&lt;br&gt;Consistent across platforms&lt;br&gt;Automated coordination&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;50% faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6→20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85% less&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Developer Experience Win 🎉
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before GoReleaser:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push code&lt;/li&gt;
&lt;li&gt;Wait for matrix builds&lt;/li&gt;
&lt;li&gt;Debug platform-specific issues&lt;/li&gt;
&lt;li&gt;Manually create release&lt;/li&gt;
&lt;li&gt;Upload artifacts one by one&lt;/li&gt;
&lt;li&gt;Write release notes&lt;/li&gt;
&lt;li&gt;Hope nothing is broken&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After GoReleaser:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git tag v1.0.0-release&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push origin v1.0.0-release&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;☕ Coffee time&lt;/li&gt;
&lt;li&gt;✅ Complete release with all platforms ready&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started in 5 Minutes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install GoReleaser:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   brew &lt;span class="nb"&gt;install &lt;/span&gt;goreleaser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize config:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;goreleaser init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Test locally:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;goreleaser release &lt;span class="nt"&gt;--snapshot&lt;/span&gt; &lt;span class="nt"&gt;--clean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add to GitHub Actions:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;goreleaser/goreleaser-action@v5&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;~&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;v2'&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release --clean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;GoReleaser didn't just simplify my releases - it transformed how I think about distribution. Instead of dreading release day, I now ship with confidence, knowing that every platform gets the same quality experience.&lt;/p&gt;

&lt;p&gt;The numbers speak for themselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hugo: Powers 100k+ websites with zero-friction updates&lt;/li&gt;
&lt;li&gt;Terraform: Trusted by enterprises for infrastructure automation&lt;/li&gt;
&lt;li&gt;Kubernetes tools: Enable container orchestration at global scale&lt;/li&gt;
&lt;li&gt;My otel-sandbox: Reduced CI complexity by 75%, added Windows support effortlessly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're maintaining a Go project and still doing manual releases, you're missing out. GoReleaser isn't just a tool - it's a productivity multiplier that lets you focus on what matters: building great software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it yourself:&lt;/strong&gt; Check out the &lt;a href="https://github.com/Akshit-Zatakia/otel-sandbox" rel="noopener noreferrer"&gt;otel-sandbox repository&lt;/a&gt; to see GoReleaser in action, or start with the &lt;a href="https://goreleaser.com/" rel="noopener noreferrer"&gt;official GoReleaser docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>go</category>
      <category>devops</category>
      <category>cicd</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>🚀 Introducing OTel Sandbox: Your Zero-Config OpenTelemetry Playground</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Mon, 18 Aug 2025 14:35:33 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/introducing-otel-sandbox-your-zero-config-opentelemetry-playground-53d7</link>
      <guid>https://dev.to/akshitzatakia/introducing-otel-sandbox-your-zero-config-opentelemetry-playground-53d7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Stop wrestling with complex OpenTelemetry setups. Start experimenting in seconds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you've ever tried to set up OpenTelemetry for the first time, you know the pain. Multiple components, complex configurations, version compatibility nightmares, and hours spent just to see your first trace. What if I told you there's a better way?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meet OTel Sandbox&lt;/strong&gt; – a developer-first tool that gets you from zero to observability in under 30 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 The Problem Every Developer Faces
&lt;/h2&gt;

&lt;p&gt;Picture this: You want to experiment with OpenTelemetry, but first you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install and configure an OTel Collector&lt;/li&gt;
&lt;li&gt;Set up Jaeger for trace visualization&lt;/li&gt;
&lt;li&gt;Configure Prometheus for metrics&lt;/li&gt;
&lt;li&gt;Write YAML configs for each component&lt;/li&gt;
&lt;li&gt;Debug networking issues between services&lt;/li&gt;
&lt;li&gt;Spend your weekend reading documentation instead of coding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OTel Sandbox eliminates all of this friction.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What Makes OTel Sandbox Special?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🏃‍♂️ Lightning Fast Setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# That's it. Seriously.&lt;/span&gt;
./otel-sandbox up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In 30 seconds, you have a complete observability stack running locally:&lt;br&gt;
✅ OpenTelemetry Collector (configured &amp;amp; running)&lt;br&gt;
✅ Jaeger UI (&lt;a href="http://localhost:16686" rel="noopener noreferrer"&gt;http://localhost:16686&lt;/a&gt;)&lt;br&gt;
✅ Prometheus (&lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt;)&lt;br&gt;
✅ All networking configured automatically&lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 Built-in Verification
&lt;/h2&gt;

&lt;p&gt;Wonder if everything is working? Don't guess:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./otel-sandbox verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sends real telemetry data through your stack and confirms:&lt;br&gt;
✅ Traces are being collected&lt;br&gt;
✅ Metrics are being recorded&lt;br&gt;
✅ Logs are being captured&lt;br&gt;
✅ All exporters are functioning&lt;/p&gt;


&lt;h2&gt;
  
  
  📊 Smart Data Export
&lt;/h2&gt;

&lt;p&gt;View your collected telemetry data in multiple formats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Quick summary view&lt;/span&gt;
./otel-sandbox &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; summary

&lt;span class="c"&gt;# Full JSON export for analysis&lt;/span&gt;
./otel-sandbox &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎛️ Effortless Process Management
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check what's running&lt;/span&gt;
./otel-sandbox status

&lt;span class="c"&gt;# Clean shutdown of all components&lt;/span&gt;
./otel-sandbox down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🧪 Experiment with New SDKs&lt;/strong&gt;&lt;br&gt;
Testing a new language SDK? Spin up OTel Sandbox, point your app at &lt;code&gt;localhost:4317&lt;/code&gt;, and immediately see traces flowing through Jaeger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎓 Learning OpenTelemetry&lt;/strong&gt;&lt;br&gt;
Perfect for workshops, tutorials, or just understanding how the pieces fit together. No complex setup means more time learning concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐛 Debug Integration Issues&lt;/strong&gt;&lt;br&gt;
Having problems with your production OTel setup? Use OTel Sandbox as a known-good reference environment to isolate issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📚 Demo Creation&lt;/strong&gt;&lt;br&gt;
Need to create a demo for your team? OTel Sandbox gives you a reproducible environment that works everywhere.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;🏗️ Architecture That Just Works&lt;/strong&gt;&lt;br&gt;
OTel Sandbox bundles battle-tested components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Your App → OTel Collector → Jaeger &lt;span class="o"&gt;(&lt;/span&gt;traces&lt;span class="o"&gt;)&lt;/span&gt;
                        → Prometheus &lt;span class="o"&gt;(&lt;/span&gt;metrics&lt;span class="o"&gt;)&lt;/span&gt;  
                        → File Export &lt;span class="o"&gt;(&lt;/span&gt;logs&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is pre-configured with sensible defaults, but you can still customize configurations if needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Get Started in 3 Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Download&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download the binary as per your platform (for windows you need to build it manually): &lt;br&gt;
&lt;a href="https://github.com/Akshit-Zatakia/otel-sandbox/releases/tag/v1.0.0-release" rel="noopener noreferrer"&gt;https://github.com/Akshit-Zatakia/otel-sandbox/releases/tag/v1.0.0-release&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Unpack the file&lt;/strong&gt;&lt;br&gt;
Unpack the tar archive and navigate into the extracted folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Launch&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./otel-sandbox-&amp;lt;os&amp;gt;-&amp;lt;&lt;span class="nb"&gt;arch&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Explore&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit &lt;a href="http://localhost:16686" rel="noopener noreferrer"&gt;http://localhost:16686&lt;/a&gt; for Jaeger&lt;/li&gt;
&lt;li&gt;Visit &lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt; for Prometheus&lt;/li&gt;
&lt;li&gt;Run ./otel-sandbox-- verify to see sample data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: If this doesn't work due to restrictions, you can build the binary by clonning this repository and use &lt;code&gt;go build&lt;/code&gt; command&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Pro Tips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Quick Health Check&lt;/strong&gt;&lt;br&gt;
Always run ./otel-sandbox status before starting development to see what's running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean Slate&lt;/strong&gt;&lt;br&gt;
Use ./otel-sandbox down between experiments to ensure clean state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Analysis&lt;/strong&gt;&lt;br&gt;
Export data with ./otel-sandbox export --format json and pipe it to jq for analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./otel-sandbox &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; json | jq &lt;span class="s1"&gt;'.traces[0].resourceSpans[0].scopeSpans[0].spans[0]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔮 What's Coming Next?
&lt;/h2&gt;

&lt;p&gt;We're constantly improving OTel Sandbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Hints Feature (Coming Soon): Intelligent suggestions for optimizing your telemetry setup&lt;/li&gt;
&lt;li&gt;📦 More Export Formats: Prometheus, CSV, and custom formats&lt;/li&gt;
&lt;li&gt;🎨 Enhanced UI: Better visualization of your telemetry pipeline&lt;/li&gt;
&lt;li&gt;🔧 Advanced Configuration: Easy customization for power users&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎉 Join the Community
&lt;/h2&gt;

&lt;p&gt;OTel Sandbox is open source and built by developers, for developers. We'd love your feedback:&lt;/p&gt;

&lt;p&gt;⭐ Star us on GitHub&lt;br&gt;
🐛 Report issues or request features&lt;br&gt;
🤝 Contribute improvements&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Stop Fighting Setup, Start Building
&lt;/h2&gt;

&lt;p&gt;The future of observability is here, and it shouldn't require a PhD in YAML configuration.&lt;/p&gt;

&lt;p&gt;OTel Sandbox gets you from curious about OpenTelemetry to shipping instrumented code in minutes, not hours.&lt;/p&gt;

&lt;p&gt;Ready to transform your observability workflow?&lt;/p&gt;




&lt;p&gt;Built with ❤️ for the developer community. Because your time should be spent building amazing things, not fighting configuration files.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>go</category>
      <category>analytics</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>Demystifying OpenTelemetry: The Ultimate Developer's Guide to Observability 🚀</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Mon, 11 Aug 2025 06:52:10 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/demystifying-opentelemetry-the-ultimate-developers-guide-to-observability-2ogl</link>
      <guid>https://dev.to/akshitzatakia/demystifying-opentelemetry-the-ultimate-developers-guide-to-observability-2ogl</guid>
      <description>&lt;p&gt;In today's microservices-driven world, understanding what's happening inside your applications isn't just helpful—it's &lt;strong&gt;essential&lt;/strong&gt;. Enter &lt;strong&gt;OpenTelemetry&lt;/strong&gt;, the open-source superhero of observability, here to save your day (and your production deployments).&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is OpenTelemetry… and Why Should You Care? 🤔
&lt;/h2&gt;

&lt;p&gt;At its core, &lt;strong&gt;OpenTelemetry&lt;/strong&gt; (often abbreviated &lt;strong&gt;OTel&lt;/strong&gt;) is a vendor-neutral framework for collecting and exporting three vital types of data from your applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📊 Traces&lt;/strong&gt;: Follow a request's journey through your services, from the user's click to the database query&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📈 Metrics&lt;/strong&gt;: Quantify system health—think request rates, error counts, or memory usage
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📝 Logs&lt;/strong&gt;: Capture event snapshots in human-readable form&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why use it?
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;Unified instrumentation&lt;/strong&gt;: One API, SDKs in every popular language, and a single Collector to process all your telemetry&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Vendor freedom&lt;/strong&gt;: Swap backends (Jaeger, Prometheus, Datadog, you name it) without rewriting your instrumentation&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Cloud-native ready&lt;/strong&gt;: Built to shine in containerized, distributed environments&lt;/p&gt;




&lt;h2&gt;
  
  
  Where and How You'll Use OpenTelemetry 🎯
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Picture this:&lt;/strong&gt; you deploy a new feature, and suddenly your latency spikes. Without tracing, you're left guessing. With OpenTelemetry, you…&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instrument your code&lt;/strong&gt;—either automatically or manually—to emit spans, metrics, and logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship data to the Collector&lt;/strong&gt;, which can filter, batch, and enrich before forwarding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visualize and analyze&lt;/strong&gt; in your favorite observability platform&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  You'll find OTel in use cases like:
&lt;/h3&gt;

&lt;p&gt;🔍 Diagnosing performance bottlenecks in microservices&lt;br&gt;&lt;br&gt;
⚡ Monitoring down-to-the-nanosecond latency in serverless functions&lt;br&gt;&lt;br&gt;
🔗 Correlating logs, metrics, and traces to pinpoint root causes  &lt;/p&gt;


&lt;h2&gt;
  
  
  A Fun, Practical Example: Rolling the Dice with Traces! 🎲
&lt;/h2&gt;

&lt;p&gt;Let's build a tiny "Dice Roller" Flask app instrumented with OpenTelemetry. We'll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roll a die&lt;/li&gt;
&lt;li&gt;Tag the player's name (if provided)
&lt;/li&gt;
&lt;li&gt;Observe each roll as a trace in real time&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Quick Start Guide
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Clone the repository&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Akshit-Zatakia/otel-learning.git
&lt;span class="nb"&gt;cd &lt;/span&gt;otel-learning/application-usecase-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create and activate a virtual environment&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate      &lt;span class="c"&gt;# On Windows: venv\Scripts\activate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Install dependencies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
opentelemetry-bootstrap &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Run with Instrumentation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Try It Out!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In another terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:8080/rolldice?player=Alice"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔍 &lt;strong&gt;Watch in your console&lt;/strong&gt; as OTel prints a span for each roll—complete with timing details. Now you can spot if "Alice" rolls more slowly than "Bob" (maybe she's superstitious? 😉).&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Output
&lt;/h3&gt;

&lt;p&gt;You should see JSON traces like this in your console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET /rolldice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"trace_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x5da641262fdb1bbdf1f43a73d838ea0e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"span_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x37f8c4453afbb51a"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SpanKind.SERVER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"http.method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"http.target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/rolldice?player=Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"http.status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-08T10:24:13.732856Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"end_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-08T10:24:13.733273Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why This Rocks for Developers 💪
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;⚡ Instant Gratification&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Zero-code auto-instrumentation means you see telemetry in seconds—no digging through docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;🚀 Portable Insights&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your instrumentation lives with your code. Push to staging or production, and OTel keeps collecting.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;🐛 Debugging Bliss&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Correlate logs, traces, and metrics in one place. No more "It worked on my machine" excuses.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next? 🎯
&lt;/h2&gt;

&lt;p&gt;Ready to dive deeper? Here are some next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔧 &lt;strong&gt;Explore the Collector&lt;/strong&gt;: Centralize and enrich your telemetry pipelines&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Add Custom Metrics&lt;/strong&gt;: Track business KPIs like "widgets sold per minute"&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Integrate with CI/CD&lt;/strong&gt;: Fail builds when latency thresholds spike&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Try Different Backends&lt;/strong&gt;: Export to Jaeger, Grafana, or your favorite observability platform&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Wrapping Up 🎬
&lt;/h2&gt;

&lt;p&gt;OpenTelemetry transforms your chaotic logs-and-dashboards world into a clear, correlated observability story. So roll up your sleeves, instrument a few lines of code, and let OTel illuminate your system's inner workings—&lt;strong&gt;one span at a time&lt;/strong&gt;!&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Akshit-Zatakia/otel-learning" rel="noopener noreferrer"&gt;Sample Code Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>analytics</category>
      <category>opensource</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>Dynamically Updating Streaming Rules in Golang – A Production-Ready Approach</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sun, 09 Feb 2025 14:28:24 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/dynamically-updating-streaming-rules-in-golang-a-production-ready-approach-3290</link>
      <guid>https://dev.to/akshitzatakia/dynamically-updating-streaming-rules-in-golang-a-production-ready-approach-3290</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Kafka is a powerhouse for real-time data streaming, but what if your processing logic needs to change dynamically? Manually redeploying your service every time a rule changes isn’t practical.&lt;/p&gt;

&lt;p&gt;Imagine a system where rules can be updated in real-time without stopping the consumer. In this blog, we'll explore how to consume Kafka messages, update processing rules dynamically, and handle high throughput efficiently in Golang.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Problem Statement
&lt;/h2&gt;

&lt;p&gt;We need a Kafka consumer that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads messages from a rules topic (to update streaming rules dynamically).&lt;/li&gt;
&lt;li&gt;Reads messages from a data topic (to process data based on the latest rules).&lt;/li&gt;
&lt;li&gt;Applies arithmetic operations (sum, minus, multiply, divide) on selected JSON fields.&lt;/li&gt;
&lt;li&gt;Supports high throughput using goroutines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Use Case 🔥&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider an e-commerce platform where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The rules-topic updates the calculation method for order prices.&lt;/li&gt;
&lt;li&gt;The test-topic contains order details (price, tax, discount, etc.).&lt;/li&gt;
&lt;li&gt;The consumer processes orders in real-time based on the current rules.&lt;/li&gt;
&lt;li&gt;The output is sent to another topic for further analytics.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1️⃣ Define the Rule Struct&lt;/strong&gt;&lt;br&gt;
We use a mutex to ensure thread-safe updates of the rule structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;RuleStruct&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mu&lt;/span&gt;        &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RWMutex&lt;/span&gt;
    &lt;span class="n"&gt;Operation&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;   &lt;span class="c"&gt;// sum, minus, multiply, divide&lt;/span&gt;
    &lt;span class="n"&gt;KeyNames&lt;/span&gt;  &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="c"&gt;// Keys to process in test-topic messages&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2️⃣ Convert Values to Float64&lt;/strong&gt;&lt;br&gt;
Since Kafka messages store data as JSON, fields may be &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, or &lt;code&gt;float64&lt;/code&gt;. We normalize them to &lt;code&gt;float64&lt;/code&gt; before applying calculations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;numStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsedNum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsedNum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3️⃣ Processing Kafka Messages Efficiently&lt;/strong&gt;&lt;br&gt;
Processing the messages with go routines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageChan&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt; &lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncProducer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;messageChan&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid JSON in test-topic:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// Get the latest rule&lt;/span&gt;
        &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyNames&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ruleConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c"&gt;// Apply operation on specified keys&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;applyOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Publish result to test-destination-topic&lt;/span&gt;
        &lt;span class="n"&gt;jsonResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProducerMessage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Topic&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;destinationTopic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StringEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonResult&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error sending message to destination topic:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Published processed data:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonResult&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Function to apply the rule logic&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;applyOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;numStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsedNum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numStr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsedNum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"No valid numeric values found"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"sum"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"minus"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"multiply"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"divide"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Division by zero"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Unknown operation"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
        &lt;span class="s"&gt;"operation"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"keys"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4️⃣ Dynamic Rule Updates from Kafka&lt;/strong&gt;&lt;br&gt;
When a new message arrives in the rules-topic, we update our &lt;code&gt;RuleStruct&lt;/code&gt; dynamically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;RuleStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SetRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newOperation&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newKeys&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newOperation&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KeyNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newKeys&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;RuleTopicConsumer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ConsumeClaim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConsumerGroupSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;claim&lt;/span&gt; &lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConsumerGroupClaim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Messages&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ruleData&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ruleData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid JSON in rules-topic:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// Extract rule operation and key names&lt;/span&gt;
        &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opExists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ruleData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;keysInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keysExist&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ruleData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"keynames"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;opExists&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;keysExist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid rule format in rules-topic:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ruleData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;keyNames&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;keysInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;keyNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyNames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c"&gt;// Update global rule struct dynamically&lt;/span&gt;
        &lt;span class="n"&gt;ruleConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Updated Rule =&amp;gt; Operation:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Keys:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Mark message as processed&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarkMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔬 Performance Benchmarking – Sending 100 Messages per Second
&lt;/h2&gt;

&lt;p&gt;We create a producer script to send 1000 messages per second for testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTicker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;messagesPerSec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="c"&gt;// Generate batch of messages&lt;/span&gt;
                &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProducerMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batchSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;batchSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"order_id": "%d", "price": %.2f, "tax": %.2f, "quantity": %d, "cost_per_item": %.2f}`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float64&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float64&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Float64&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProducerMessage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;Topic&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sarama&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StringEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="c"&gt;// Send batch messages asynchronously&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📌 Why This Approach is Production-Ready?
&lt;/h2&gt;

&lt;p&gt;✅ Real-time Rule Updates (No restart required)&lt;br&gt;
✅ Parallel Processing with Goroutines&lt;br&gt;
✅ High Throughput &lt;br&gt;
✅ Handles JSON Data Type Variations&lt;br&gt;
✅ Kafka Producer-Consumer Optimized for Performance&lt;/p&gt;




&lt;h2&gt;
  
  
  🌟 Conclusion
&lt;/h2&gt;

&lt;p&gt;Dynamically updating rules in Kafka consumers without service restarts is a game-changer for real-time applications. By using Golang, Kafka, and worker pools, we built a system that is fast, efficient, and scalable.&lt;/p&gt;

&lt;p&gt;🔹 Check out the Full Code on GitHub: &lt;a href="https://github.com/Akshit-Zatakia/go-stream-pipeline" rel="noopener noreferrer"&gt;Dynamic Kafka Processing in Golang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Got questions or improvements? Drop a comment below! 🚀&lt;/p&gt;

</description>
      <category>go</category>
      <category>kafka</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>Buffered vs Unbuffered Channels in Golang: A Developer's Guide to Concurrency</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Mon, 03 Feb 2025 16:28:51 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/buffered-vs-unbuffered-channels-in-golang-a-developers-guide-to-concurrency-3m75</link>
      <guid>https://dev.to/akshitzatakia/buffered-vs-unbuffered-channels-in-golang-a-developers-guide-to-concurrency-3m75</guid>
      <description>&lt;p&gt;Concurrency is one of the most powerful features of Go (Golang), and channels are at the heart of it. Channels allow goroutines to communicate and synchronize their execution. However, not all channels are created equal. In this blog, we’ll dive deep into buffered and unbuffered channels, explore their differences, and provide practical examples to help you understand when and how to use them effectively.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Channels in Go?
&lt;/h2&gt;

&lt;p&gt;Channels are a typed conduit through which you can send and receive values between goroutines. They are the primary mechanism for managing concurrency in Go. Channels can be either &lt;strong&gt;buffered&lt;/strong&gt; or &lt;strong&gt;unbuffered&lt;/strong&gt;, and understanding the distinction between the two is crucial for writing efficient and bug-free concurrent programs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Unbuffered Channels: Synchronous Communication
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;unbuffered channel&lt;/strong&gt; has no capacity to hold data. It operates on a strict "send and receive" synchronization model. When a goroutine sends a value to an unbuffered channel, it blocks until another goroutine receives the value. Similarly, a receive operation blocks until a value is sent to the channel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Unbuffered Channels&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Unbuffered channel&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending value to channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="c"&gt;// Send value to channel&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value sent!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Simulate delay&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receiving value from channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Receive value from channel&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value received:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Sending value to channel...
Receiving value from channel...
Value received: a
Value sent!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sender goroutine blocks until the receiver is ready.&lt;/li&gt;
&lt;li&gt;Unbuffered channels ensure &lt;strong&gt;synchronous communication&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use unbuffered channels when you need guaranteed synchronization between goroutines.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Buffered Channels: Asynchronous Communication
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;buffered channel&lt;/strong&gt; has a fixed capacity to hold data. Sending to a buffered channel only blocks when the buffer is full, and receiving blocks only when the buffer is empty. This allows for more flexible communication patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Buffered Channels&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Buffered channel with capacity of 2&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending value 1 to channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="c"&gt;// Send value to channel&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 1 sent!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending value 2 to channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"k"&lt;/span&gt; &lt;span class="c"&gt;// Send another value to channel&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 2 sent!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending value 3 to channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"s"&lt;/span&gt; &lt;span class="c"&gt;// This will block because the buffer is full&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 3 sent!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// This won't execute until space is available&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Simulate delay&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receiving value 1 from channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;val1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Receive value from channel&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 1 received:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receiving value 2 from channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;val2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Receive another value from channel&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 2 received:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receiving value 3 from channel..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;val3&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Receive the third value from channel&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value 3 received:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Sending value 1 to channel...
Value 1 sent!
Sending value 2 to channel...
Value 2 sent!
Sending value 3 to channel...
Receiving value 1 from channel...
Value 1 received: a
Receiving value 2 from channel...
Value 2 received: k
Receiving value 3 from channel...
Value 3 received: s
Value 3 sent!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sender goroutine only blocks when the buffer is full.&lt;/li&gt;
&lt;li&gt;Buffered channels allow for &lt;strong&gt;asynchronous communication&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use buffered channels when you want to decouple senders and receivers or handle bursts of data.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visualizing Buffered vs Unbuffered Channels
&lt;/h2&gt;

&lt;p&gt;To better understand the difference, let’s visualize how data flows in both types of channels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unbuffered Channel Diagram&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8571jf714emtc2w6ue0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8571jf714emtc2w6ue0u.png" alt="Unbuffered channel" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The arrow represents the synchronization point. Both goroutines must be ready for the data transfer to occur.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Buffered Channel Diagram&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4pdit3tf4oe6lyzpdon6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4pdit3tf4oe6lyzpdon6.png" alt="Buffered Channel" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The buffer acts as a temporary storage, allowing the sender and receiver to operate independently until the buffer is full or empty.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When to Use Buffered vs Unbuffered Channels?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unbuffered Channels&lt;/th&gt;
&lt;th&gt;Buffered Channels&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Use when you need strict synchronization.&lt;/td&gt;
&lt;td&gt;Use when you want to decouple senders and receivers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ideal for handshake-like communication.&lt;/td&gt;
&lt;td&gt;Ideal for handling bursts of data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Simpler to reason about.&lt;/td&gt;
&lt;td&gt;Requires careful handling to avoid deadlocks.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices for Using Channels
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Deadlocks&lt;/strong&gt;: Ensure that every send operation has a corresponding receive operation, especially with unbuffered channels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose Buffer Size Wisely&lt;/strong&gt;: For buffered channels, choose a buffer size that balances memory usage and performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use&lt;/strong&gt; select &lt;strong&gt;for Multiplexing&lt;/strong&gt;: Use the select statement to handle multiple channels efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Close Channels Gracefully&lt;/strong&gt;: Use close() to signal that no more data will be sent, and handle it properly in receivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the difference between buffered and unbuffered channels is essential for writing efficient and scalable concurrent programs in Go. Unbuffered channels provide strict synchronization, while buffered channels offer more flexibility. By choosing the right type of channel for your use case, you can harness the full power of Go’s concurrency model.&lt;/p&gt;




&lt;p&gt;Feel free to experiment with the examples provided and explore how channels can simplify your concurrent programming tasks. Happy coding! 🚀&lt;/p&gt;

</description>
      <category>go</category>
      <category>concurrency</category>
      <category>bufferedchannels</category>
      <category>coding</category>
    </item>
    <item>
      <title>Boost Your Java Development: Speed Up Maven Builds with mvnd</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Thu, 30 Jan 2025 10:20:37 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/boost-your-java-development-speed-up-maven-builds-with-mvnd-2203</link>
      <guid>https://dev.to/akshitzatakia/boost-your-java-development-speed-up-maven-builds-with-mvnd-2203</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Introduction
&lt;/h2&gt;

&lt;p&gt;As Java developers, we all know the pain of long build times when using Apache Maven. Every time we run mvn clean install, the JVM starts from scratch, dependencies are reloaded, and the build process feels sluggish. But what if I told you there's a way to turbocharge your Maven builds and cut down wait times drastically?&lt;/p&gt;

&lt;p&gt;Enter mvnd (Maven Daemon) — a game-changing tool that dramatically speeds up Maven builds by running a persistent daemon in the background. If you’re tired of slow builds and want to boost productivity, this blog is for you! 🎯&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ What is mvnd?
&lt;/h2&gt;

&lt;p&gt;mvnd (Maven Daemon) is a high-performance version of Apache Maven designed to eliminate build overhead. It speeds up builds by keeping a background JVM daemon running, reusing classloaders, and executing tasks in parallel.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Traditional Maven (mvn) starts a new JVM process for each build, leading to startup delays.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maven Daemon (mvnd) keeps a persistent JVM and reuses it, reducing execution time significantly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 If you use Maven, you should be using mvnd!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 How Does &lt;code&gt;mvnd&lt;/code&gt; Make Builds Lightning Fast?
&lt;/h2&gt;

&lt;p&gt;Let’s break down how &lt;code&gt;mvnd&lt;/code&gt; achieves its speed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1️⃣ Daemon Process (No More JVM Startup Overhead)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each time you run &lt;code&gt;mvn&lt;/code&gt;, a fresh JVM starts, loads dependencies, and then shuts down. &lt;code&gt;mvnd&lt;/code&gt; eliminates this overhead by keeping a long-running daemon process, drastically cutting down build times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2️⃣ Parallel Execution (Faster Multi-Module Builds)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvnd&lt;/code&gt; runs tasks in parallel across multiple CPU cores, optimizing multi-module projects. Unlike traditional Maven, which processes modules sequentially, &lt;code&gt;mvnd&lt;/code&gt; uses a dependency graph to determine independent tasks that can be executed simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3️⃣ Classloader &amp;amp; Dependency Caching (No More Repeated Loading)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Maven loads dependencies every time a new build starts. &lt;code&gt;mvnd&lt;/code&gt; caches these dependencies in memory, so subsequent builds don’t need to reload them, making incremental builds faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4️⃣ Built on Quarkus (Optimized for Speed)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Quarkus-based architecture makes mvnd incredibly lightweight, further improving performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5️⃣ Smart Process Management (Automatic Daemon Recycling)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvnd&lt;/code&gt; automatically restarts the daemon when needed, ensuring memory leaks don’t slow things down.&lt;/p&gt;

&lt;p&gt;It optimizes task scheduling, minimizing idle time between dependent tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 How to Install &amp;amp; Use &lt;code&gt;mvnd&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Ready to supercharge your Maven builds? Follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Step 1: Install &lt;code&gt;mvnd&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can install &lt;code&gt;mvnd&lt;/code&gt; easily using below tools or by downloading it manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install using SDKMAN!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk install mvnd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install using Homebrew&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install mvndaemon/homebrew-mvnd/mvnd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install using MacPorts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo port install mvnd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other installation ways are mentioned in their &lt;a href="https://github.com/apache/maven-mvnd" rel="noopener noreferrer"&gt;official site&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Step 2: Run mvnd&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once installed, simply replace mvn with mvnd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvnd clean install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 Enjoy the massive speed boost in your builds!&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Performance Comparison: mvn vs mvnd
&lt;/h2&gt;

&lt;p&gt;Here’s a real-world test on a multi-module Maven project which is &lt;a href="https://github.com/spring-petclinic/spring-petclinic-microservices" rel="noopener noreferrer"&gt;pet-clinic&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;code&gt;mvn&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1g40pz9rxypkr8e8ilxc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1g40pz9rxypkr8e8ilxc.png" alt="Using mvn" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;code&gt;mvnd&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnl8lnamvfkc8gaj1st2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnl8lnamvfkc8gaj1st2f.png" alt="Using mvnd" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Result: mvnd is 4x faster than traditional Maven! 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Should You Use mvnd?
&lt;/h2&gt;

&lt;p&gt;If you’re using Apache Maven, the answer is a resounding YES! 🔥&lt;/p&gt;

&lt;p&gt;✅ Massively faster builds 🚀&lt;/p&gt;

&lt;p&gt;✅ No more waiting for JVM startup ⏳&lt;/p&gt;

&lt;p&gt;✅ Parallel execution for better CPU utilization ⚙️&lt;/p&gt;

&lt;p&gt;✅ Fully compatible with existing Maven projects 🔄&lt;/p&gt;

&lt;p&gt;The best part? You don’t need to modify your Maven projects—just switch from mvn to mvnd and enjoy the speed boost! 💨&lt;/p&gt;




&lt;h2&gt;
  
  
  📢 Final Thoughts: Get More Done in Less Time
&lt;/h2&gt;

&lt;p&gt;As developers, our time is precious. Why waste it waiting for slow builds when you can make them 4x faster?&lt;/p&gt;

&lt;p&gt;With mvnd, you can:&lt;/p&gt;

&lt;p&gt;🚀 Ship features faster&lt;/p&gt;

&lt;p&gt;💻 Boost productivity&lt;/p&gt;

&lt;p&gt;⏳ Reduce waiting time&lt;/p&gt;

&lt;p&gt;I’ve never seen such a boost in build speed! 💪🔥 If you know of any tools that are even more efficient, drop them in the comments—let’s discuss and benchmark them! 😁&lt;/p&gt;

&lt;p&gt;Happy coding! 👨‍💻🚀&lt;/p&gt;

</description>
      <category>java</category>
      <category>devops</category>
      <category>softwaredevelopment</category>
      <category>coding</category>
    </item>
    <item>
      <title>EasyJSON: Supercharge JSON Performance in Go</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Thu, 23 Jan 2025 17:23:50 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/easyjson-supercharge-json-performance-in-go-28</link>
      <guid>https://dev.to/akshitzatakia/easyjson-supercharge-json-performance-in-go-28</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Why EasyJSON Stands Out
&lt;/h2&gt;

&lt;p&gt;JSON serialization and deserialization are at the heart of many Go applications, from web servers to microservices. While Go’s encoding/json package is reliable, it often struggles with performance when processing large data structures.&lt;/p&gt;

&lt;p&gt;That’s where EasyJSON comes into play. Designed for speed and low memory consumption, EasyJSON generates serialization code at compile time, eliminating runtime reflection overhead. In this blog, we’ll explore how EasyJSON works, compare it to other libraries, and demonstrate why it’s a game-changer for performance-hungry applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Choose EasyJSON for JSON Serialization?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Outperforms Go’s standard library and most third-party solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Runtime Reflection&lt;/strong&gt;: Generates static code, avoiding costly reflection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight&lt;/strong&gt;: Reduces memory allocations significantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility&lt;/strong&gt;: Works seamlessly with existing Go structs.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Getting Started with EasyJSON
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mailru&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;easyjson&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mailru&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;easyjson&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure gopath is in your PATH for generating code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GOPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/Users/&amp;lt;username&amp;gt;/go
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$GOPATH&lt;/span&gt;/bin:&lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generating Code for Your Structs&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define your Go struct:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;  

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;ID&lt;/span&gt;   &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;  
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;  
    &lt;span class="n"&gt;Age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"age"`&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Generate EasyJSON code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;easyjson &lt;span class="nt"&gt;-all&lt;/span&gt; user.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates user_easyjson.go, containing optimized serialization methods for your struct.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code Example: Using EasyJSON in Your Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;  

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;  
    &lt;span class="s"&gt;"github.com/mailru/easyjson"&lt;/span&gt;  
&lt;span class="p"&gt;)&lt;/span&gt;  

&lt;span class="c"&gt;//easyjson:json  &lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;ID&lt;/span&gt;   &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;  
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;  
    &lt;span class="n"&gt;Age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"age"`&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="c"&gt;// Serialize&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;easyjson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Serialized JSON:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  

    &lt;span class="c"&gt;// Deserialize  &lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;deserialized&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;easyjson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;deserialized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deserialized Struct:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deserialized&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Benchmarking EasyJSON vs. Alternatives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;br&gt;
We compared EasyJSON with encoding/json and json-iterator using a struct with nested fields and lists.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/Akshit-Zatakia/go-easyjson-benchmark" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; which has the code for benchmarking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Results&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Library         | Serialization (ns/op) | Deserialization (ns/op) | Allocations (B/op) | Allocations (#) |
|-----------------|-----------------------|--------------------------|--------------------|------------------|
| `encoding/json` | 13,000               | 14,000                  | 1,500              | 15               |
| `json-iterator` | 8,500                | 9,200                   | 800                | 10               |
| **EasyJSON**    | **4,500**            | **4,800**               | **100**            | **1**            |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: EasyJSON is up to 3x faster than encoding/json and minimizes memory allocations dramatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison: EasyJSON vs. Other JSON Libraries
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Feature                   | `encoding/json` | `json-iterator` | **EasyJSON**   |
|---------------------------|-----------------|-----------------|----------------|
| Reflection-Free           | ✗               | ✗               | ✅             |
| Performance               | Medium          | High            | **Very High**  |
| Memory Efficiency         | Medium          | High            | **Very High**  |
| Code Generation Required? | ✗               | ✗               | ✅             |
| API Simplicity            | ✅               | ✅               | ✅             |

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When Should You Use EasyJSON?
&lt;/h2&gt;

&lt;p&gt;EasyJSON is ideal for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;High-throughput APIs requiring low-latency serialization.&lt;/li&gt;
&lt;li&gt;Memory-constrained environments where allocations must be minimized.&lt;/li&gt;
&lt;li&gt;Applications where compile-time code generation is acceptable.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Caveats of Using EasyJSON
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Generation&lt;/strong&gt;: Requires an extra step in your build process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance&lt;/strong&gt;: Any changes to structs necessitate regenerating EasyJSON code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;EasyJSON is a powerful tool for developers seeking unmatched performance and efficiency in JSON processing. While it introduces some overhead in terms of code generation, the benefits far outweigh the drawbacks in performance-critical applications.&lt;/p&gt;

&lt;p&gt;If speed and memory efficiency matter to your Go projects, it’s time to give EasyJSON a spin! 🚀&lt;/p&gt;




&lt;p&gt;Do you use EasyJSON or another library? Share your experiences in the comments below!&lt;/p&gt;

</description>
      <category>go</category>
      <category>jsonserialization</category>
      <category>performance</category>
    </item>
    <item>
      <title>AI Can Now Dream 💭</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sun, 19 Jan 2025 08:51:11 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/ai-can-now-dream-2nfa</link>
      <guid>https://dev.to/akshitzatakia/ai-can-now-dream-2nfa</guid>
      <description>&lt;p&gt;Imagine a world where artificial intelligence (AI) doesn’t just follow orders but dreams of new possibilities. It imagines its own structure, redesigns itself, and learns faster than ever. This isn’t science fiction—this is the promise of Neural Architecture Search (NAS), a groundbreaking field of AI research. &lt;/p&gt;

&lt;p&gt;Let’s dive into this fascinating idea of AI dreaming about its own architecture and how it’s changing the way we think about machine learning.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does It Mean for AI to "Dream"?
&lt;/h2&gt;

&lt;p&gt;Think of AI as a sculptor designing its tools. Neural networks are the building blocks of AI, like chisels and hammers for a sculptor. Traditionally, humans decide the size, shape, and function of these tools—adding layers, choosing activation functions, and determining connections.&lt;/p&gt;

&lt;p&gt;With NAS, it experiments, evaluates, and optimizes its own design to better perform tasks. In essence, it dreams of new architectures and brings them to life.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is AI’s Dreaming Important?
&lt;/h2&gt;

&lt;p&gt;For years, humans painstakingly designed neural networks by trial and error. NAS changes the game by automating this process. Here’s why this matters:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Efficiency:&lt;/strong&gt; NAS discovers optimized architectures faster than humans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Innovation:&lt;/strong&gt; It uncovers unconventional designs that outperform human-made models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessibility:&lt;/strong&gt; By automating design, NAS lowers the barrier for creating state-of-the-art AI models.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Does NAS Work?
&lt;/h2&gt;

&lt;p&gt;Let’s simplify NAS with a fun analogy. Imagine AI as a chef dreaming of the perfect cake recipe. Here’s how it works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Search Space&lt;/strong&gt;&lt;br&gt;
The chef decides the ingredients to experiment with—flour, sugar, butter, and chocolate. In NAS, this search space includes neural network components like layers, activation functions, and connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Search Algorithm&lt;/strong&gt;&lt;br&gt;
The chef tries different combinations of ingredients. Some are random; others are guided by past experiences. Similarly, NAS uses algorithms like random search, reinforcement learning, or evolutionary strategies to test architectures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Evaluation&lt;/strong&gt;&lt;br&gt;
After baking each cake, taste-testers rate it. In NAS, models are tested for accuracy, speed, and efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Optimization&lt;/strong&gt;&lt;br&gt;
The chef refines the recipe based on feedback. NAS iteratively improves architectures to achieve the best results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Example
&lt;/h2&gt;

&lt;p&gt;Here’s an example of NAS in action:&lt;/p&gt;

&lt;p&gt;🚗 &lt;strong&gt;Self-Driving Cars&lt;/strong&gt;: Designing neural networks for processing sensor data and making real-time decisions is complex. NAS has created architectures that improve safety and efficiency, making autonomous driving a reality.&lt;/p&gt;




&lt;h2&gt;
  
  
  How NAS Is Transforming AI
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Democratizing AI:&lt;/strong&gt; Open-source tools and benchmarks make NAS accessible to developers worldwide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-Disciplinary Applications:&lt;/strong&gt; From healthcare to finance, NAS is optimizing AI models across industries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speeding Up Research:&lt;/strong&gt; By automating network design, researchers can focus on solving real-world problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: The Dawn of Dreaming AI
&lt;/h2&gt;

&lt;p&gt;AI’s ability to dream through NAS marks a turning point in technology. It’s no longer a tool but a creator, reshaping its own limits and unlocking possibilities we haven’t yet imagined.&lt;/p&gt;

&lt;p&gt;So, the next time you hear about a groundbreaking AI system, remember—it might just be the result of AI dreaming its way to perfection.&lt;/p&gt;

&lt;p&gt;Let's discuss more on the comments and yes, AI won't be taking over jobs anytime soon but these are the new technologies that are being developed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>techinnovation</category>
    </item>
    <item>
      <title>OTP Authentication: The Passwordless Superhero of Your App! 🦸‍♂️✨</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sun, 05 Jan 2025 10:53:59 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/otp-authentication-the-passwordless-superhero-of-your-app-1pih</link>
      <guid>https://dev.to/akshitzatakia/otp-authentication-the-passwordless-superhero-of-your-app-1pih</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ever felt like passwords are your kryptonite?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
We’ve all been there. Forgetting passwords, trying to create the perfect combo of letters, numbers, and symbols. Then there’s the “forgot password” reset loop that makes you want to throw your phone into the ocean. 😤&lt;/p&gt;

&lt;p&gt;Well, fret no more, because OTP authentication is here to save the day! Forget passwords and embrace the magic of One-Time Passwords (OTPs)—the true passwordless superhero your app needs.&lt;/p&gt;


&lt;h2&gt;
  
  
  What is OTP Authentication?
&lt;/h2&gt;

&lt;p&gt;OTP (One-Time Password) authentication is exactly what it sounds like—a magical password that’s valid for only one single login attempt. When users try to log in, instead of entering a password, they’ll receive an OTP via email (or SMS). This OTP is like a secret key that grants access for a brief time—secure, easy, and oh-so-convenient.&lt;/p&gt;

&lt;p&gt;But wait, OTP is only the beginning of the superhero saga! We pair it with Access Tokens and Refresh Tokens, creating an even more powerful and secure way to keep users safe while making login easy-breezy. 🌬️&lt;/p&gt;


&lt;h2&gt;
  
  
  How Does OTP Authentication Work?
&lt;/h2&gt;

&lt;p&gt;Let’s break it down with a simple example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: The Magic Request 🪄&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You (the user) open up your favorite app, let’s say it’s SuperApp.
Instead of asking for your password, the app simply asks for your email address. You enter it in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: The OTP Arrives 📨&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app sends a magical OTP (something like 123456) to your email. This code is valid for a limited time—usually a few minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: The OTP Entered 🧑‍💻&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You open your inbox, grab that OTP, and enter it into the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Access Granted! 🎉&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app verifies the OTP and—BOOM! You’re in, no password needed!
In the backend, the app generates an Access Token, which is like a VIP badge for you to use the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: The Power of Refresh Tokens 🔄&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What if your Access Token expires (after 15 minutes, for example)? Don’t worry! The Refresh Token will keep you logged in and grant you a fresh Access Token without needing to ask for a new OTP.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;"Spring Boot: Like a magical kitchen, where the ingredients are already prepared, you just need to assemble them—no need to break a sweat! 🍳"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Code: The Nuts and Bolts of OTP + JWT Authentication
&lt;/h2&gt;

&lt;p&gt;Let’s dive into some of the key snippets from the GitHub repository to make things super simple&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Generate OTP and Send via Email&lt;/strong&gt;&lt;br&gt;
We generate an OTP and send it to the user's email. Here's the magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateOTP&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SecureRandom&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SecureRandom&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Generates a random digit (0-9)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EmailDto&lt;/span&gt; &lt;span class="n"&gt;emailDto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SimpleMailMessage&lt;/span&gt; &lt;span class="n"&gt;simpleMailMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleMailMessage&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;simpleMailMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emailDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTo&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;simpleMailMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emailDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;simpleMailMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emailDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;javaMailSender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simpleMailMessage&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. OTP Verification and JWT Token Generation&lt;/strong&gt;&lt;br&gt;
Once the user enters the OTP, we verify it and generate JWT tokens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;TokenResponseDto&lt;/span&gt; &lt;span class="nf"&gt;generateToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LoginCode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loginCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loginCodeRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getExpirationTime&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isBefore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LocalDateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvalidDataException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid or expired code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User not found"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Generate JWT&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setClaims&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"roles"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRoles&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"sub"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;ACCESS_TOKEN_EXPIRATION_TIME&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;refreshToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;REFRESH_TOKEN_EXPIRATION_TIME&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Remove the used login token&lt;/span&gt;
    &lt;span class="n"&gt;loginCodeRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;TokenResponseDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Token Refreshing&lt;/strong&gt;&lt;br&gt;
If the access token expires, we use the refresh token to issue a new access token without requiring the user to re-enter the OTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;TokenResponseDto&lt;/span&gt; &lt;span class="nf"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Claims&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parserBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSigningKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseClaimsJws&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User not found!"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;newToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setClaims&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"roles"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRoles&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"sub"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;ACCESS_TOKEN_EXPIRATION_TIME&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;TokenResponseDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UnauthorizedAccessException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unauthorized access!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Role-Based Access Control&lt;/strong&gt;&lt;br&gt;
Now, let's add some roles to make our authentication even more interesting. A system with roles ensures that only specific users can access particular resources. For example, Admin users may have access to modify user data, while Regular users can just view their data.&lt;/p&gt;

&lt;p&gt;Here’s how we implement roles:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Assign Roles to JWT Tokens&lt;/strong&gt;&lt;br&gt;
When generating the access token, we can include the user's roles within the token as claims. Let's say we have two roles: ADMIN and USER. The ADMIN role has higher privileges, and the USER role has limited access.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setClaims&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"roles"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRoles&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"sub"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loginCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;ACCESS_TOKEN_EXPIRATION_TIME&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Extract Roles from JWT Tokens&lt;/strong&gt;&lt;br&gt;
When a user makes a request, we can extract their roles from the JWT token to determine if they have access to a specific endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Claims&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parserBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSigningKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseClaimsJws&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"roles"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Use Roles to Control Access to APIs (RBAC)&lt;br&gt;
Now that we have the roles, we can apply role-based access control (RBAC) to protect certain API endpoints. For example, only ADMINs can access admin APIs, while USERs can access user-specific data.&lt;/p&gt;

&lt;p&gt;In Spring Security, we can configure role-based access like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@PreAuthorize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hasAuthority('USER')"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserDto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;UserDto&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
&lt;span class="nd"&gt;@PreAuthorize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hasAuthority('ADMIN')"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserDto&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUsers&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Pros of OTP Authentication (The Good Stuff!)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;No More Passwords! 🙌&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forget trying to remember a password! OTPs are simple, secure, and easy to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stronger Security 💪&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-time-use codes make hacking or phishing attempts virtually useless.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quick &amp;amp; Easy 🚀&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logging in is a breeze—just check your email, enter the code, and you’re in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Refresh Tokens = Long-Term Access🔄&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refresh Tokens make your login experience even smoother by keeping you logged in without the need to re-enter codes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Cons (Every Superhero Has a Weakness)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Relies on Email Access 📧&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you can’t access your email, you can’t log in! Always keep your inbox handy!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Token Interception Risk ⚠️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If someone intercepts your Refresh Token, they could potentially gain access. Always use HTTPS and ensure proper security measures!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Final Thoughts: OTP Authentication = The Passwordless Future!
&lt;/h2&gt;

&lt;p&gt;So there you have it! OTP Authentication is like a passwordless superhero that swoops in to save your app and its users. By pairing OTPs with Access Tokens and Refresh Tokens, you create a smooth, secure, and seamless login experience.&lt;/p&gt;

&lt;p&gt;Say goodbye to remembering complex passwords and hello to the future of easy, magic-like authentication. 🪄✨&lt;/p&gt;

&lt;p&gt;If you haven’t already, it’s time to embrace OTP and leave the password struggles behind. Your users (and your app) will thank you! 🙏&lt;/p&gt;




&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;

&lt;p&gt;You can find the full code and setup for this OTP + JWT authentication in my GitHub repo: &lt;a href="https://github.com/Akshit-Zatakia/authentication-via-email" rel="noopener noreferrer"&gt;OTP Authentication with JWT Example&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Let’s Discuss!
&lt;/h2&gt;

&lt;p&gt;Do you have suggestions, feedback, or new ideas for improving OTP authentication? Let me know in the comments below!&lt;/p&gt;

&lt;p&gt;Feel free to share this blog with your network and let others join the passwordless revolution. 🚀&lt;/p&gt;

&lt;p&gt;Looking forward to your thoughts! 🙌&lt;/p&gt;

</description>
      <category>security</category>
      <category>otpauthentication</category>
      <category>passwordlesslogin</category>
      <category>springboot</category>
    </item>
    <item>
      <title>The Traffic Cop of the Internet: A Fun Guide to Load Balancers</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sat, 14 Dec 2024 14:29:31 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/the-traffic-cop-of-the-internet-a-fun-guide-to-load-balancers-3li3</link>
      <guid>https://dev.to/akshitzatakia/the-traffic-cop-of-the-internet-a-fun-guide-to-load-balancers-3li3</guid>
      <description>&lt;h2&gt;
  
  
  What Is a Load Balancer (and Why You Should Care)?
&lt;/h2&gt;

&lt;p&gt;Imagine you’re hosting a party and everyone’s lining up at the same food stall. Chaos, right? Now imagine you have multiple food stalls, and a party planner directing guests to the stall with the shortest line. That’s basically what a load balancer does for your website or application—it’s the ultimate party planner for your servers!&lt;/p&gt;

&lt;p&gt;In tech terms, a load balancer is like a traffic cop for incoming network requests. It ensures these requests are evenly distributed across multiple servers so that no single server gets overwhelmed. The result? A faster, smoother, and more reliable experience for your users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is a Load Balancer So Important?
&lt;/h2&gt;

&lt;p&gt;Let’s face it—no one likes a crashed app or a slow-loading website. Without a load balancer, all traffic would go to one poor, overworked server that’ll eventually throw in the towel. Here’s why load balancers are a game-changer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No More Server Meltdowns&lt;/strong&gt;: By distributing traffic, a load balancer prevents servers from getting overwhelmed and keeps your application running smoothly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always Open for Business&lt;/strong&gt;: If one server decides to take a vacation (a.k.a. goes down), the load balancer redirects traffic to healthy servers, ensuring users don’t notice a thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Room to Grow&lt;/strong&gt;: Adding more servers to handle increased traffic? A load balancer ensures that new servers fit seamlessly into the system, like adding more hands to a busy kitchen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Load Balancing Algorithms
&lt;/h2&gt;

&lt;p&gt;Load balancers don’t just blindly throw traffic at servers. They follow clever algorithms to decide where to send each request. Let’s explore three popular ones—with easy, relatable examples:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Round Robin
&lt;/h4&gt;

&lt;p&gt;This one’s like dealing out playing cards in a card game. The load balancer distributes requests one by one to each server in a circular fashion.&lt;/p&gt;

&lt;p&gt;Example: Imagine a pizza delivery service. Each delivery driver gets assigned one order at a time, in turn, until all drivers are busy. Simple and fair, right?&lt;/p&gt;

&lt;p&gt;Best For: Servers with roughly equal capacity and speed.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Least Connections
&lt;/h4&gt;

&lt;p&gt;Here, the load balancer looks for the server with the fewest active connections and sends the next request there. It’s like finding the line at the grocery store with the fewest people—you’ll get served faster.&lt;/p&gt;

&lt;p&gt;Example: Picture a bank with multiple tellers. The load balancer (branch manager) directs you to the teller with the shortest queue.&lt;/p&gt;

&lt;p&gt;Best For: Scenarios where some servers may handle tasks faster than others.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Least Response Time
&lt;/h4&gt;

&lt;p&gt;This is like picking the fastest checkout line. The load balancer checks which server responds the quickest and sends the request there.&lt;/p&gt;

&lt;p&gt;Example: Think of rideshare apps. You’re matched with the driver who can reach you the fastest, not just the nearest one.&lt;/p&gt;

&lt;p&gt;Best For: When speed is the top priority.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Load Balancer’s Job, Simplified:
&lt;/h2&gt;

&lt;p&gt;Let’s summarize it with a quirky scenario:&lt;/p&gt;

&lt;p&gt;You own a bakery that’s booming with customers (yay!). You have three cashiers, and a manager (your load balancer) directing customers to the shortest line.&lt;/p&gt;

&lt;p&gt;If customers arrive in order, the manager uses Round Robin.&lt;/p&gt;

&lt;p&gt;If some lines move faster, the manager chooses Least Connections.&lt;/p&gt;

&lt;p&gt;If a cashier is known to be super quick, the manager opts for Least Response Time.&lt;/p&gt;

&lt;p&gt;No stressed-out cashiers, no long lines, and happy customers leaving with their cakes—win-win!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why You Should Trust the Party Planner
&lt;/h2&gt;

&lt;p&gt;Whether you’re running a small blog or a global app like Netflix, a load balancer ensures everything runs like clockwork. It gives your servers room to breathe, keeps your users happy, and helps your business grow without breaking a sweat.&lt;/p&gt;

&lt;p&gt;So, next time you’re scaling your application, think of the load balancer as the unsung hero—making sure your servers never drop the ball (or the cake, or the pizza, or... you get it).&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Load Balancer in Go (Real-World Application!)
&lt;/h2&gt;

&lt;p&gt;If you’re a developer, you’ll be thrilled to know that building a load balancer isn’t rocket science. I recently created a load balancer in Golang, leveraging Go’s powerful concurrency and simplicity. Here’s an overview of how it works:&lt;/p&gt;

&lt;h4&gt;
  
  
  Concurrency for Handling Requests:
&lt;/h4&gt;

&lt;p&gt;Using Go’s goroutines, the load balancer can handle multiple incoming requests simultaneously, making it highly efficient and scalable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation of Algorithms:
&lt;/h4&gt;

&lt;p&gt;I implemented Round Robin, Least Connections, and Least Response Time algorithms in Go to decide where to route incoming requests. For example:&lt;/p&gt;

&lt;p&gt;Round Robin uses a counter to track the next server.&lt;/p&gt;

&lt;p&gt;Least Connections checks a map of active connections for each server.&lt;/p&gt;

&lt;p&gt;Least Response Time periodically pings servers to determine their speed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Health Checks:
&lt;/h4&gt;

&lt;p&gt;The load balancer continuously monitors the health of servers (using HTTP pings) to ensure it’s only routing traffic to available servers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Extensibility:
&lt;/h4&gt;

&lt;p&gt;Written in Go, the load balancer is modular, making it easy to add more features like SSL termination, logging, or advanced algorithms.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/Akshit-Zatakia/load-balancer" rel="noopener noreferrer"&gt;Github link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>loadbalancing</category>
      <category>applicationscaling</category>
      <category>devops</category>
      <category>go</category>
    </item>
    <item>
      <title>Mastering Flink Streaming: A Practical Guide to Word Counting for Beginners in Big Data</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Sun, 14 Jan 2024 18:56:14 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/mastering-flink-streaming-a-practical-guide-to-word-counting-for-beginners-in-big-data-31jm</link>
      <guid>https://dev.to/akshitzatakia/mastering-flink-streaming-a-practical-guide-to-word-counting-for-beginners-in-big-data-31jm</guid>
      <description>&lt;p&gt;Hey, fellow programmers! After delving into the world of streaming and getting a glimpse of Flink in our previous articles, your curiosity has likely piqued, and you're itching to dive into Flink coding. Well, buckle up because we're about to embark on our first Flink coding adventure: a basic word-counting program. Fire up your favorite IDE and Docker to effortlessly set up and plunge into the realm of streaming with just a few keystrokes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazqhee79nby8j3cyikjk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazqhee79nby8j3cyikjk.png" alt="Intellij" width="361" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word Count Streaming Program:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this program, we'll tally up repeated words in a sentence. For instance, in the sentence "Hello, I am Akshit, and I will perform streaming," the word "I" is repeated, and our program will highlight that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 17&lt;/li&gt;
&lt;li&gt;Flink 1.18&lt;/li&gt;
&lt;li&gt;IntelliJ&lt;/li&gt;
&lt;li&gt;Socket terminal (For Mac, the command is: nc -lk 9999)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start, create a Maven Java project with Flink dependencies installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;mvn&lt;/span&gt; &lt;span class="nl"&gt;archetype:&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nc"&gt;DarchetypeGroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flink&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nc"&gt;DarchetypeArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;flink&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quickstart&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nc"&gt;DarchetypeVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.18&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll use Flink's DataStream API, and the following line marks the beginning of our streaming journey:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;StreamExecutionEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StreamExecutionEnvironment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExecutionEnvironment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read data from a socket like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;DataStream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;socketTextStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's utilize the powerful flatMap function in Flink to transform our data streams. This function allows us to unnest elements, filter elements based on custom logic, and modify elements individually.&lt;/p&gt;

&lt;p&gt;Create a custom flatMap function to split the words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tokenizer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;FlatMapFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Tuple2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Collector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\W+"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Tuple2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's sum the repeated words and create a DataStream object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;DataStream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tuple2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Tokenizer&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keyBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, print/sink the output in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute the Flink streaming job with the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Word count streaming"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the complete program on &lt;a href="https://github.com/Akshit-Zatakia/flink-streaming/tree/main/word-count-streaming" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Explore the results of the output and witness the streaming magic unfold.&lt;/p&gt;

&lt;p&gt;Input of the data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e1jc5jcsqhn5x0ltc9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e1jc5jcsqhn5x0ltc9c.png" alt="Terminal" width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output from the streaming engine:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttou1y70m11s44umz8rg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttou1y70m11s44umz8rg.png" alt="result" width="566" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;p&gt;In this hands-on session, we implemented the word count program to grasp the basics of streaming with Flink. The journey doesn't end here; stay tuned as we delve into more advanced Flink concepts in the upcoming articles. Keep up with me, show some love to the blog, and let the data streaming continue! 🚀💻&lt;/p&gt;

</description>
      <category>apacheflink</category>
      <category>streaming</category>
      <category>bigdata</category>
      <category>java</category>
    </item>
    <item>
      <title>Mastering Stream Processing: Explore Apache Flink's Wonders in Real-Time Data Magic!</title>
      <dc:creator>Akshit Zatakia</dc:creator>
      <pubDate>Fri, 05 Jan 2024 04:53:12 +0000</pubDate>
      <link>https://dev.to/akshitzatakia/mastering-stream-processing-explore-apache-flinks-wonders-in-real-time-data-magic-2heg</link>
      <guid>https://dev.to/akshitzatakia/mastering-stream-processing-explore-apache-flinks-wonders-in-real-time-data-magic-2heg</guid>
      <description>&lt;p&gt;Hello, fellow wildlife enthusiasts and coding critters! Today, we're embarking on a wild journey into the animal kingdom of streaming data, led by none other than the majestic Apache Flink. Just like how animals have their unique strengths and features, Flink brings its own magic to the streaming realm. So, grab your virtual binoculars, and let's explore the wonders of Apache Flink with a twist of animal flair!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtfu8rznkxwdhooni72w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtfu8rznkxwdhooni72w.png" alt="Wild Life" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Unleashing the Magic: Apache Flink in the Animal Kingdom
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Meet Apache Flink, the Stream Safari Guide:&lt;/strong&gt;&lt;br&gt;
Imagine Apache Flink as the wise safari guide of the animal kingdom, ready to navigate the roaring rivers and dense forests of streaming data. Much like how Flink effortlessly handles real-time events, our guide understands the importance of timing in the wild.&lt;/p&gt;




&lt;h2&gt;
  
  
  Flink's Stripes - Key Features:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Clever Chameleon - Event Time Processing:&lt;/strong&gt;&lt;br&gt;
Flink is a clever chameleon, adapting to the flow of time in the animal kingdom. With event time processing, it understands when events occurred, just like a predator tracking its prey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6j9aejg4wul9l9yhqi8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6j9aejg4wul9l9yhqi8.png" alt="Clever Chameleon" width="540" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elephant Memory - Stateful Computations:&lt;/strong&gt;&lt;br&gt;
Flink boasts an elephant-like memory, perfect for stateful computations. Just as elephants remember crucial details, Flink can maintain and update state across events, ensuring a seamless flow of information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctnqrt3x9h56r8idqdil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctnqrt3x9h56r8idqdil.png" alt="Elephant memory" width="260" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ant's Resilience - Fault Tolerance:&lt;/strong&gt;&lt;br&gt;
Just like an ant colony bounces back from challenges, Flink embraces fault tolerance. It can handle disruptions gracefully, ensuring the survival of the streaming ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvt2l46y5jhbi26zhum2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvt2l46y5jhbi26zhum2.png" alt="Ant's Resilience" width="800" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monarch Butterfly's Journey - Exactly-Once Semantics:&lt;/strong&gt;&lt;br&gt;
Similar to a monarch butterfly's migration, Flink ensures exactly-once processing semantics. This means no duplicated or lost messages, offering a reliable journey through the data migration routes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47nrrloxbyee9227byjt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47nrrloxbyee9227byjt.png" alt="Monarch Butterfly" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multilingual Parrot - Rich Set of APIs:&lt;/strong&gt;&lt;br&gt;
Flink is like a multilingual parrot, speaking Java, Scala, and Python. Its rich set of APIs allows animals of all kinds (developers, that is!) to communicate seamlessly in their preferred language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freqigw6tl06ijj2s6tro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freqigw6tl06ijj2s6tro.png" alt="Multilingual Parrot" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Navigating the Animal Kingdom: Advantages and Disadvantages of the Flink Safari
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cheetah's Speed - Low Latency:&lt;br&gt;
Flink, like a cheetah, processes data at lightning speed, making it perfect for applications that demand quick insights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chameleon's Adaptability - Flexibility in State Management:&lt;br&gt;
Flink's adaptability, like a chameleon changing colors, shines through in its stateful computations, offering flexibility in handling diverse streaming scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Savannah Harmony - Unified Processing Model:&lt;br&gt;
Flink provides a harmonious model for both batch and stream processing, resembling the balanced ecosystem of the savannah.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Learning Curve - The Monkey Bars:&lt;br&gt;
Just like monkeys swinging on branches, mastering Flink might feel like navigating the jungle gym. The learning curve can be challenging for newcomers to the streaming safari.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hippo's Appetite - Resource Intensiveness:&lt;br&gt;
While a hippo's appetite is impressive, Flink's scalability can be resource-intensive. It requires a well-prepared environment for optimal performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Animal Kingdom Size - Community Support:&lt;br&gt;
Flink's community, like an animal kingdom, might not be as vast as some other frameworks. This could affect the availability of community support and resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;As we wrap up our safari through the animal kingdom of streaming data, Apache Flink stands tall as the mighty guide, leading us through the wild waters and dense forests. With its animalistic features and streaming prowess, Flink is a force to be reckoned with. So, join the Flink safari, and let the streaming adventures continue in the magical world of big data! 🐾🦓🚀&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
