<?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>Forem: Rishabh Gupta</title>
    <description>The latest articles on Forem by Rishabh Gupta (@zeerorg).</description>
    <link>https://forem.com/zeerorg</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%2F50212%2Faacb6627-cdd4-4e6e-b468-83181b8fb22a.jpeg</url>
      <title>Forem: Rishabh Gupta</title>
      <link>https://forem.com/zeerorg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/zeerorg"/>
    <language>en</language>
    <item>
      <title>Build Multi-Arch docker images on Travis</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Fri, 01 Mar 2019 13:25:22 +0000</pubDate>
      <link>https://forem.com/zeerorg/build-multi-arch-docker-images-on-travis-5428</link>
      <guid>https://forem.com/zeerorg/build-multi-arch-docker-images-on-travis-5428</guid>
      <description>&lt;p&gt;&lt;em&gt;Read the post on my &lt;a href="https://blog.zeerorg.site/post/multi-arch-docker-travis"&gt;blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lot of people are shipping applications as docker images so that they can run in a container. Docker has first class support for multiple architectures and if you are trying to add support for different platforms to your app, you might have come across the problem of automating this process. The pain point is the fact that most hosted CI services like travis and circle only provide amd64 environment.&lt;/p&gt;

&lt;p&gt;But some projects do ship out constantly updated docker images for different architectures and they don't do so manually. Let's take a look at the official docker images for golang (&lt;a href="https://github.com/docker-library/golang"&gt;repo&lt;/a&gt;), in the README you'll see that they use Travis, Appveyor and Jenkins. Jenkins is used to build arm images, but it is a self hosted service and hence not our goal. Another approach is using &lt;a href="https://cloud.drone.io/"&gt;drone cloud&lt;/a&gt; as a ci service, since they have arm servers which can be used to build docker images. But if you don't want to change the current CI service you &lt;strong&gt;were&lt;/strong&gt; out of luck.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don't need physical ARM servers
&lt;/h2&gt;

&lt;p&gt;You can run a program compiled for ARM on amd64 linux machine if it has &lt;a href="https://www.kernel.org/doc/html/v4.18/admin-guide/binfmt-misc.html"&gt;&lt;code&gt;binfmt_misc&lt;/code&gt;&lt;/a&gt; support. It essentially allows you to run a program without worrying about which architecture it was built for. &lt;code&gt;binfmt_misc&lt;/code&gt; doesn't come by default in ubuntu, but adding it is really easy using docker.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set &lt;code&gt;dist: xenial&lt;/code&gt; to &lt;code&gt;.travis.yml&lt;/code&gt; since I've found that binfmt_misc mount, errors out on ubuntu precise which is the default travis distro.&lt;/li&gt;
&lt;li&gt;Add the following block to travis config:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;before_install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sudo docker run --privileged linuxkit/binfmt:v0.6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This single command mounts binfmt_misc to the os &lt;code&gt;/proc/sys/fs&lt;/code&gt; directory. Now our build server has superpowers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Buildkit for building docker images
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/moby/buildkit"&gt;Buildkit&lt;/a&gt; is a toolkit for building container images, it is used in docker and many other places and is advertised to be quite fast. It has a client-server architecture and you'll need to start the server and then use the client to interact with it. There is a fantastic &lt;a href="https://asciinema.org/a/GYOx4B88r272HWrLTyFwo156s"&gt;demo&lt;/a&gt; on building multi-arch docker images by &lt;a href="https://github.com/tonistiigi"&gt;Tõnis Tiigi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our process will goes like this, first we'll start the buildkit server as a container process, then we'll copy the &lt;code&gt;buildctl&lt;/code&gt; binary which the command line frontend for buildkit to our &lt;code&gt;/usr/bin&lt;/code&gt; directory and then we'll set &lt;code&gt;BUILDKIT_HOST&lt;/code&gt; environment variable. Finally, before_install block will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;before_install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sudo docker run --privileged linuxkit/binfmt:v0.6&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sudo docker run -d --privileged -p 1234:1234 --name buildkit moby/buildkit:latest --addr tcp://0.0.0.0:1234 --oci-worker-platform linux/amd64 --oci-worker-platform linux/armhf&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sudo docker cp buildkit:/usr/bin/buildctl /usr/bin/&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export BUILDKIT_HOST=tcp://0.0.0.0:1234&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We specify &lt;code&gt;--addr&lt;/code&gt; to buildkit server to bind it to the specified port and address, we also give &lt;code&gt;--oci-worker-platform&lt;/code&gt; argument to tell the buildkit server that our machine can be used to create images for these platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Images
&lt;/h2&gt;

&lt;p&gt;We can now finally write the script to build images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PLATFORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm &lt;span class="c"&gt;# equivalent to armhf&lt;/span&gt;
&lt;span class="nv"&gt;DOCKERFILE_LOCATION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./Dockerfile.armhf"&lt;/span&gt;
&lt;span class="nv"&gt;DOCKER_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"someone"&lt;/span&gt;
&lt;span class="nv"&gt;DOCKER_IMAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"some_server"&lt;/span&gt;
&lt;span class="nv"&gt;DOCKER_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"latest"&lt;/span&gt;

buildctl build &lt;span class="nt"&gt;--frontend&lt;/span&gt; dockerfile.v0 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--frontend-opt&lt;/span&gt; &lt;span class="nv"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--frontend-opt&lt;/span&gt; &lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKERFILE_LOCATION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--exporter&lt;/span&gt; image &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--exporter-opt&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker.io/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IMAGE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TAG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--exporter-opt&lt;/span&gt; &lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--local&lt;/span&gt; &lt;span class="nv"&gt;dockerfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--local&lt;/span&gt; &lt;span class="nv"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command has a few options, we'll go over them one by one&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;--frontend dockerfile.v0&lt;/code&gt; specifies which frontend to use with buildkit, there is also a &lt;code&gt;gateway.v0&lt;/code&gt; frontend, but we'll stick with dockerfile.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--frontend-opt&lt;/code&gt;, this is used to pass parameters to the fronend used.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;platform&lt;/code&gt; specifies the platform we want to build the image for, these are listed &lt;a href="https://github.com/containerd/containerd/blob/a69a0b0192f647aff8730e493f2da622eb0fd13d/platforms/platforms.go#L88"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filename&lt;/code&gt; specifies the filename of Dockerfile to be used equivalent to docker build's &lt;code&gt;-f&lt;/code&gt; argument.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--exporter image&lt;/code&gt; specifies the export plugin to be used, there are also &lt;code&gt;oci&lt;/code&gt; and &lt;code&gt;local&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; is the url of the registry to push docker images to.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;push&lt;/code&gt; can be set to &lt;code&gt;true&lt;/code&gt; to push the built docker images.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Pushing manifest - Final Step to Multi-Arch
&lt;/h2&gt;

&lt;p&gt;A container manifest is a file that contains data about a container image. We can create a manifest which points to images for different architectures so that when using the image on a particular architecture the docker automatically pulls the desired image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w5etfg89--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://zeerorgprocessedblog.blob.core.windows.net/photos/container-manifest.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w5etfg89--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://zeerorgprocessedblog.blob.core.windows.net/photos/container-manifest.png" alt="Kubernetes Setting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating manifest is an experimental Docker-cli feature and you should update docker for good measure. Add following lines to .travis.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;addons&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker-ce&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First we create the manifest, then we annotate the manifest and finally do a push. For this example let us take the user to be "someone" and docker image to be "my-image" with the tag "latest" i.e the image is "someone/my-image:latest", PLATFORM_1 and PLATFORM_2 are two different platforms for which we need to create the multi arch image. The commands look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;enabled

docker manifest create someone/my-image:latest &lt;span class="se"&gt;\&lt;/span&gt;
            someone/my-image:latest-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_1&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            someone/my-image:latest-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_2&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

docker manifest annotate someone/my-image:latest someone/my-image:latest-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_1&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--arch&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_1&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
docker manifest annotate someone/my-image:latest someone/my-image:latest-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_2&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--arch&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PLATFORM_2&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

docker manifest push someone/my-image:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you ahve successfully automated the creation and push of multiarch docker images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding points
&lt;/h2&gt;

&lt;p&gt;I added multi-arch support to &lt;a href="https://github.com/zeerorg/cron-connector"&gt;cron-connector&lt;/a&gt; and was able to remove armhf specific config files as well as automate the pushing of armhf images. You can find my commit &lt;a href="https://github.com/zeerorg/cron-connector/commit/9c219366fd1898c9a7749fda55b0d36cf6a67e15"&gt;here&lt;/a&gt;. Also, mad props to &lt;a href="https://github.com/johanneswuerbach"&gt;Johannes Würbach&lt;/a&gt; who's Grafana PR &lt;a href="https://github.com/grafana/grafana/pull/14617"&gt;#14617&lt;/a&gt; was where I picked up the &lt;code&gt;binfmt_misc&lt;/code&gt; part and to buildkit team for creating a really nice piece of software.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>raspberrypi</category>
      <category>ci</category>
    </item>
    <item>
      <title>Develop with kubernetes on Docker Desktop with WSL</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Tue, 12 Feb 2019 09:01:05 +0000</pubDate>
      <link>https://forem.com/zeerorg/develop-with-kubernetes-on-docker-desktop-with-wsl-21mh</link>
      <guid>https://forem.com/zeerorg/develop-with-kubernetes-on-docker-desktop-with-wsl-21mh</guid>
      <description>&lt;p&gt;Docker Desktop for Windows comes shipped with kubernetes out of the box. It preconfigures a lot of stuff on your Windows machine, like downloads kubectl and puts everything in PATH variable, so that it can be accessed from powershell. But a lot of developers have took a liking to WSL which provides a more linux native environment for development. This post will go through steps to set up kubernetes for wsl.&lt;/p&gt;

&lt;p&gt;You should have docker for desktop installed and WSL enabled to follow along.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable kubernetes&lt;/strong&gt; if you haven't done so already. Go to docker desktop settings -&amp;gt; Kubernetes tab -&amp;gt; check "Enable Kubernetes" setting. After status says "kubernetes is running" run the following command in powershell.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it shows &lt;code&gt;docker-for-desktop&lt;/code&gt; then it means kubernetes is running correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Fenable-k8s-docker-desktop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Fenable-k8s-docker-desktop.png" alt="Kubernetes Setting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open WSL console and &lt;strong&gt;install kubectl&lt;/strong&gt; using the following commands
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; apt-transport-https
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://packages.cloud.google.com/apt/doc/apt-key.gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add -
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb https://apt.kubernetes.io/ kubernetes-xenial main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/apt/sources.list.d/kubernetes.list
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; kubectl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Setting up kubeconfig file&lt;/strong&gt;: This is the magic step, kubernetes runs on port 6443 on your host computer and to access it you'll need a kubeconfig file. This is already done by docker for the windows environment but for WSL you'll need to grab the config. Turns out it's pretty easy. Just run the following command in bash and replace {username} with your windows username (not the WSL user name)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /mnt/c/Users/&lt;span class="o"&gt;{&lt;/span&gt;username&lt;span class="o"&gt;}&lt;/span&gt;/.kube/config ~/.kube/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command copies your kubeconfig file from windows to wsl.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;All done&lt;/strong&gt;: Just run
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to see a &lt;code&gt;docker-for-desktop&lt;/code&gt; node.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>wsl</category>
      <category>docker</category>
    </item>
    <item>
      <title>React hooks and their dependence on each other</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Sun, 27 Jan 2019 14:01:20 +0000</pubDate>
      <link>https://forem.com/zeerorg/react-hooks-and-their-dependence-on-each-other-13pe</link>
      <guid>https://forem.com/zeerorg/react-hooks-and-their-dependence-on-each-other-13pe</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my &lt;a href="https://blog.zeerorg.site/post/react-hooks-dependence"&gt;blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Pretty much everyone knows about react hooks already. From react docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hooks are an upcoming feature that lets you use state and other React features without writing a class&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One very notable difference between hooks and classes is that there can be multiple state variables and you are not limited to fiddling with a single state object. This obviously provides greater separation of concerns and more composability for effects inside a component, but if done wrong it can introduce weird bugs. We'll look at some pointers that might help you with dealing that complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching data depending on some state variable
&lt;/h2&gt;

&lt;p&gt;This is the most common case of state dependence. You want to fetch some data, that depends on a state variable. For example: Getting different quotes based on some user input. I'll go ahead and give you the code sample (view on &lt;a href="https://codesandbox.io/s/92klk88mqr"&gt;CodeSandbox&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;inp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setInp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setQuote&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GetQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inp&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// This is important&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;inp&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setInp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;You'll see that the &lt;code&gt;useEffect&lt;/code&gt; hook has the second argument as an array which contains a single value, the state variable it depends on. This effectively tells useEffect to be triggered only when the state changes. This is a basic skeleton of how you can chain hooks in a sane way. You can add more states and effects to this components and chain them using this method so they don't clash with each other.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a case of "Effects depending on state"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fetching data is only a simple effect, other types of effects like manipulating DOM nodes or updating a server can be done in a similar manner. The state variable can be something like the position of the cursor or it can even be something obtained from a hook library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't call hooks in nested scope
&lt;/h2&gt;

&lt;p&gt;This has been said a lot of times before, but I should just say it again. Hooks are impure and their behavior in nested scopes is undefined. Below are some tips to shift the scope.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For conditional effects, rely on the second useEffect argument and comparing the values inside the effect itself.&lt;/li&gt;
&lt;li&gt;Similarly, for effects in a loop, shift the loop in the effect callback scope.&lt;/li&gt;
&lt;li&gt;Always initialize state with a default value and don't put it in condtional scope.&lt;/li&gt;
&lt;li&gt;Set the state as an array or object instead of initializing states in a loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  This is not the end
&lt;/h2&gt;

&lt;p&gt;These are somethings I keep in mind while using hooks. You'll encounter and discover a lot more patterns from your use of hooks, when you do, please share them with the rest of the community.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Displaying a Series of Posts</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Thu, 10 Jan 2019 13:16:40 +0000</pubDate>
      <link>https://forem.com/zeerorg/displaying-a-series-of-posts-3o43</link>
      <guid>https://forem.com/zeerorg/displaying-a-series-of-posts-3o43</guid>
      <description>&lt;p&gt;&lt;em&gt;I originally published this post on my &lt;a href="https://blog.zeerorg.site/post/adding-series-to-blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is another feature that I didn't have in mind at the start. I was inspired by dev's series feature and I even created my first ever series, this is the fourth post in that series. The tech / casual / major sections on the &lt;a href="https://blog.zeerorg.site/" rel="noopener noreferrer"&gt;front page&lt;/a&gt; are gone, they were taking up valuable space and I'm pretty sure instead of sorting out the posts they added to the confusion.&lt;/p&gt;

&lt;p&gt;One of the big reasons I wanted to add this is because of what I'm working on as the next series of posts. I don't want to spoil the fun so I won't tell what I'm exactly working on but the posts would need to be tied together coherently to make better sense.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Facaq65f16a2zcjdudxyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Facaq65f16a2zcjdudxyh.png" alt="Screenshot of the blog with series"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev's series are limited
&lt;/h2&gt;

&lt;p&gt;I took the concept of series from dev.to but I found the implementation fits greatly in dev but not so on my blog. So, I came up with a more comprehensive design which when implemented fitted perfectly on my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes to Content Management System
&lt;/h2&gt;

&lt;p&gt;I've talked briefly about my content management system in the previous post in the series. I've wanted to keep things on this blog as simple as possible and push most of the complexity towards the frontend which is the major processing layer in the architecture. Keeping things simple, my content management system has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main.json&lt;/code&gt; : Contains metadata for all the posts.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog-development-live-preview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filename&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LivePreviewBlogChanges&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tech&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tldr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Adding live preview of changes when I'm writing the blog.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Live Preview Blog Edits&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1544608657&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev_to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to/zeerorg/live-preview-blog-edits-2oh1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;series&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this-blog-series&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frontend-caching&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filename&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FrontEndCaching&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tech&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tldr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A simple trick to improve site performance with frontend caching&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Caching data in frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timestamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1545049130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev_to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to/zeerorg/caching-data-in-frontend-3973&lt;/span&gt;&lt;span class="dl"&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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;html/&lt;/code&gt; : Contains the markdown content compiled to html.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;series.json&lt;/code&gt; : Contains details about the series and list of posts in that series.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this-blog-series&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this-blog-architecture&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog-development-live-preview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rss-feed-azure-functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;adding-series-to-blog&lt;/span&gt;&lt;span class="dl"&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;I introduced a new &lt;code&gt;series.json&lt;/code&gt; so that the frontend stays compliant with the existing &lt;code&gt;main.json&lt;/code&gt; and I don't have to calculate the posts in the series on frontend which would be more complex and error prone. I found a middle ground between backend and frontend complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization sacrifices
&lt;/h2&gt;

&lt;p&gt;I'll admit my frontend caching design is not the most optimized approach. The 2 main costly operations are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sending a network request everytime I fetch from cache&lt;/strong&gt;. The render prop component &lt;a href="https://github.com/zeerorg/BlogSite/blob/master/src/Components/GetContent.jsx" rel="noopener noreferrer"&gt;&lt;code&gt;GetContent&lt;/code&gt;&lt;/a&gt; which is responsible for caching and loading data from backend, initially acquires data from cache and also sends a request to the backend to fetch the latest data. This "update on new" caching provides better experience to viewers, as they get the latest updates instantly without closing the browser session but also don't have to wait for the network request to complete to get the first render.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parsing the text to JSON, everytime I need to access metadata&lt;/strong&gt;. Everytime there's a need to fetch &lt;code&gt;main.json&lt;/code&gt;, &lt;code&gt;GetContent&lt;/code&gt; makes the call, hence only the raw text version is returned which is parsed using &lt;code&gt;JSON.Parse&lt;/code&gt; utility. The only way to prevent this is to introduce Redux or maintain a global variable for the data. This would also mean treating json data and html data differently and the responsibility will fall on the shoulders of &lt;code&gt;GetContent&lt;/code&gt; and any component which fetches the data. This increase in complexity will certainly won't help much when compared to single render time, since the parse is called only once per render.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Even with some sacrifices, the project has scaled with the addition of a new feature without giving a headache, I'd consider this an achievement. I'm also really happy with how this feature turned out to be and I'm looking forward for your feedback.&lt;/p&gt;

</description>
      <category>blog</category>
      <category>react</category>
      <category>caching</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Sharing your apps with the world for 5$</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Fri, 04 Jan 2019 07:20:26 +0000</pubDate>
      <link>https://forem.com/zeerorg/sharing-your-apps-with-the-world-for-5-1p80</link>
      <guid>https://forem.com/zeerorg/sharing-your-apps-with-the-world-for-5-1p80</guid>
      <description>&lt;p&gt;Raspberry Pi is a bit underpowered to compete with a full server, no doubt about it, but a lot of our hobby apps which don't ever see the light of the internet, or our test projects which are not ready for the cloud world are the best match with this tiny marvel. You learn a lot about how servers work and get a project hosted on internet, for the cheapest price possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I run on my Raspberry Pi
&lt;/h2&gt;

&lt;p&gt;I currently have an &lt;a href="https://docs.openfaas.com/"&gt;OpenFaas&lt;/a&gt; instance running on my Raspberry Pi serving two applications, first a Github Webhook endpoint and second a Password generator based on &lt;a href="https://www.eff.org/dice"&gt;EFF list&lt;/a&gt;.  OpenFaas runs over Docker swarm which I manage using a &lt;a href="https://www.portainer.io/"&gt;Portainer&lt;/a&gt; ui also running as Docker container. I monitor resource usage with &lt;a href="https://nicolargo.github.io/glances/"&gt;Glances&lt;/a&gt; server. I plan on adding a &lt;a href="https://jupyterhub.readthedocs.io/en/stable/"&gt;Jupyter Hub&lt;/a&gt; instance and putting all of this behind an NGINX proxy server possibly with auth.&lt;/p&gt;

&lt;p&gt;Yes, my setup is a bit too overkill for a small machine like raspberry pi, but it has taught me a lot of things about a lot of different software and possibilities of this tiny monster.&lt;/p&gt;

&lt;p&gt;You can access the password generator on this &lt;a href="https://home.zeerorg.site:3333/"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;5$ Raspberry Pi&lt;/li&gt;
&lt;li&gt;Domain Name (Optional but highly recommended for https)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Diagram Time
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aHLqhAnR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://zeerorgprocessedblog.blob.core.windows.net/photos/rpiserver.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aHLqhAnR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://zeerorgprocessedblog.blob.core.windows.net/photos/rpiserver.jpg" alt="Home server setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse proxy - because, Security
&lt;/h2&gt;

&lt;p&gt;Setting up a reverse proxy server might seem like a bit of a pain but it provides a secure gateway as exposing your home network and your applications on the internet is always a risk. You can also use it to setup SSL if you have a domain. I prefer Nginx simply because it has a lot of guides and is simple to setup (Apache's config scares me). Simple HTTP reverse proxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
  listen 443&lt;span class="p"&gt;;&lt;/span&gt;
  location / &lt;span class="o"&gt;{&lt;/span&gt;
    proxy_pass http://locahost:[:PORT]/&lt;span class="p"&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;Deploying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/nginx/sites-enabled/default
&lt;span class="c"&gt;# Copy the config then Ctrl+x to save&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-s&lt;/span&gt; reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also see: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-nginx-for-ubuntu-14-04"&gt;SSL with nginx&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Correctly starting your applications
&lt;/h2&gt;

&lt;p&gt;The second biggest mistake you can make after ignoring security, is assuming that your raspberry pi will be running most of the time, and if it reboots, you'll just start your services again. Don't make this mistake, setting up a self starting service is trivial and its the best that you can do for your peace of mind. Refer &lt;a href="https://www.raspberrypi.org/documentation/linux/usage/systemd.md"&gt;this official Raspbian guide&lt;/a&gt; on setting up a self starting service.&lt;/p&gt;

&lt;p&gt;app.service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;My Applicaiton
&lt;span class="nv"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;network.target

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/python3 &lt;span class="nt"&gt;-u&lt;/span&gt; main.py
&lt;span class="nv"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/pi/applicaiton
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pi

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Copy and enable service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;app.service /etc/systemd/system/app.service
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start app.service
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;app.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  ARM has come a long way
&lt;/h2&gt;

&lt;p&gt;Another concern which people have before going and hosting their service is that it'll be a pain to build for a different architecture, or they'll have to submit to satan to get their application running. It was the case few years back, but not anymore! Building your application for different architecture is as easy as providing a build time flag for compiled languages, or installing the interpreted languages runtime. Interpreted languages like python and javascript can be easily installed using existing package manager.&lt;/p&gt;

&lt;p&gt;Statically compiled languages can be cross compiled for ARM on your current machine. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Golang: &lt;code&gt;env GOOS=linux GOARCH=arm GOARM=5 go build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;.NET Core: &lt;code&gt;dotnet publish -r linux-arm&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>raspberrypi</category>
      <category>server</category>
      <category>hobby</category>
      <category>deploy</category>
    </item>
    <item>
      <title>Adding RSS with .NET Core</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Sun, 23 Dec 2018 06:03:34 +0000</pubDate>
      <link>https://forem.com/zeerorg/adding-rss-with-net-core-279o</link>
      <guid>https://forem.com/zeerorg/adding-rss-with-net-core-279o</guid>
      <description>&lt;p&gt;&lt;em&gt;This is 3rd post in continuation to my major project on this &lt;a href="https://blog.zeerorg.site"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RSS is an old technology and has been fading out of the general ecosystem over the years. With Google shuting down its Google Reader service and Firefox &lt;a href="https://dev.to/sudiukil/firefox-64-drops-rss-support-thoughts-4hbo"&gt;dropping support&lt;/a&gt; for RSS in their last 2018 release. I admit I've never actually gotten into RSS, setting up a reading list for different blogs. I am not a frequent blog reader and most of my news source is through apps which meant I never actually had any need for RSS.&lt;/p&gt;

&lt;p&gt;So when I thought of adding RSS to my website it was actually a decision I took after thinking long and hard. I actually went ahead and tried out &lt;a href="https://feedly.com/"&gt;Feedly&lt;/a&gt; to get an idea of how modern RSS readers work. I can certainly see why a lot of people do like it, which forms the second reason why I thought of going ahead with it. The last reason is purely because I wanted to learn more about RSS and XML in general. This would be my first time implementing XML based schema for data.&lt;/p&gt;

&lt;h2&gt;
  
  
  .NET Core SyndicationFeed
&lt;/h2&gt;

&lt;p&gt;The main library that implements helper classes for RSS feed in .NET is &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.syndication?view=netcore-2.2"&gt;System.ServiceModel.Syndication&lt;/a&gt;. The top level class is &lt;code&gt;SyndicationFeed&lt;/code&gt; which can be serialized to not only the latest RSS 2.0 standard but also to Atom 1.0 feed so you can choose whichever you want. You'll need to add the library module through &lt;a href="https://www.nuget.org/packages/System.ServiceModel.Syndication/"&gt;NuGet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First we create a &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.syndication.syndicationfeed?view=netcore-2.2"&gt;syndication feed&lt;/a&gt; object and add preliminary information to it. Like the title, description and url of the blog. Then we add authors, here we can specify more than one authors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Top level feed setup&lt;/span&gt;
&lt;span class="n"&gt;SyndicationFeed&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SyndicationFeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Language&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"en-us"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastUpdatedTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Adding Authors&lt;/span&gt;
&lt;span class="n"&gt;SyndicationPerson&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SyndicationPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"r.g.gupta@outlok.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Rishabh Gupta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"https://zeerorg.site/"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Every &lt;code&gt;&amp;lt;item&amp;gt;&lt;/code&gt; element in RSS is represented as an object of &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.syndication.syndicationitem?view=netcore-2.2"&gt;SyndicationItem&lt;/a&gt; class. The items can be added to the feed object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;SyndicationItem&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SyndicationItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastUpdatedTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTimeOffset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromUnixTimeSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One important but optional element inside the &lt;code&gt;&amp;lt;item&amp;gt;&lt;/code&gt; element is &lt;code&gt;&amp;lt;content:encoded&amp;gt;&lt;/code&gt; element, this is important only for those feeds which also need to provide content of the post along with the updates. But setting this is not directly supported inside the api, so we need to create a custom element and assign it to the item.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The third argument specifies&lt;/span&gt;
&lt;span class="n"&gt;XMLDocument&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;XMLElement&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"encoded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"http://purl.org/rss/1.0/modules/content/"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InnerText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElementExtensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After setting up the feed it can be serialized to RSS 2.0 standard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;StringWriter&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringWriter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;XmlWriter&lt;/span&gt; &lt;span class="n"&gt;rssWriter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XmlWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// The second false specifies the format for feed.&lt;/span&gt;
&lt;span class="c1"&gt;// As it can be converted to an older RSS 2.0 format or the newer a10 format.&lt;/span&gt;
&lt;span class="n"&gt;Rss20FeedFormatter&lt;/span&gt; &lt;span class="n"&gt;rssFormatter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Rss20FeedFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;rssFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rssWriter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;rssWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FeedString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting RSS Feed for my blog
&lt;/h2&gt;

&lt;p&gt;For my blog all the metadata is stored in a &lt;code&gt;main.json&lt;/code&gt; file which is fetched from the blob storage. It's a very rudimentary content management system. The json contains a list of posts as json objects and each item contains data corresponding to that post. One of the data that is stored is &lt;code&gt;filename&lt;/code&gt; which specifies the filename that contains the HTML to be fetched from blob container. The RSS feed generator extracts data from JSON object of every post for the &lt;code&gt;&amp;lt;item&amp;gt;&lt;/code&gt; elements and sets the html content fetched from the blob container using &lt;code&gt;filename&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;First, I used to trigger this function on every request, but after some tests I realized creating an RSS Feed on the fly was a costly operation, so I am triggering the creation of rss on every change to &lt;code&gt;main.json&lt;/code&gt; and saving the results in a blob which is served directly.&lt;/p&gt;

&lt;p&gt;Checkout my rss feed &lt;a href="https://blog.zeerorg.site/rss.xml"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rss</category>
      <category>dotnet</category>
      <category>azure</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Caching Data in frontend</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Tue, 18 Dec 2018 15:07:24 +0000</pubDate>
      <link>https://forem.com/zeerorg/caching-data-in-frontend-3973</link>
      <guid>https://forem.com/zeerorg/caching-data-in-frontend-3973</guid>
      <description>&lt;p&gt;&lt;em&gt;We'll talk about ways you can effectively cache requests sent to backend without fidelling with backend HTTP headers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Coordinating data between state changes can be hard, consider an application where you are sending request to the backend to get a list of posts to be displayed, and when user clicks on a post the application sends another request to get that post data. Now the backend is fairly simple so you get the precise data for that post, but you also want to display the title of next post and previous post, and maybe some sponsor data which is shared during the user's session. Requesting data again from backend is wasteful in such cases so the frontend has some options at this point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Javascript state
&lt;/h2&gt;

&lt;p&gt;The frontend can keep a track of the data that will be reused. Storing that data in a global variable, passing state to higher levels, or using an api like &lt;a href="https://reactjs.org/docs/context.html" rel="noopener noreferrer"&gt;React Context&lt;/a&gt;. There are problems with each of these approaches, global variables are evil by default. Passing data around components or maintaining it in a context like api can become messy as number of requests grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a state management framework
&lt;/h2&gt;

&lt;p&gt;This is a very typical use case for a JavaScript state management framework like &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;redux&lt;/a&gt;. They provide a way to manage complex application data. But if you are anything like me, the idea of introducing a new framework and overhead of learning to code around it can be a daunting task. These frameworks can also force opinionated design on your frontend so for someone who is not familiar with one, it can be a big commitment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Storage (the real MVP)
&lt;/h2&gt;

&lt;p&gt;We come at our final answer, browser storage api. It is a key value store which is managed by the browser. There are two types of browser storages: local and session. Both of these provide a similar api, but, while the local storage is never cleared, session storage is cleared after the tab is closed. This approach is a lot better than our previous approaches as it's &lt;strong&gt;not as barebones as passing the state around&lt;/strong&gt; and &lt;strong&gt;not as complex as learning a new state management framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Browser storage api includes only two operations, &lt;code&gt;setItem&lt;/code&gt; and &lt;code&gt;getItem&lt;/code&gt; and as you can probably guess &lt;code&gt;setItem&lt;/code&gt; stores the value for a given key and &lt;code&gt;getItem&lt;/code&gt; retrieves the value. We are free from managing the state ourselves and can just provide the key and value for the data to store and retrieve it later.&lt;/p&gt;

&lt;p&gt;An example use of this api is demonstrated by creating a function that invokes a GET request to a url and returns the result as a promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Without caching&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;FetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// With Caching&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;FetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storageData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storageData&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textData&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;textData&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storageData&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;We treat the provided url as our key and store the fetched data, so that any subsequent request is fulfilled from the cache. The best part about this approach is that it is easier to understand and doesn't intrude with our frontend code. It is also the best solution for our problem in this case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Ffrontend-caching.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Ffrontend-caching.png" title="Browser storage api" alt="Basic Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caching is one of the most effective techniques to optimize performance and user experience. Storing request data on the frontend provides speedy navigation and greater control over what is stored by avoiding unnecessary requests to the backend.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you like my posts checkout my &lt;a href="https://blog.zeerorg.site/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ux</category>
      <category>optimize</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Live Preview Blog Edits</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Sat, 15 Dec 2018 06:19:31 +0000</pubDate>
      <link>https://forem.com/zeerorg/live-preview-blog-edits-2oh1</link>
      <guid>https://forem.com/zeerorg/live-preview-blog-edits-2oh1</guid>
      <description>&lt;h1&gt;
  
  
  Live Preview Blog Edits
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;This is 2nd post in continuation to my major project on this &lt;a href="https://blog.zeerorg.site"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The original requirements didn't consider live preview as an option. Seems like I was wrong, the live preview would help me see the current changes inside the window. This also gives me the flexibility to see my changes and gives me more confidence in what I'm writing. A lot of these changes are not compatible with what I see in my editor markdown preview because I'm using a custom CSS for posts.&lt;/p&gt;

&lt;p&gt;Adding live preview involves changes in the frontend and a test backend. One option I considered was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uploading directly to Azure storage.&lt;/strong&gt; This would be great since I won't have to change much in the backend and could leverage what I've built till now. But life ain't that easy, uploading to the backend takes some time and the azure blob trigger can take up to 10 minutes to run 😲!! This solution was obviously not viable, I cannot escape this ordeal easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Backend
&lt;/h2&gt;

&lt;p&gt;I reluctantly start with building a backend. The good part is that laying out a simple blog architecture makes this process much easier. If I could find a way to provide the current draft as an input to the frontend I could preview the changes in my local machine. This proved to be a relatively easy problem to tackle.&lt;/p&gt;

&lt;p&gt;For the backend, I run an HTTP based file server to emulate my blob storage use. I use nodejs-based &lt;a href="https://www.npmjs.com/package/http-server"&gt;http-server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the frontend, I check if the &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; environment is set to &lt;code&gt;"development"&lt;/code&gt; and point to the local server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building markdown on change
&lt;/h2&gt;

&lt;p&gt;My azure function backend uses &lt;a href="https://github.com/lunet-io/markdig"&gt;Markdig&lt;/a&gt; to compile markdown to HTML. I have a test project from few days before, that used Markdig to compile markdown, I picked it up to repurpose it for building the markdown files on change. I implemented a simple file watcher and compiled the files that changed to markdown. I'll link down the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;C# &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netcore-2.1"&gt;FileSystemWatcher&lt;/a&gt; was pretty easy to implement. I also learned about the &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; variable in React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zeerorg/BlogPosts/tree/master/src"&gt;Blog Posts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zeerorg/BlogPosts/tree/master/MarkdownCheck"&gt;Markdown file watcher and compiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zeerorg/BlogSite"&gt;React Frontend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hotreloading</category>
      <category>blog</category>
      <category>react</category>
    </item>
    <item>
      <title>My Blog's Architecture</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Thu, 13 Dec 2018 16:05:46 +0000</pubDate>
      <link>https://forem.com/zeerorg/my-blogs-architecture-43p7</link>
      <guid>https://forem.com/zeerorg/my-blogs-architecture-43p7</guid>
      <description>&lt;h1&gt;
  
  
  Blog's Architecture
&lt;/h1&gt;

&lt;p&gt;This is my first blog on how I'm creating my &lt;a href="https://blog.zeerorg.site" rel="noopener noreferrer"&gt;blog&lt;/a&gt;. I've started writing this before the blog site is up detailing what restrictions I'm going to place, the features I'll be adding and how I'll go about them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Block diagrams ftw
&lt;/h2&gt;

&lt;p&gt;A simple block diagram for the overall architecture. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Fblog-architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzeerorgprocessedblog.blob.core.windows.net%2Fphotos%2Fblog-architecture.png" alt="Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements (or maybe restrictions)
&lt;/h2&gt;

&lt;p&gt;Every project needs some requirements so I should underline those for this blog. I want to work under these so I don't go on doing something I actually regret later on.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Easy to write&lt;/strong&gt;. I don't want to go though the "write-build-deploy" cycle over and over again everytime I write a post. The process should be as easy as typing in my editor, seeing the preview and uploading the file. That's it, no preprocessing, no building, minimal stuff.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No bullsh*t features&lt;/strong&gt;. The feature set should be minimal. So things like comments and reacting or sharing of a post are not going to be included. Any new feature added will have an explanation on why its there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier on the bill&lt;/strong&gt;. This is not going to earn me something so I want this to be as easy on the wallet as possible. This might also push me to find newer solutions (hopefully).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Going about it
&lt;/h2&gt;

&lt;p&gt;This is why and what I decided. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Storing in Azure blobs&lt;/strong&gt;. This is going to be the place for storing original blog markdown files. This keeps a backup and also creates a destination for original source files.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stored files are automatically processed when uploaded&lt;/strong&gt;. I set this up and the files are processed without my interaction. These processed files are used by the backend to answer requests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend and backend live separately&lt;/strong&gt;. This is more of a personal choice than a practical one. I'll be writing the blog in react and I need a backend to query my blogs.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functions as backend&lt;/strong&gt;. They are really cheap to run compared to an always on server.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting frontend on Netlify&lt;/strong&gt;. I have heard good things about netlify and wanted to try it out. Its free tier is great and I can add my custom domain for free.
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>architecture</category>
      <category>blog</category>
      <category>major</category>
    </item>
    <item>
      <title>Going Cloud</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Mon, 06 Aug 2018 07:08:41 +0000</pubDate>
      <link>https://forem.com/zeerorg/going-cloud-3o8p</link>
      <guid>https://forem.com/zeerorg/going-cloud-3o8p</guid>
      <description>&lt;p&gt;I few weeks back I decided to try out a new workflow for my assignments and projects. This involved doing all my work on a remote server including coding, compiling and checking output. &lt;/p&gt;

&lt;h2&gt;
  
  
  Reason
&lt;/h2&gt;

&lt;p&gt;The main reason I wanted to try this out was because I hated carrying my laptop to college everyday (its almost 2.7kgs) and wanted a workflow that can be easily ported and can work from anywhere. I also had 100$ digitalocean joining credit which I thought could be put to good use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;This was an easy part. All I needed was to create a virtual machine and install necessary language tools.&lt;br&gt;
I went with the stable ubuntu 16.04 vm and installed Python, Nodejs and cloned my projects from github.&lt;br&gt;
Now take care to select a vm near to your location, as this will decrease latency and improve the overall experience&lt;/p&gt;

&lt;h2&gt;
  
  
  First tries : sshfs
&lt;/h2&gt;

&lt;p&gt;I was reluctant to give up the comforts of my favorite editor so I thought I could mount the remote server as a folder and then open those files through text editor. This was obvioulsy going to be faster than using vnc or any other kind of remote desktop protocol.&lt;/p&gt;

&lt;p&gt;This worked fine for small assignments but slowed down for projects with a lot of files. I was working on a react project and indexing all modules became a big task. This also meant you needed to install all basic language tools locally and remote server served as nothing more than a network drive.&lt;/p&gt;

&lt;p&gt;During this mess of a workflow I also learnt about &lt;a href="https://direnv.net/" rel="noopener noreferrer"&gt;direnv&lt;/a&gt;, a tool to set environment variables specific to each project directory. You should check it out if you haven't already.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better workflow
&lt;/h2&gt;

&lt;p&gt;Second logical workflow involved using exclusively just the terminal and ssh into the remote server.&lt;br&gt;
Just cloning the repo and installing stuff wasn't going to cut it. Every time I needed to work I had to ssh into machine and navigate to that repo then open a file to edit it. Working on multiple files by opening multiple terminal windows was a nightmare. &lt;/p&gt;

&lt;p&gt;Now came TMUX, like a savior from the dark. It was just the solution I needed and more. Honestly anyone who has used tmux knows how awesome it is and I recommend it to everyone to try it out. It is used to create multiple terminals inside a single console window. Taking terminator and applying it inside a console instead of using it on a gui.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.tecmint.com%2Fwp-content%2Fuploads%2F2016%2F01%2FTmux-Manage-Multiple-Linux-Terminals.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.tecmint.com%2Fwp-content%2Fuploads%2F2016%2F01%2FTmux-Manage-Multiple-Linux-Terminals.png" alt="TMUX"&gt;&lt;/a&gt;&lt;br&gt;
Image from tecmint, check out their &lt;a href="https://www.tecmint.com/tmux-to-access-multiple-linux-terminals-inside-a-single-console/" rel="noopener noreferrer"&gt;tmux article&lt;/a&gt; for deeper look.&lt;/p&gt;

&lt;p&gt;TMUX starts a session and each session contains some windows and each window can be divided into multiple panes.  TMUX session don't need to be closed whenever you close a terminal window they can be suspended to background. &lt;br&gt;
This meant I don't even need to start a new session every time I need to work, all I need to do is create a session after I am done cloning the repo. Now whenever I ssh I could just open that session and start working on my project.&lt;br&gt;
This solved a lot of problems, I didn't have to write any script to start a session and my environment was always ready whenever I wanted to start working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downsides
&lt;/h2&gt;

&lt;p&gt;There are obviously a lot of downsides to this approach.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You loose any support for gui editors and are locked with terminal editors like vim and emacs.&lt;/li&gt;
&lt;li&gt;Some workflows are straight up impossible to shift to cloud like developing GUI apps or working with external devices. These will require a lot of extra setup and might not be optimized and won't be as portable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Have you tried any interesting workflows you might want to discuss about in the comment section?&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>workflow</category>
      <category>experiment</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Another Cryptocurrency post</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Tue, 27 Mar 2018 08:54:21 +0000</pubDate>
      <link>https://forem.com/zeerorg/another-cryptocurrency-post-1pjh</link>
      <guid>https://forem.com/zeerorg/another-cryptocurrency-post-1pjh</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this post I'll share some cryptocurrency concepts. It's an explanation post so we won't dive into code and keep it as general as possible.&lt;br&gt;
We start by a basic concept of passbook: When we do any bank transaction it is recorded in our &lt;a href="https://en.wikipedia.org/wiki/Passbook" rel="noopener noreferrer"&gt;passbook&lt;/a&gt;, it holds all the history to our spendings and earnings.&lt;br&gt;
Passbook is a form of simplified ledger. We start by taking a simple example.&lt;/p&gt;

&lt;h1&gt;
  
  
  Two friends' example
&lt;/h1&gt;

&lt;p&gt;Now we take two friends A and B who want to transfer fake money to each other but instead of printing their own money they do one thing, they create a shared passbook. This shared passbook stores records of both of them. A transfers money to B by adding a record in his own version and he tells B about his transaction, now B can record that transaction too.&lt;br&gt;
This shared record is a distributed ledger, the basis of blockchain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzeerorg%2FWriteIt%2Fmaster%2Fledger.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzeerorg%2FWriteIt%2Fmaster%2Fledger.png" alt="Shared ledger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now more people want to trade with them using this fake money so everyone gets that shared passbook. When someone transfers money they inform everyone that they have done so, so that everyone updates their ledger.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q1 : Where did the starting money come from ? Ans, The game of dice.
&lt;/h3&gt;

&lt;p&gt;Initially, A and B agreed that they will play dice and whoever gets a bigger number will have 10 fake currency. This is also added to ledger.&lt;br&gt;
They agree to do this every hour and hence someone collects 10 fake currency every hour.&lt;br&gt;
Later, anyone who has the ledger has the right to play the game of dice.&lt;/p&gt;

&lt;p&gt;This is a basic &lt;strong&gt;crypto currency mining&lt;/strong&gt; scheme. If a lot of people are competing the game of dice is not feasible, hence they are given a problem to solve. Whoever solves the problem first is given the money.&lt;/p&gt;

&lt;p&gt;The beauty of this structure is that there is no actual physical notes or any type of asset exchange, it is just a series of transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2 : What if someone starts to cheat ?
&lt;/h3&gt;

&lt;p&gt;Let's say B got greedy and wanted extra money, so he added a transaction from A to himself and told everyone A has done so.&lt;/p&gt;

&lt;p&gt;To prevent this they agreed to add a signature to the transaction. Much like a signature on the cheque, this acts as a proof telling that the transaction was done by the person himself. Now, B cannot copy A's signatures hence, he cannot create that transaction. Every node checks the signature before adding the transaction to their ledger.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3 : Spending money more than once !
&lt;/h3&gt;

&lt;p&gt;This time B got creative at cheating, he had 10 currency at a point in time and he sent that to both A and C. He told everyone (except C) that he sent money to A, and he told C that he sent that money to C. C thought the transaction was a success. &lt;/p&gt;

&lt;p&gt;This is the problem of double spending. To prevent double spending participants need a way to differentiate between confirmed and unconfirmed transactions. This is achieved through block chains.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj80w5n9vg5xuv4wwtm8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fj80w5n9vg5xuv4wwtm8a.png" alt="Double Spending"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4: What is a block chain ?
&lt;/h3&gt;

&lt;p&gt;Block : It is a collection of transactions and contains a hash of the previous block. (hash is a unique number corresponding to a block)&lt;/p&gt;

&lt;p&gt;This is similar to linked lists ! Where each block is a node and it's hash is a type of reference. &lt;/p&gt;

&lt;p&gt;Every block corresponds to a problem which needs to be solved. This is the mining problem discussed in previous section. Answer of this problem is the hash of the block which is added to the next block. Only a single block is being solved at any point in time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;After a block is solved the transactions it contains are confirmed&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Now no one can change the transaction as this will change the block, which will change the problem and the answer to that problem, causing a chain reaction where the block next to it will change and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzeerorg%2FWriteIt%2Fmaster%2Fblockchain.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fzeerorg%2FWriteIt%2Fmaster%2Fblockchain.png" alt="Block chain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra Reading:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;I find &lt;a href="https://en.bitcoin.it/wiki/Main_Page" rel="noopener noreferrer"&gt;Bitcoin wiki&lt;/a&gt; a great resource to understand more concepts.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blockexplorer.com/" rel="noopener noreferrer"&gt;Bitcoin block explorer&lt;/a&gt; for taking a look around.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>blockchain</category>
      <category>cryptocurrency</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Lifetimes in Rust</title>
      <dc:creator>Rishabh Gupta</dc:creator>
      <pubDate>Sun, 28 Jan 2018 15:31:44 +0000</pubDate>
      <link>https://forem.com/zeerorg/lifetimes-in-rust-j8</link>
      <guid>https://forem.com/zeerorg/lifetimes-in-rust-j8</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Rust is a system programming language which guarantees memory safety and prevents problems associated with it like data races between threads, memory leaks and dangling pointers by taking radically new approach to memory management. In this article I'd like to discuss about one such approach which they call Lifetimes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Brief intro to borrowing and ownership
&lt;/h2&gt;

&lt;p&gt;Borrowing, ownership and lifetimes, all three of them are concepts in Rust which complement each other and provide memory guarantees at runtime. To keep our focus on Lifetimes we'll briefly see what others are.&lt;/p&gt;

&lt;h4&gt;
  
  
  Borrowing
&lt;/h4&gt;

&lt;p&gt;Example: &lt;code&gt;let x = &amp;amp;y&lt;/code&gt;&lt;br&gt;
Here &lt;code&gt;x&lt;/code&gt; references &lt;code&gt;y&lt;/code&gt; and is "almost" similar in functionality to C/C++ references. &lt;/p&gt;
&lt;h4&gt;
  
  
  Ownership
&lt;/h4&gt;

&lt;p&gt;Rust doesn't have a garbage collector, so it follows a simple rule to clear out allocated memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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;When &lt;code&gt;v&lt;/code&gt; goes out of scope it's memory will be cleared, even if it is dynamically allocated.&lt;/p&gt;

&lt;h1&gt;
  
  
  So what is Lifetime ?
&lt;/h1&gt;

&lt;p&gt;In layman terms lifetime of a thing is "the length of time that thing is usable" and it means almost the same in Rust, the "thing" here being "variables".&lt;/p&gt;

&lt;p&gt;Take a look at this code, and errors generated by compiler in the comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&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;1&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c"&gt;// borrow occurs here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;                   &lt;span class="c"&gt;// `i` dropped here while still borrowed&lt;/span&gt;

    &lt;span class="nd"&gt;println!&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="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;    &lt;span class="c"&gt;// borrowed value needs to live until here&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;What happens here is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We declare a variable &lt;code&gt;r&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We go inside a scope 
2.1. We initialize a variable &lt;code&gt;i&lt;/code&gt; 
2.2. Assign a reference of &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;r&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Go out of scope&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;r&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At step 3, what happened was that memory for &lt;code&gt;i&lt;/code&gt; was freed and &lt;code&gt;r&lt;/code&gt; referred to a junk memory location.&lt;/p&gt;

&lt;p&gt;The compiler gave us a sweet error message after step 4 saving us from a runtime disaster which C/C++ would have given us.&lt;/p&gt;

&lt;h1&gt;
  
  
  Okay, but why care ?
&lt;/h1&gt;

&lt;p&gt;Let's see another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Car&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You create a struct, and happily click that compile button, but...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0106]: missing lifetime specifier

model: &amp;amp;str
        ^ expected lifetime parameter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you get this message. You're scratching your head and thinking, "I didn't do anything wrong".&lt;/p&gt;

&lt;p&gt;Well, by compiler logic the reference &lt;code&gt;model&lt;/code&gt; will be destroyed as soon as the struct scope finishes. So how do you fix it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;'a&lt;/code&gt;, we have explicitly assigned a name to variable's lifetime, then in the statement &lt;code&gt;model: &amp;amp;'a str&lt;/code&gt; we tell the compiler to keep the reference around for as long as we have the variable of type &lt;code&gt;Car&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Point to take note is that, lifetimes are always there but most of the times they are implied automatically by the compiler so you don't have to explicitly assign them each time you borrow a reference.&lt;/p&gt;

&lt;h1&gt;
  
  
  Leveling up
&lt;/h1&gt;

&lt;p&gt;We'll look at another code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;do_task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nf"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&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;Here &lt;code&gt;do_task&lt;/code&gt; is a reference to a function and it borrows a string reference, "but... we didn't define &lt;code&gt;&amp;amp;'a str&lt;/code&gt;". &lt;code&gt;&amp;amp;str&lt;/code&gt; means it is tied to the scope of function, hence the string reference will be cleared when the function completes.&lt;/p&gt;

&lt;p&gt;While &lt;code&gt;do_task&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; are tied to the scope of variable which is of &lt;code&gt;Person&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Lifetimes is a new and interesting concept, but can be hard to understand the first time. Other resources you can look at are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rustbyexample.com/scope/lifetime.html"&gt;Rust by example: Lifetimes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/1.9.0/book/lifetimes.html"&gt;Rust Documentation: Lifetimes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding!!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>coding</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
