<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Tarun Batra</title>
  
  <subtitle>Developer</subtitle>
  <link href="//atom.xml" rel="self"/>
  
  <link href="https://tarunbatra.com/"/>
  <updated>2021-02-13T21:12:25.450Z</updated>
  <id>https://tarunbatra.com/</id>
  
  <author>
    <name>Tarun Batra</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Git before Github</title>
    <link href="https://tarunbatra.com/blog/x/git-before-github/"/>
    <id>https://tarunbatra.com/blog/x/git-before-github/</id>
    <published>2020-10-24T20:17:54.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p>Back when I was studying CS at university, we had assignments to code various algorithms. When the assignments were due we were supposed to execute the code in laboratory systems and get the output checked by the professors. I liked coding and tinkering with the algorithms; some of my classmates didn’t. They used to copy the code from my system on a USB stick and execute them on their system and get done with it. I didn’t judge them but I was tired of giving each one their copy and sometimes also instructing them how to execute that piece of code. In one such assignment, I uploaded the code on GitHub and shared the <a href="https://github.com/tarunbatra/re2nfa" target="_blank" rel="noopener">link</a> with anybody who asked. <strong>Unknowingly, I had made my first open source contribution.</strong></p><p>A lot of people have similar stories and for most, Github is synonymous with Open Source. One thing that is also used interchangeably with Github is git. Even though these are three different entities, a lot of developers including me have never contributed to open source or used git without Github. Thus I was surprised when I learned that famous open source projects like Linux were not on Github even though they used git. Also, git was around before Github, so there must be other more native ways in git to get things done. I wondered how it worked but didn’t do anything about it until recently when I decided to experience a git only development workflow.</p><h2 id="Git-server-access"><a href="#Git-server-access" class="headerlink" title="Git server access"></a>Git server access</h2><p>We use version control systems broadly for two use cases – to contribute to a repository where we have write access; to contribute to a public repository where we don’t have write access. To collaborate with developers to whom access can be given, Github or other platforms are not necessary. Anybody can host a <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server" target="_blank" rel="noopener">Git server</a> that can be used to host repositories. Developers can clone, push to, and pull from these remote repositories once access is granted to their ssh identity.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone origin git@&lt;host&gt;&#x2F;&lt;repo&gt;.git</span><br></pre></td></tr></table></figure><p>This is similar to how we upload our SSH keys to Github or other platforms for being able to clone the repositories using SSH.</p><h2 id="Pull-requests"><a href="#Pull-requests" class="headerlink" title="Pull requests"></a>Pull requests</h2><p>One thing which is missing in the above-mentioned method is the ability to create Pull Requests, get them reviewed and merged into the code. It becomes a big issue when the developers don’t have write access to the repositories as is the case in open source development. General open source flow is to fork a repository, push the changes in your forked repositories, and create a <strong>pull request</strong> to the original repository from where the maintainers can review and merge. Pull request is not a feature of git, but of platforms like Github. Collaborative development in git has the following steps:</p><ol><li>Clone the original repository</li><li>Create a patch</li><li>Send the patch to the maintainer</li><li>The maintainer applies the patch and pushes the code</li></ol><p>We introduced two new processes in this workflow – creating a patch and applying a patch. Let’s discuss them further.</p><hr><h3 id="Patch"><a href="#Patch" class="headerlink" title="Patch"></a>Patch</h3><p>A patch is a diff of code and metadata around it. A diff is the actual code change which can be viewed using the command <code>git diff</code>. It is a Unix concept that is way older than git and Unix systems even have a builtin tool, <a href="https://man7.org/linux/man-pages/man1/diff.1.html" target="_blank" rel="noopener"><code>diff</code></a> which compares changes between two files. Its output can then be saved to a file that can be processed by another utility tool called <code>patch</code> which updates one of the files to make its content identical to another file.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">touch original.txt new.txt</span><br><span class="line"><span class="built_in">echo</span> <span class="string">"New addition"</span> &gt; new.txt</span><br></pre></td></tr></table></figure><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">diff original.txt new.txt -u &gt; changes.patch</span><br></pre></td></tr></table></figure><figure class="highlight patch"><figcaption><span>changes.patch</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">--- original.txt2020-10-18 23:43:32.000000000 +0200</span></span><br><span class="line"><span class="comment">+++ new.txt2020-10-18 23:43:32.000000000 +0200</span></span><br><span class="line">@@ -0,0 +1 @@</span><br><span class="line"><span class="addition">+New addition</span></span><br></pre></td></tr></table></figure><p>If we want to update the original file with the contents of the new one, we need to “patch” it.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">patch original.txt changes.patch</span><br></pre></td></tr></table></figure><p><strong>NOTE:</strong> <em>Use <a href="https://github.com/tarunbatra/git-before-github" target="_blank" rel="noopener">git-before-github repository</a> to practice this example and all the ones which are to follow.</em></p><p>Now that we understand the concepts of diff and patch, we can proceed with using them in git. To generate a patch file in git, we need to use <code>git format-patch</code> command.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git format-patch HEAD~1..HEAD</span><br></pre></td></tr></table></figure><p>This will create a patch file for the latest commit. Tinker with the argument to produce patch files for other commits too. By default, each file represents a single commit and the file name is of the format <code>0001-&lt;commit message&gt;.patch</code>. Interestingly, it is in <a href="https://en.wikipedia.org/wiki/Mbox" target="_blank" rel="noopener">Unix mbox</a> format which means it has some email-like metadata (from, subject, etc.) followed by the patch data.</p><figure class="highlight patch"><figcaption><span>0001-Added-Tarun-Batra-to-contributors.patch</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">From 619814a3ac21012580e725136864e8397c14e20b Mon Sep 17 00:00:00 2001</span><br><span class="line">From: Tarun Batra &lt;tarun.batra00@gmail.com&gt;</span><br><span class="line">Date: Tue, 20 Oct 2020 23:15:32 +0200</span><br><span class="line">Subject: [PATCH] Added Tarun Batra to contributors</span><br><span class="line"></span><br><span class="line"><span class="comment">---</span></span><br><span class="line"> CONTRIBUTORS.txt | 1 +</span><br><span class="line"> 1 file changed, 1 insertion(+)</span><br><span class="line"></span><br><span class="line">diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt</span><br><span class="line">index e69de29..1d12219 100644</span><br><span class="line"><span class="comment">--- a/CONTRIBUTORS.txt</span></span><br><span class="line"><span class="comment">+++ b/CONTRIBUTORS.txt</span></span><br><span class="line">@@ -0,0 +1 @@</span><br><span class="line"><span class="addition">+Tarun Batra &lt;tarun.batra00@gmail.com&gt;</span></span><br><span class="line"><span class="deletion">--</span></span><br><span class="line">2.28.0</span><br></pre></td></tr></table></figure><p>This is the patch file I created to add my name to the contributors’ list of the <a href="https://github.com/tarunbatra/git-before-github" target="_blank" rel="noopener">git-before-github</a> repository as an exercise for myself.</p><hr><h3 id="Apply"><a href="#Apply" class="headerlink" title="Apply"></a>Apply</h3><p>We have a patch file which we can send to the maintainers so that they can apply the patch. We can either use traditional ways to send the patch or use git itself, but more on it later. In this section, we will explore the process to apply a patch.</p><p><code>git apply &lt;patch file&gt;</code> is a command which applies the changes described in the patch file locally but does not commit them. They will appear in our workspace and we can stage them and commit them. This is not ideal as even though we get the changes, the commit metadata like author name and message is lost. A better way to apply patches is <code>git am</code> (abbrev. for “apply mailbox”).</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git am --signoff &lt;patch file&gt;</span><br></pre></td></tr></table></figure><p>The flag <code>--signoff</code> is used if the commit message needs to be appended with a “Signed-off-by” line to indicate who applied the commit. Below is the signed-off and applied commit for the patch we generated as an exercise in the last section.</p><figure class="highlight sh"><figcaption><span>git log</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Author: Tarun Batra &lt;tarun.batra00@gmail.com&gt;</span><br><span class="line">Date:   Tue Oct 20 23:15:32 2020 +0200</span><br><span class="line"></span><br><span class="line">    Added Tarun Batra to contributors</span><br><span class="line"></span><br><span class="line">    Signed-off-by: Tarun Batra &lt;tarun.batra00@gmail.com&gt;</span><br></pre></td></tr></table></figure><hr><h3 id="Sending-the-patch"><a href="#Sending-the-patch" class="headerlink" title="Sending the patch"></a>Sending the patch</h3><p>Now we can explore how to send a patch file to a maintainer in the “git” way. There are two ways that I know of –</p><ol><li><p>imap-send</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git imap-send &lt;patch file&gt;</span><br></pre></td></tr></table></figure><p>It will upload the email to an IMAP folder from where it can be sent. To use it we need to add IMAP server details in our <code>~/.gitconfig</code> file. I use Gmail so my IMAP details look like:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[imap]</span></span><br><span class="line">folder = "[Gmail]/Drafts"</span><br><span class="line">host = imaps://imap.gmail.com</span><br><span class="line">user = email@gmail.com</span><br><span class="line">pass = yourpassword</span><br><span class="line">port = 993</span><br></pre></td></tr></table></figure><p>Gmail allows its IMAP server to be used if the <a href="https://myaccount.google.com/lesssecureapps" target="_blank" rel="noopener">Less secure app access</a> setting is turned on.</p></li><li><p>send-email</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git send-email --to=&lt;email&gt; &lt;patch file&gt;</span><br></pre></td></tr></table></figure><p>It will use an SMTP server to send email. The corresponding config to use this command is:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[sendemail]</span></span><br><span class="line">smtpEncryption = tls</span><br><span class="line">smtpServer = &lt;host&gt;</span><br><span class="line">smtpUser = &lt;user&gt;</span><br><span class="line">smtpServerPort = 587</span><br></pre></td></tr></table></figure><p>Both of these methods can be used to send an email per patch file. The subject of the commit by default is of the format <code>[PATCH] &lt;commit message&gt;</code>.</p></li></ol><p><strong>NOTE:</strong> <em>Sender email addresses can be spoofed quite easily and this raises the question of authentication and authorization when submitting patches. I tried creating patches of PGP signed git commits but the patch doesn’t retain the PGP signature. We could encrypt the email itself using PGP but that’s a lot of extra work for both the contributor and the maintainer.</em></p><p>So what can we do with this newly acquired knowledge?</p><ol><li>Git patches often <a href="https://lkml.org/lkml/2020/10/16/629" target="_blank" rel="noopener">float</a> <a href="https://lkml.org/lkml/2020/10/19/82" target="_blank" rel="noopener">around</a> in the Linux development mailing list and it gives me satisfaction that I understand how they work a little better now than before.</li><li>When platforms like Github and Gitlab have an outage, work in most of the development teams stall. Now I know a way to get my code reviewed even in these situations. (Okay, that might be a stretch)</li><li>EDIT: About when this article was published, <a href="https://yt-dl.org/about.html" target="_blank" rel="noopener"><code>youtube-dl</code></a> was taken down by Github due to <a href="https://github.com/github/dmca/blob/master/2020/10/2020-10-23-RIAA.md" target="_blank" rel="noopener">a DMCA request</a>. The whole episode brings to light that Github being a platform is subject to censorship, unlike git which is distributed.</li></ol><p>You can practice for yourself by adding your name to the <code>CONTRIBUTORS.txt</code> file of the <a href="https://github.com/tarunbatra/git-before-github" target="_blank" rel="noopener">git-before-github</a> repository, committing it, and then sending me the patch. I would readily <del>merge</del> apply it. 😀</p>]]></content>
    
    <summary type="html">
    
      Have you collaborated over git without using platforms like Github? I haven&#39;t either. But git is distributed in itself so it is possible and here is how.
    
    </summary>
    
    
    
      <category term="git" scheme="https://tarunbatra.com/tags/git/"/>
    
      <category term="github" scheme="https://tarunbatra.com/tags/github/"/>
    
      <category term="opensource" scheme="https://tarunbatra.com/tags/opensource/"/>
    
  </entry>
  
  <entry>
    <title>PyPi packages decoded for npm developers</title>
    <link href="https://tarunbatra.com/blog/python/PyPi-packages-decoded-for-npm-developers/"/>
    <id>https://tarunbatra.com/blog/python/PyPi-packages-decoded-for-npm-developers/</id>
    <published>2020-08-31T18:00:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p>If you are a developer in Javascript / Node.js ecosystem, you have used <code>npm</code>. It’s the world’s largest software registry and the ecosystem around it is advanced and mature. I realized it when I tried to port <code>password-validator</code>, an open source npm package I maintain, to Python. I spent weeks to figure out things which were very intuitive to me in the Javascript world. This blog will list down some of the key differences I found between the two ecosystems for anybody else who treads the same path. By the end of this post, we should be able to install our package using:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install &lt;my-awesome-package&gt;</span><br></pre></td></tr></table></figure><h2 id="What-is-a-package"><a href="#What-is-a-package" class="headerlink" title="What is a package?"></a>What is a package?</h2><p>In <code>npm</code>, any folder which has a <code>package.json</code> file is a package. In Python world, we need a file called <code>setup.py</code> in the root folder to make our project a package for <a href="https://pypi.org/" target="_blank" rel="noopener">PyPi</a>, a common repository for Python packages. This file is used to declare meta data like name, version, author, and even dependencies (with a catch). Look at this <a href="https://github.com/pypa/sampleproject/blob/master/setup.py" target="_blank" rel="noopener">sample setup.py file</a> to get an idea.</p><p>Normally, the actual package code goes inside a directory with the package name and it is required to have a <code>__init__.py</code> file in it to indicate that it is a module. So the directory structure would look more or less like:</p><pre>package-project├── setup.py└── my-package    ├── __init__.py    └── lib.py</pre><p>In this structure your actual package code will go in <code>__init__.py</code> and/or any other python file in this directory like <code>lib.py</code>.</p><h2 id="Dependency-management"><a href="#Dependency-management" class="headerlink" title="Dependency management"></a>Dependency management</h2><p>Dependency management is one area where I found Python ecosystem lacking and primordial. <code>npm</code> has concepts like <code>dependencies</code> and <code>devDependencies</code> and <code>package-lock</code> which make dependency management easier. The manifest file <code>setup.py</code> has a section called <code>install-requires</code> which is a list of the dependencies required to run the project. These dependencies are downloaded while installing the package using <code>pip</code>. It’s not very widely used to define the exact dependencies and dependencies of dependencies.</p><p>Instead, a combination of a virtual environment and requirements file is used.</p><h3 id="Virtual-environment"><a href="#Virtual-environment" class="headerlink" title="Virtual environment"></a>Virtual environment</h3><p><code>npm</code> allows installing packages globally or local to a project. In <code>pip</code>, all packages are installed globally.  To separate the local dependencies from system-wide packages, a virtual environment is created which contains all the dependencies local to the project and even a local Python distribution. Code running in a virtual environment doesn’t require any system dependency, so one can be assured that the code should run in all systems wherever the local virtual environment is set up correctly.</p><p>There are multiple ways of setting up a virtual environment, like <code>venv</code> and <code>virtualenv</code>. I found former to be the easiest to use.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 -m venv &lt;dir&gt;</span><br></pre></td></tr></table></figure><p>The above command creates a virtual environment in directory <code>&lt;dir&gt;</code> which means this directory will house everything required to run the program including Python and pip distributions. This directory needs not be committed to version control. To use the virtual environment, it has to be “activated”.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">source</span> &lt;dir&gt;/bin/activate</span><br></pre></td></tr></table></figure><h3 id="Requirements-file"><a href="#Requirements-file" class="headerlink" title="Requirements file"></a>Requirements file</h3><p>Every virtual environment has its own pip and Python distribution. So it’s a clean slate when you start. When we install dependencies, we can make a log of them using:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip freeze &gt; requirements.txt</span><br></pre></td></tr></table></figure><p>This will log all the packages and their versions installed by pip in the file <code>requirements.txt</code>. The file name can be anything but it’s a convention in the Python community to use this name. There is no concept of devDependencies in Python but it’s not uncommon for some projects to have a <code>requirements-dev.txt</code> to log devDependencies of the project. Here’s a <a href="https://github.com/tarunbatra/password-validator-python/blob/master/requirements-dev.txt" target="_blank" rel="noopener">sample requirements file</a>.</p><p>Installing a project’s dependencies now can be done with:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install -r requirements.txt</span><br></pre></td></tr></table></figure><h2 id="Documentation"><a href="#Documentation" class="headerlink" title="Documentation"></a>Documentation</h2><p><code>JSDocs</code> is the most common way to document code in JavaScript and the list of documentation tools alomst stops there. Documentation in Python is taken very seriously.</p><h3 id="Sphinx"><a href="#Sphinx" class="headerlink" title="Sphinx"></a>Sphinx</h3><p><a href="https://www.sphinx-doc.org/en/master/" target="_blank" rel="noopener"><code>Sphinx</code></a> is a documentation generator for Python which can be used in various ways thanks to a variety of extensions available. To get started with sphinx, we need a <code>conf.py</code> file which will have configuration for sphinx. The file can be generated using <code>sphinx-quickstart</code> CLI utility. Here’s a <a href="https://github.com/tarunbatra/password-validator-python/blob/master/docs/source/conf.py" target="_blank" rel="noopener">sample conf.py file</a> to get started.</p><p>Sphinx and Python ecosystem prefers using <code>reStructuredText</code> (reST) for documentation instead of Markdown which is common in the JavaScript world. M↓ can be used with Sphinx too, but it’s a bit of work and reST is very similar to M↓. Here’s a sample <a href="https://raw.githubusercontent.com/tarunbatra/password-validator-python/master/README.rst" target="_blank" rel="noopener">README in reST</a>.</p><h2 id="Docstrings"><a href="#Docstrings" class="headerlink" title="Docstrings"></a>Docstrings</h2><p>Sphinx can look through special comments in Python code and include them in the documentation. These comments which are called <code>Docstrings</code> are used to describe functions, classes etc. and are very similar to JSDocs in JavaScript and JavaDocs in Java. Here’s a method documented with Docstrings:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">add</span><span class="params">(a, b)</span>:</span></span><br><span class="line">  <span class="string">''' Performs addition of 2 numbers</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  Example:</span></span><br><span class="line"><span class="string">    &gt;&gt;&gt; res = add(1, 2)</span></span><br><span class="line"><span class="string">    3</span></span><br><span class="line"><span class="string">  Returns:</span></span><br><span class="line"><span class="string">    int: Result of addition</span></span><br><span class="line"><span class="string">  '''</span></span><br><span class="line">  <span class="keyword">return</span> a + b</span><br></pre></td></tr></table></figure><p>There are a number of formats for writing Docstrings, which can be a topic discussion in itself. I found myself going back to <a href="https://realpython.com/documenting-python-code/#documenting-your-python-code-base-using-docstrings" target="_blank" rel="noopener">this guide by RealPython</a> and I recommend giving it a read for a deeper understanding of Docstrings. Using the combination of reSt files and Docstrings, we can generate documentation using Sphinx in a form like PDF and HTML. Here’s a <a href="https://tarunbatra.com/password-validator-python/api_reference.html">sample HTML documentation</a> generated using Sphinx.</p><p>There are less popular alternatives to Sphinx which can also be used for documentation, most notable being <a href="https://readthedocs.org/" target="_blank" rel="noopener">ReadTheDocs</a>.</p><h2 id="Tests"><a href="#Tests" class="headerlink" title="Tests"></a>Tests</h2><p>I found writing unit tests in Python easier than in JavaScript due to the availability of mature and built-in tools.</p><h3 id="unittest"><a href="#unittest" class="headerlink" title="unittest"></a>unittest</h3><p>Python has a built-in module <a href="https://docs.python.org/3/library/unittest.html" target="_blank" rel="noopener"><code>unittest</code></a> which can be used to run the tests. The syntax is very similar to Jest or Mocha. Every “test” is a class and every class method is a test case. Methods like <code>setUp()</code> and <code>teardown()</code> have special meanings and are equivalent to <code>before</code> and <code>after</code> methods seen in JavaScript testing frameworks. Here’s a <a href="https://github.com/tarunbatra/password-validator-python/blob/master/tests/test_password_validator.py" target="_blank" rel="noopener">sample test file</a>. Tests are run by:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 -m unittest discover -s &lt;test_directory&gt;</span><br></pre></td></tr></table></figure><p><a href="https://docs.pytest.org/en/stable/" target="_blank" rel="noopener">Pytest</a> and <a href="https://docs.nose2.io/en/latest/" target="_blank" rel="noopener">nose2</a> are some of the alternatives but I found <code>unittest</code> adequate.</p><h3 id="Doctests"><a href="#Doctests" class="headerlink" title="Doctests"></a>Doctests</h3><p>Earlier in Documentation section, we discussed about Docstrings. The Examples section in a Docstring provide the user an understanding of how to use the function. What’s great is we can also run the example against an automated unit test, using <a href="https://docs.python.org/3/library/doctest.html" target="_blank" rel="noopener">doctest</a> (another built-in module). This can keep the documentation and implementation in sync.</p><h2 id="Publishing"><a href="#Publishing" class="headerlink" title="Publishing"></a>Publishing</h2><p>Packages can be publushed to PyPi after building. Earlier the builds were made in Egg format, however now it is being replaced by Wheel format. To create a wheel build, we need to install <code>setuptools</code> and <code>wheel</code>.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 -m pip install --user --upgrade setuptools wheel</span><br></pre></td></tr></table></figure><p>Now the build can be created by running:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 setup.py sdist bdist_wheel</span><br></pre></td></tr></table></figure><p>This will create two files in <code>dist</code> folder:</p><ul><li>One with <code>.tar.gz</code> extension which is a source archive.</li><li>Another with <code>.whl</code> extension which is the build file ready to be installed.</li></ul><p>Now we need to upload the package build to PyPi. We need <code>twine</code> for that.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 -m pip install --user --upgrade twine</span><br></pre></td></tr></table></figure><p>Final step, the uploading of the build:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 -m twine upload --repository testpypi dist&#x2F;*</span><br></pre></td></tr></table></figure><p><code>--repository</code> here lets you select a specific package repository like custom or private npm registeries. It can be configured with a <a href="https://packaging.python.org/specifications/pypirc/" target="_blank" rel="noopener"><code>.pypirc</code></a> file.</p><h2 id="Additional-resources"><a href="#Additional-resources" class="headerlink" title="Additional resources"></a>Additional resources</h2><p>Two resources which helped me a lot in fuguring out my issues were:</p><ol><li>The official <a href="https://packaging.python.org/" target="_blank" rel="noopener">Python Packaging User Guide</a>. I recommend going through it once.</li><li><a href="https://realpython.com/" target="_blank" rel="noopener">The Real Python</a>. I recommend clicking on any link from this website which comes up in search results.</li></ol><p>It was an interesting experience for me to tackle all the challenges faced when I was on a journey to publish my first package on PyPi. A mature testing frameworks was a breath of fresh air while dependency management and documentation generation was a daunting task due to all the different tools to manage. In the end I published <a href="https://github.com/tarunbatra/password-validator-python/" target="_blank" rel="noopener">password_validator</a> and I am happy with the result.</p><p>Do reach out in comments or on my <a href="https://twitter.com/tarunbatra/" target="_blank" rel="noopener">Twitter</a> if you have any issues with the steps I have mentioned here. Happy publishing!</p>]]></content>
    
    <summary type="html">
    
      Step by step guide to develop Python packages and comparisions with npm ecosystem. I deployed my package on PyPi and here&#39;s what I&#39;ve learned.
    
    </summary>
    
    
      <category term="python" scheme="https://tarunbatra.com/categories/python/"/>
    
    
      <category term="python" scheme="https://tarunbatra.com/tags/python/"/>
    
      <category term="npm" scheme="https://tarunbatra.com/tags/npm/"/>
    
      <category term="pip" scheme="https://tarunbatra.com/tags/pip/"/>
    
  </entry>
  
  <entry>
    <title>Deploy your website on IPFS: Why and How</title>
    <link href="https://tarunbatra.com/blog/decentralization/Deploy-your-website-on-IPFS-Why-and-How/"/>
    <id>https://tarunbatra.com/blog/decentralization/Deploy-your-website-on-IPFS-Why-and-How/</id>
    <published>2020-04-18T22:00:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sup>Photo by <a href="https://unsplash.com/@clintadair" target="_blank" rel="noopener">Clint Adair</a> on <a href="https://unsplash.com" target="_blank" rel="noopener">Unsplash</a></sup></p><p>I wanted to learn about IPFS and Web 3.0 so I started exploring it and tried to upload my site there. This is an account of the concepts I learnt along the way and how I finally got my site hosted on <a href="http://tbking.eth.link" target="_blank" rel="noopener">tbking.eth</a>. I’ll give a brief intro about IPFS and why hosting static content there makes sense. If you are already familiar with IPFS, you can skip to the <a href="#Hosting-on-IPFS">hosting part</a>.</p><h2 id="What-is-IPFS"><a href="#What-is-IPFS" class="headerlink" title="What is IPFS"></a>What is IPFS</h2><p>Inter-Planetary File System is a decentralized network of shared content. It has a very simple yet interesting design philosophy:</p><blockquote><p>Build a network that works inter planets, and it will be a better network for communication across Earth too.</p></blockquote><p>IPFS is a decentralized network where peers are connected and share files, in many ways like BitTorrent. The fundamental principle is that unlike the traditional web, where files are served based on their location, in IPFS files are served based on their content. Consider this comparison:</p><p>Google’s privacy policy is identified as a file hosted on Google’s servers on the address <a href="https://policies.google.com/privacy" target="_blank" rel="noopener">https://policies.google.com/privacy</a>. The content of the policy doesn’t matter. This is called <strong><code>location-addressing</code></strong>.<br>On the other hand, IPFS identifies files by their content, using the hash of the file. Let’s say you want to read the “<em>XKCD #327 - Exploits of a Mom</em>“. Its IPFS address is <a href="https://ipfs.io/ipfs/QmZVjV5jFV7Jo4Hfj6WPyRnHCxf8kbadkqtQBco2gef64x/" target="_blank" rel="noopener">https://ipfs.io/ipfs/QmZVjV5jFV7Jo4Hfj6WPyRnHCxf8kbadkqtQBco2gef64x/</a>. This address doesn’t depend on the location of the server but the hash. This is called <strong><code>content-addressing</code></strong>. Whoever cares about XKCD, can host it. This makes <a href="https://en.wikipedia.org/wiki/Link_rot" target="_blank" rel="noopener">broken links</a> unlikely, which is also one of the goals of IPFS.</p><p><a href="https://docs-beta.ipfs.io/concepts/" target="_blank" rel="noopener">IPFS docs</a> explain these concepts well. I recommend them to anyone who wants to dig deeper.</p><h2 id="Hosting-on-IPFS"><a href="#Hosting-on-IPFS" class="headerlink" title="Hosting on IPFS"></a>Hosting on IPFS</h2><p>Deploying static content such as personal websites on IPFS is easy. The steps I’m listing below can be used for any file such as a plain HTML file, a website generated by static site generators like Jekyll, Hugo, Hexo, and Gatsby or even a media file. So let’s dive in.</p><h3 id="Adding-files"><a href="#Adding-files" class="headerlink" title="Adding files"></a>Adding files</h3><h4 id="IPFS-Desktop"><a href="#IPFS-Desktop" class="headerlink" title="IPFS Desktop"></a>IPFS Desktop</h4><p>If you have <a href="https://github.com/ipfs-shipyard/ipfs-desktop" target="_blank" rel="noopener">IPFS Desktop</a> installed and running, you can add your files using a normal file selector. Just import the directory which has the contents of your static website.</p><p><img src="/data/images/Deploy-your-website-on-IPFS-Why-and-How/ipfs-desktop-file-add.png" alt="Adding file in IPFS Desktop"></p><p>Right-click on the newly added content and select <code>Copy CID</code>. Open <code>https://ipfs.io/ipfs/&lt;cid&gt;</code> to see our files on the web! 🚀</p><p>Easy right? 😀</p><h4 id="IPFS-CLI"><a href="#IPFS-CLI" class="headerlink" title="IPFS CLI"></a>IPFS CLI</h4><p><a href="https://dist.ipfs.io/#go-ipfs" target="_blank" rel="noopener">IPFS CLI</a> allows adding of files and directories using <code>add</code> subcommand.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ipfs add -r .&#x2F;sample_website</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">added QmaYZE5QQVR3TqQSL5WDcwuxUwBqczbMkmbHeoeNEAumbe sample_website&#x2F;index.css</span><br><span class="line">added Qme5TzVW4en8HWP49N9nLHwUkAMhCn6zvWteoknmFDhwJg sample_website&#x2F;index.html</span><br><span class="line">added QmThzr7LgYmUz6tfTArJK5tbrtidXSA12ZCL4ESy6HB8P2 sample_website&#x2F;index.js</span><br><span class="line">added QmSYDncaMte6GPx5jC7kqeXWnrKsCp4nkLfQXPxiAKtECU sample_website&#x2F;something.html</span><br><span class="line">added QmeUG2oZvyx4NzfpP9rruKbmV5UNDmTQ8MoxuhTJGVZVTW sample_website</span><br><span class="line"> 1.01 KiB &#x2F; 1.01 KiB [&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;] 100.00%</span><br></pre></td></tr></table></figure><p> The hash printed in the last line is the CID for the whole directory and thus our website. We can see the sample website hosted on <a href="https://ipfs.io/ipfs/QmeUG2oZvyx4NzfpP9rruKbmV5UNDmTQ8MoxuhTJGVZVTW/" target="_blank" rel="noopener">https://ipfs.io/ipfs/QmeUG2oZvyx4NzfpP9rruKbmV5UNDmTQ8MoxuhTJGVZVTW/</a></p><blockquote><p>TIP: It is important to use relative links in your website since IPFS gateways have a URL which looks like <code>&lt;gateway&gt;/ipfs/&lt;cid&gt;/file.ext</code>.</p></blockquote><h3 id="Pinning"><a href="#Pinning" class="headerlink" title="Pinning"></a>Pinning</h3><p>In the last section, we added files to <strong>our</strong> IPFS node for the network to find. This is why the IPFS gateway was able to resolve it and show it in the browser. But the site will most likely become unreachable once you shut down your IPFS daemon. Even though, after requesting some content on IPFS, the receiving node also becomes a host of the content, but the content will be garbage collected after 12 hours. How to serve your site round the clock in a decentralized web without a server?</p><p>Welcome, <a href="https://docs.ipfs.io/guides/concepts/pinning/" target="_blank" rel="noopener">Pinning</a>!</p><p>A node that pins some content on IPFS hosts it forever (until it unpins it). There are pinning services like <a href="https://pinata.cloud/" target="_blank" rel="noopener">Pinata</a> which pin the files on their IPFS nodes. This way the website is available always.<br>In Pinata, you can either upload a file or just provide it’s hash if the content has already been uploaded to IPFS. Here’s how I pinned the sample website we uploaded above.</p><p><img src="/data/images/Deploy-your-website-on-IPFS-Why-and-How/pinata-pin-example.png" alt="Pinata pinning example"></p><blockquote><p>TIP: It is good to pin your site using multiple pinning services for redundancy.</p></blockquote><h3 id="Automated-deployments"><a href="#Automated-deployments" class="headerlink" title="Automated deployments"></a>Automated deployments</h3><p>As you might have noticed already, using IPFS is very easy. I would go as far as to say it’s easier than dealing with the traditional web that we use. However, this process has to be repeated every time you want to change your files which is not very ideal. There are tools like <a href="https://fleek.co/" target="_blank" rel="noopener">Fleek</a> which help in automating all the steps listed above.</p><p>Fleek is like Travis or CircleCi for IPFS deployments. You can link your Github account with it and using the Github hooks, Fleek will trigger a deployment on every push to the Github repository. They also pin everything they deploy.</p><p>So I use Hexo to generate this blog and I was able to add a build step in the Fleek dashboard itself so that I don’t need to generate the HTML and push to my repository. Here’s the build command that I use:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git submodule update --recursive --init &amp;&amp; npm i &amp;&amp; npm run build</span><br></pre></td></tr></table></figure><p>Yes, I needed to install the submodules myself. They don’t do that by default (yet). Check it out, it’s super easy.</p><h3 id="Link-to-a-domain"><a href="#Link-to-a-domain" class="headerlink" title="Link to a domain"></a>Link to a domain</h3><p>So now we have our site up and running, but content on IPFS is not as easy to look up as on the traditional web. My site can be found at <a href="https://tarunbatra.com">https://tarunbatra.com</a>. But on IPFS, the <em>current version</em> can be accessed at <a href="https://ipfs.io/ipfs/QmTPTa1ddoSkuakaW56SaL9dicbC71BbwfjRbVjasshCXs/" target="_blank" rel="noopener">https://ipfs.io/ipfs/QmTPTa1ddoSkuakaW56SaL9dicbC71BbwfjRbVjasshCXs/</a>.<br>You see the problem. This is not human readable. And the CID changes after every update. There are 2 solutions to this:</p><h4 id="DNSLink"><a href="#DNSLink" class="headerlink" title="DNSLink"></a>DNSLink</h4><p>With <a href="https://docs.ipfs.io/guides/concepts/dnslink/" target="_blank" rel="noopener">DNSLink</a>, you can point a normal domain to an IPFS content. It can be set up on Fleek very easily. I’ve pointed <a href="http://ipfs.tarunbatra.com" target="_blank" rel="noopener">ipfs.tarunbatra.com</a> to the IPFS version using Fleek and you’ll be able to open this site.</p><p>IPNS (Inter-Planetary Name Service) also exists and is similar to DNSLink but it’s much slower right now.</p><h4 id="Ethereum-Name-Service"><a href="#Ethereum-Name-Service" class="headerlink" title="Ethereum Name Service"></a>Ethereum Name Service</h4><p><a href="https://ens.domains/" target="_blank" rel="noopener">ENS</a> is a naming service that lives on Ethereum blockchain and uses smart contracts to buy domains and set resolver records to them. Since Ethereum is involved, you’d need <a href="https://metamask.io/" target="_blank" rel="noopener">MetaMask</a> to use it.</p><p><img src="/data/images/Deploy-your-website-on-IPFS-Why-and-How/ens-records.png" alt="ENS records for tbking.eth"></p><p>I bought the domain <code>tbking.eth</code> and pointed it to the IPFS CID of this site. With changing content, the resolver record of the domain also needs to be updated every time to point at the new CID. Good thing is, Fleek has <a href="https://blog.fleek.co/posts/Fleek-Release-ENS-Domains" target="_blank" rel="noopener">recently</a> integrated ENS. You can set Fleek as a controller for the domain and they will update the record automatically on each deploy.</p><p>Sweet! This was it. IPFS is perfect as the storage layer of the <code>Web 3.0</code>. Try for yourself, and if you liked this blog, share it, and maybe pin it! :)</p>]]></content>
    
    <summary type="html">
    
      I deployed my website on the Web3 using IPFS and ENS. Here I&#39;m detailing why that makes sense and how to do it.
    
    </summary>
    
    
      <category term="decentralization" scheme="https://tarunbatra.com/categories/decentralization/"/>
    
    
      <category term="ipfs" scheme="https://tarunbatra.com/tags/ipfs/"/>
    
      <category term="web3" scheme="https://tarunbatra.com/tags/web3/"/>
    
      <category term="ens" scheme="https://tarunbatra.com/tags/ens/"/>
    
  </entry>
  
  <entry>
    <title>How to choose between Kafka and RabbitMQ</title>
    <link href="https://tarunbatra.com/blog/comparison/How-to-choose-between-Kafka-and-RabbitMQ/"/>
    <id>https://tarunbatra.com/blog/comparison/How-to-choose-between-Kafka-and-RabbitMQ/</id>
    <published>2019-10-12T02:00:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sup>Image sourced from “<a href="https://www.cloudamqp.com/blog/2017-01-09-apachekafka-vs-rabbitmq.html" target="_blank" rel="noopener">Comparison: Apache Kafka VS RabbitMQ</a>“ by <a href="https://www.cloudamqp.com/" target="_blank" rel="noopener">CloudAMQP</a>.</sup></p><p>Kafka and RabbitMQ – These two terms are frequently thrown around in tech meetings discussing distributed architecture. I have been part of a series of such meetings where we discussed their pros and cons, and whether they fit our needs or not. Here’s me documenting my findings for others and my future self.</p><p><em>Spoiler: We ended up using both for different use-cases.</em></p><h2 id="Message-Routing"><a href="#Message-Routing" class="headerlink" title="Message Routing"></a>Message Routing</h2><p>With respect to message routing capabilities, Kafka is very light. Producers produce messages to topics. Topics can further have partitions (like sharding). Kafka logs the messages in its very simple data structure which resembles… a log! It can scale as much as the disk can.<br>Consumers connect to these partitions to read the messages. Kafka uses a pull-based approach, so the onus of fetching messages and tracking offsets of read messages lies on consumers.</p><p><strong>RabbitMQ has very strong routing capabilities</strong>. It can route the messages through a complex system of exchanges and queues. Producers send messages to exchanges which act according to their configurations. For example, they can broadcast the message to every queue connected with them, or deliver the message to some selected queues, or even expire the messages if not read in a stipulated time.<br>Exchanges can also pass messages to other exchanges, making a wide variety of permutations possible. Consumers can listen to messages in a queue or a pattern of queues. Unlike Kafka, RabbitMQ pushes the messages to the consumers, so the consumers don’t need to keep track of what they have read.</p><p><img src="/data/images/How-to-choose-between-Kafka-and-RabbitMQ/rabbitmq-system.gif" alt="&#39;RabbitMQ routing simulation&#39;"></p><center><sup>RabbitMQ routing simulated using http://tryrabbitmq.com</sup></center>- - -<h2 id="Delivery-guarantee"><a href="#Delivery-guarantee" class="headerlink" title="Delivery guarantee"></a>Delivery guarantee</h2><p>Distributed systems can have 3 delivery semantics:</p><ul><li><p><em>at-most-once delivery</em></p><p>  In case of failure in message delivery, no retry is done which means data loss can happen, but data duplication can not. This isn’t the most used semantic due to obvious reasons.</p></li><li><p><em>at-least-once delivery</em></p><p>  In case of failure in message delivery, retries are done untill delivery is successfully acknowledged. This ensures no data is lost but this can result in duplicated delivery.</p></li><li><p><em>exactly-once delivery</em></p><p>  Messages are ensured to be delivered exactly once. This is the most desirable delivery semantic and almost <a href="https://bravenewgeek.com/you-cannot-have-exactly-once-delivery/" target="_blank" rel="noopener">impossible to achieve</a> in a distributed enviornment.</p></li></ul><blockquote><p>Both Kafka and RabbitMQ offer at-most-once and at-least-once delivery guarantees.</p></blockquote><p>Kafka provides exactly-once delivery between producer to the broker using idempotent producers (<code>enable.idempotence=true</code>). Exactly-once message delivery to the consumers is more complex. It is achieved at consumers end by using transactions API and only reading messages belonging to committed transactions (<code>isolation.level=read_committed</code>).<br>To truly achieve this, consumers would need to avoid non-idempotent processing of messages in case a transaction has to be aborted, which is not always possible. <strong>So, Kafka transactions are not very useful in my opinion.</strong></p><p>In RabbitMQ, exactly-once delivery is not supported due to the combination of complex routing and the push-based delivery. Generally, it’s recommended to use at-least-once delivery with idempotent consumers.</p><p><sub><em><br>NOTE: Kafka Streams is an example of truely idempotent system, which it achieves by eliminating non-idempotent operations in a transaction. It, however is out of the scope of this article. I recommend reading <a href="https://www.confluent.io/blog/enabling-exactly-once-kafka-streams/" target="_blank" rel="noopener">“Enabling Exactly-Once in Kafka Streams” by Confluent</a> if you want to dig in it further.<br></em></sub></p><hr><h2 id="Throughput"><a href="#Throughput" class="headerlink" title="Throughput"></a>Throughput</h2><p>Throughput of message queues depends on many variables like message size, number of nodes, replication configuration, delivery guarantees, etc. I will be focussing on the speed of messages produced versus consumed. The two cases which arise are:</p><ul><li>Queue is empty due to messages being consumed as and when they are produced.</li><li>Queue is backed up due to consumers being offline or producers being faster than consumers.</li></ul><p>RabbitMQ stores the messages in DRAM for consumption. In the case where consumers are not far behind, the messages are served quickly from the DRAM. Performance takes a hit when a lot of messages are unread and the queue is backed up. In this case, the messages are pushed to disk and reading from it is slower. So, RabbitMQ works faster with empty queues.</p><p>Kafka uses sequential disk I/O to read chunks of the log in an orderly fashion. Performance improves further in case fresh messages are being consumed, as the messages are served from the OS page cache without any I/O reads. However, it should be noted that implementing transactions as discussed in last section will have <em>negative effect</em> on the throughput.</p><blockquote><p>Overall, <strong>Kafka can process millions of messages in a second and is faster than RabbitMQ</strong>. Whereas, RabbitMQ can process upwards of 20k messages per second.</p></blockquote><hr><h2 id="Persistence"><a href="#Persistence" class="headerlink" title="Persistence"></a>Persistence</h2><p>Persistence of messages is another front where both of these tools can not be more different.</p><p>Kafka is designed with persistent (or retention as they call it) in mind. A Kafka system can be configured to retain messages – both delivered and undelivered, by configuring either <code>log.retention.hours</code> or <code>log.retention.bytes</code>.<br>Retaining messages doesn’t effect the performance of Kafka. The consumers can replay retained messages by changing the offset of messages they have read.</p><p>RabbitMQ on the other hand, works very differently. Messages when delivered to multiple queues, are duplicated in these queues. These copies are then governed independently of each other by the policy of the queues they are in, and the exchanges they are passing. So to persist the messages in RabbitMQ:</p><ul><li>queues and exchanges need to be made durable,</li><li>messages produced need to be tagged as persistent by the producer</li></ul><p>Not to mention, this will have performance impact since disk is involved in an otherwise memory operation.</p><hr><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><blockquote><p>RabbitMQ offers complex routing use-cases which can not be realized with Kafka’s simple architecture. However, Kafka provides higher throughput and persistence of messages.</p></blockquote><p>Apart from these differences, both of them provide similar capabilities like fault-tolerance, high availability, scalability, etc. Keeping this in mind, we at <a href="https://smallcase.com" target="_blank" rel="noopener">smallcase</a> used RabbitMQ for <a href="https://medium.com/making-smalltalk/polling-reliably-at-scale-using-dlqs-841512659c8f" target="_blank" rel="noopener">consistent polling in our transactions system</a> and Kafka for making our notifications system quick and snappy.</p><h2 id="References"><a href="#References" class="headerlink" title="References"></a>References</h2><ul><li><a href="https://content.pivotal.io/blog/understanding-when-to-use-rabbitmq-or-apache-kafka" target="_blank" rel="noopener">Understanding When to Use RabbitMQ or Apache Kafka</a></li><li><a href="https://blog.mavenhive.in/which-one-to-use-and-when-rabbitmq-vs-apache-kafka-7d5423301b58" target="_blank" rel="noopener">A comparison between RabbitMQ and Apache Kafka</a></li><li><a href="https://www.confluent.io/blog/transactions-apache-kafka/" target="_blank" rel="noopener">Transactions in Apache Kafka</a></li><li><a href="https://arxiv.org/abs/1709.00333" target="_blank" rel="noopener">Kafka versus RabbitMQ</a></li></ul>]]></content>
    
    <summary type="html">
    
      Kafka and RabbitMQ are two very popular message queues based on very different design principles. Which one of these suits your project?
    
    </summary>
    
    
      <category term="comparison" scheme="https://tarunbatra.com/categories/comparison/"/>
    
    
      <category term="rabbitmq" scheme="https://tarunbatra.com/tags/rabbitmq/"/>
    
      <category term="kafka" scheme="https://tarunbatra.com/tags/kafka/"/>
    
      <category term="message-queue" scheme="https://tarunbatra.com/tags/message-queue/"/>
    
  </entry>
  
  <entry>
    <title>Polling reliably at scale using DLQs</title>
    <link href="https://tarunbatra.com/blog/architecture/Polling-reliably-at-scale-using-DLQs/"/>
    <id>https://tarunbatra.com/blog/architecture/Polling-reliably-at-scale-using-DLQs/</id>
    <published>2019-07-16T09:00:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sub>Originally published at <a href="https://blog.smallcase.com/polling-reliably-at-scale-using-dlqs/" target="_blank" rel="noopener">blog.smallcase.com</a> on July 16, 2019.</sub><br><br></p><p>Execution of computer programs is blazing fast. It’s only practical to need some delay in execution. Some of such use cases are:</p><ul><li>scheduling a task for sometime in future;</li><li>retrying a failed task with a backoff stratagy</li></ul><p>At smallcase, we place orders to buy or sell equities on clients’ behalf. When the order is placed, it’s execution status is not immediately known. We need to poll the partner broker to know the status of order on the exchange.</p><p>Intraday traders will tell you that stock markets are time sensitive. Any platform that caters to them needs to be fast and deterministic. Polling for order status needs to happen in a timely manner after regular intervals because an endless loading is never a pleasant sight.</p><p><img src="https://media.giphy.com/media/OQHGckzXXDHZbuH1cN/giphy.gif" alt="&#39;Loading&#39;"></p><blockquote><p>This blog explains the reliability issues we faced with our legacy system for scheduling polling and how we fixed it.</p></blockquote><h2 id="Delay-mechanisms"><a href="#Delay-mechanisms" class="headerlink" title="Delay mechanisms:"></a>Delay mechanisms:</h2><p>We will discuss the following delay mechanisms we used in our platform:</p><ul><li><a href="#Redis-Keyspace-Notifications">Redis Keyspace Notifications</a></li><li><a href="#In-memory-Timers">In-memory Timers</a></li><li><a href="#Dead-Letter-Queues">Dead Letter Queues</a></li></ul><h3 id="Redis-Keyspace-Notifications"><a href="#Redis-Keyspace-Notifications" class="headerlink" title="Redis Keyspace Notifications"></a>Redis Keyspace Notifications</h3><p>This approach is very simple. We heavily use Redis in our stack, so it was easy for us to use it for scheduling triggers. Redis allows to set keys with expiry using its <a href="https://redis.io/commands/setex" target="_blank" rel="noopener">SETEX</a> command. For instance, setting a key <code>TESTKEY</code> with value <code>TESTVALUE</code> and expiry of 10 seconds can be achieved with:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;redis SETEX TESTKEY 10 <span class="string">"TESTVALUE"</span></span><br></pre></td></tr></table></figure><p>Parallely, Redis provides <a href="https://redis.io/topics/notifications" target="_blank" rel="noopener">Keyspace notifications</a> for data changing events which can be subscribed by clients and can be used to trigger the delayed tasks. Key expiry events can be subscribed using:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SUBSCRIBE __keyevent@0__:expired</span><br></pre></td></tr></table></figure><h4 id="Pros"><a href="#Pros" class="headerlink" title="Pros:"></a>Pros:</h4><ol><li><strong>Stateless application code.</strong><br> The application doesn’t need to store the tasks to perform and delays in its memory. It is outsourced to Redis.</li><li><strong>Arbitrary delays.</strong><br> Delays of arbitrary length are possible without any extra configuration. Just changing the <code>ttl</code> paramter of <code>SETEX</code> command will work.</li></ol><h4 id="Cons"><a href="#Cons" class="headerlink" title="Cons:"></a>Cons:</h4><ol><li><strong>Unscalable.</strong><br> This strategy works only till there’s only one instance of the application listening to these events. In case this application is to be horizontally scaled, each instance of the application will receive the event because of its <a href="https://redis.io/topics/pubsub" target="_blank" rel="noopener">publish-subscribe nature</a>.</li><li><strong>Unreliable.</strong><br> The keyspace notifications can get highly unreliable as the number of keys increase. This is clearly mentioned in the docs:<blockquote><p>If no command targets the key constantly, and there are many keys with a TTL associated, there can be a significant delay between the time the key time to live drops to zero, and the time the expired event is generated.</p></blockquote></li></ol><p>This worked fine for us in the beginning. But once the orders increased, a lot of clients started reporting really long waiting periods before they could see the status of their orders. On debugging, we saw delays of the tune of 40x and this was the deal breaker for us.</p><hr><h3 id="In-memory-Timers"><a href="#In-memory-Timers" class="headerlink" title="In-memory Timers"></a>In-memory Timers</h3><p>As a quick fix to this we used in-process timers. Timers are defined and executed by the application code itself and can be used to manage delays. Node.js provides a variety of in-built <a href="https://nodejs.org/en/docs/guides/timers-in-node/" target="_blank" rel="noopener">timer functions</a>. Setting a 10 second timer is as simple as:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'This executes after 10 seconds'</span>);</span><br><span class="line">&#125;, <span class="number">10</span> * <span class="number">1000</span>);</span><br></pre></td></tr></table></figure><h4 id="Pros-1"><a href="#Pros-1" class="headerlink" title="Pros:"></a>Pros:</h4><ol><li><strong>Arbitrary delays.</strong><br> Delay time is controlled by the time argument only. Passing the required delay time in milliseconds is all that is required.</li><li><strong>Reliability.</strong><br> Timers in code are quite reliable. Deviation of only upto few milliseconds is observed.</li></ol><h4 id="Cons-1"><a href="#Cons-1" class="headerlink" title="Cons:"></a>Cons:</h4><ol><li><strong>Stateful application code.</strong><br> The application adds to its state whenever a timer is set up. It also increases memory footprint of the application.</li><li><strong>Unscalable.</strong><br> In-memory timers do not work well with horizontal scaling. Timer will always trigger the instance which set it in the first place, irrespective of the traffic distribution across the instances.</li></ol><p>Timers worked well to mask the problem until we had bandwidth to think about the problem and fix it for good. Now we needed a permanent and reliable solution that would scale.</p><hr><h3 id="Dead-Letter-Queues"><a href="#Dead-Letter-Queues" class="headerlink" title="Dead Letter Queues"></a>Dead Letter Queues</h3><p>After researching a bit about this topic, we decided to try Dead letter queues. DLQ is a sophisticated but robust way to delay message delivery used in message queues like Amazon SQS, RabbitMQ and ActiveMQ.</p><p>In very basic terms, a message with an expiry is put into a queue. The queue is instructed to take some action if the messages are expired without being read. We can instruct these expired messages to be pushed to a different queue which is actively consumed by the target application and it simulates sdelayed delivery of message. Following diagram explains this concept:</p><p><img src="/data/images/Polling-reliably-at-scale-using-DLQs/architecture.png" alt="&#39;DLQ architecture diagram&#39;"></p><div align=center><sub>Polling delay mechanism</sub></div><p>We chose RabbitMQ based on AMQP 0-9-1 for our implementation due to maturity of the protocol and its community.</p><h4 id="Pros-2"><a href="#Pros-2" class="headerlink" title="Pros:"></a>Pros:</h4><ol><li><p><strong>Stateless application code.</strong><br> The application doesn’t need to store any state. The messages in the queue represent staete in this case.</p></li><li><p><strong>Scalable.</strong><br> Unlike redis events, message delivery in MQs can be configured to use <a href="https://www.rabbitmq.com/tutorials/tutorial-two-javascript.html" target="_blank" rel="noopener">worker pattern</a> which loadbalances the consumers (subscribing instances of the application)  to deliver the message.</p><p> <img src="https://www.rabbitmq.com/img/tutorials/python-two.png" alt="&#39;RabbitMQ worker pattern&#39;"></p> <div align=center><sub>Source: RabbitMQ docs</sub></div></li><li><p><strong>Reliability.</strong><br> Message Queues are expected to be highly reliable in delivery of messages. In our testing with RabbitMQ, the results were found to be close to in-memory timers.</p></li></ol><h4 id="Cons-2"><a href="#Cons-2" class="headerlink" title="Cons:"></a>Cons:</h4><ol><li><strong>Fixed delays.</strong><br> In RabbitMQ’s implementation of DLQs, the TTL is bound to the queue and applies to all the incoming messages. There is a way to set message level TTL but it has its own <a href="https://www.rabbitmq.com/ttl.html#per-message-ttl-caveats" target="_blank" rel="noopener">caveats</a>. One of the most serious side-effects of using message-level TTL is that a message with higher TTL will block the queue and delay the processing of messages with lower TTL behind it, which is a bigger problem. Hence, we are using DLQs with queue level TTL.</li></ol><p>The chart shown below analyzes the average delay observed in resolving the orders we handled in the past year and its relation with the delay mechanism being used.<br><img src="/data/images/Polling-reliably-at-scale-using-DLQs/chart.png" alt="&#39;Result chart&#39;"></p><div align=center><sub>Graph showing consistency in the polling scheduled using RabbitMQ DLQs</sub></div><p>It is clear that the polling delay in Redis was large but consistent to start with but grew out of proportions quickly as the volumes increased. This was quickly fixed using timers but like all quick-fixes, it had a short life too. Finally, we revamped our systems and used DLQs.</p><blockquote><p>It is evident from the graph that DLQs brought consistency to the system.</p></blockquote><p>We traded flexibility with robustness and reliability by using DLQs to manage the delays in our polling for order status. If you’ve solved a related problem in any other way, do let us know in the comments.<br><br></p><p><strong>❤️ code</strong></p>]]></content>
    
    <summary type="html">
    
      How we bid goodbye to long waiting times during order execution on smallcase platform.
    
    </summary>
    
    
      <category term="architecture" scheme="https://tarunbatra.com/categories/architecture/"/>
    
    
      <category term="architecture" scheme="https://tarunbatra.com/tags/architecture/"/>
    
      <category term="rabbitmq" scheme="https://tarunbatra.com/tags/rabbitmq/"/>
    
      <category term="message-queue" scheme="https://tarunbatra.com/tags/message-queue/"/>
    
  </entry>
  
  <entry>
    <title>Restore deleted MongoDB documents using Oplog</title>
    <link href="https://tarunbatra.com/blog/data/Restore-deleted-MongoDB-documents-using-Oplog/"/>
    <id>https://tarunbatra.com/blog/data/Restore-deleted-MongoDB-documents-using-Oplog/</id>
    <published>2018-06-14T23:05:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sup>Source: <a href="http://dilbert.com/strip/2013-07-05" target="_blank" rel="noopener">Dilbert</a></sup></p><p>Recently I found myself trying to restore corrupted data to it’s original form. A query gone wrong had erased valuable data from a MongoDB collection and it needed to be restored. This blog is a means to note my learnings from that incident for my future self and others.</p><h4 id="Oplog-is-amazing"><a href="#Oplog-is-amazing" class="headerlink" title="Oplog is amazing"></a>Oplog is amazing</h4><p>If you’re using a MongoDB replica set, you can use MongoDB Oplog to undo almost any type of <em>recent</em> data loss. If you never heard of it, go read the docs as I’ll skip to the restoring part.</p><blockquote><p>The oplog is a special capped collection that keeps a rolling record of all operations that modify the data stored in your databases.</p><footer><strong>MongoDB</strong><cite><a href="https://docs.mongodb.com/manual/core/replica-set-oplog/" target="_blank" rel="noopener">Official docs</a></cite></footer></blockquote><h2 id="Restore-backup"><a href="#Restore-backup" class="headerlink" title="Restore backup"></a>Restore backup</h2><p>Restore whatever latest backup you have before the the data was corrupted. It’ll be used as a base. Make sure the oplog has operations from or before the time the backup was taken, otherwise the restore may not work.</p><h2 id="Find-the-faulty-query-queries"><a href="#Find-the-faulty-query-queries" class="headerlink" title="Find the faulty query/queries"></a>Find the faulty query/queries</h2><p>Now you need to browse the contents of the Oplog and look for the query which corrupted the data in the first place. Oplog is a special collection, but still a collection. So, you can query it to narrow down your results like this:</p><figure class="highlight plain"><figcaption><span>mongodb shell</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Replica:PRIMARY&gt; use local</span><br><span class="line">switched to db local</span><br><span class="line">Replica:PRIMARY&gt; db.oplog.rs.find()</span><br></pre></td></tr></table></figure><p>Let’s say you found the query and it looked like:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">...</span><br><span class="line">&#123; <span class="string">"ts"</span> : Timestamp(<span class="number">1528225054</span>, <span class="number">1</span>), <span class="string">"t"</span> : NumberLong(<span class="number">1</span>), <span class="string">"h"</span> : NumberLong(<span class="string">"3208671813197906204"</span>), <span class="string">"v"</span> : <span class="number">2</span>, <span class="string">"op"</span> : <span class="string">"d"</span>, <span class="string">"ns"</span> : <span class="string">"test.foo"</span>, <span class="string">"ui"</span> : UUID(<span class="string">"348dd681-e0df-4d6b-bd69-304d21cf8235"</span>), <span class="string">"wall"</span> : ISODate(<span class="string">"2018-06-05T18:57:34.245Z"</span>), <span class="string">"o"</span> : &#123; <span class="string">"_id"</span> : ObjectId(<span class="string">"5b16dd0d5861982c59fedefe"</span>) &#125; &#125;</span><br><span class="line">...</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>Note down the value of field <code>ts</code>. It will be needed later.</p><h2 id="Take-a-dump-of-oplog"><a href="#Take-a-dump-of-oplog" class="headerlink" title="Take a dump of oplog"></a>Take a dump of oplog</h2><p>Before you can restore your your from oplog, you need to dump it to a file.</p><figure class="highlight sh"><figcaption><span>mongodump</span><a href="https://docs.mongodb.com/manual/reference/program/mongodump/" target="_blank" rel="noopener">docs</a></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mongodump -d &lt;DBNAME&gt; -c oplog.rs -o oplogD</span><br><span class="line">mkdir oplogR</span><br><span class="line">mv oplogD/&lt;DBNAME&gt;/oplog.rs.bson oplogR/oplog.bson</span><br></pre></td></tr></table></figure><p>Now you have a dump of the oplog in <code>oplogR/oplog.bson</code>.</p><h2 id="Restore-from-Oplog"><a href="#Restore-from-Oplog" class="headerlink" title="Restore from Oplog"></a>Restore from Oplog</h2><p>You want to restore the data prior to the faulty write operation.</p><figure class="highlight sh"><figcaption><span>mongorestore</span><a href="https://docs.mongodb.com/manual/reference/program/mongorestore/" target="_blank" rel="noopener">docs</a></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongorestore --oplogReplay --oplogLimit 1528225054:1 oplogR</span><br></pre></td></tr></table></figure><p>The value of <code>oplogLimit</code> paramter is the <code>ts</code> property of the faulty query you noted earier.</p><p><strong>Mongo oplog is <em>idempotent</em>, i.e. it can be applied multiple times without duplicating data. This is why you need not give <code>mongorestore</code> a start time.</strong></p><h2 id="Selective-restore"><a href="#Selective-restore" class="headerlink" title="Selective restore"></a>Selective restore</h2><p>The previous method helps when the good and bad operations are clearly separated by time. But that’s not the case mostly. It’s likely that the good and bad writes happened around the same time.</p><p>Here, you need to remember that Oplog is a collection too, and in addition to be queried on, it can also be modified. You need to copy oplog to an uncapped collection and delete the bad write operations.</p><p>After you’ve removed all bad operations you can continue the restoration process from <a href="#Take-a-dump-of-oplog">a dump of the modified oplog</a>. But this time, no limit argument would be required.</p><p>Hope this helps!<br><br></p><p><strong>❤️ code</strong><br><br></p><hr><p><sub><em>This post is inpired from resources like <a href="https://stackoverflow.com/a/15451297/2751596" target="_blank" rel="noopener">Asya’s stackoverflow answer</a> which was used to solve the problem at hand.</em></sub></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;sup&gt;Source: &lt;a href=&quot;http://dilbert.com/strip/2013-07-05&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Dilbert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Recently I found mysel
      
    
    </summary>
    
    
      <category term="data" scheme="https://tarunbatra.com/categories/data/"/>
    
    
      <category term="data" scheme="https://tarunbatra.com/tags/data/"/>
    
      <category term="mongo" scheme="https://tarunbatra.com/tags/mongo/"/>
    
  </entry>
  
  <entry>
    <title>Error messages in login process: Privacy and Security</title>
    <link href="https://tarunbatra.com/blog/security/Error-messages-in-login-process-Privacy-and-Security/"/>
    <id>https://tarunbatra.com/blog/security/Error-messages-in-login-process-Privacy-and-Security/</id>
    <published>2018-04-28T22:44:03.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p>Most of us, while developing sites swear to the rule of making error messages shown to the end-user as specific as possible, which goes a long way in creating a friendly UX. But the same rule if used in the login flow, can have significant privacy and security implications. On entering wrong login credentials, most sites show variations of <code>Invalid username/password</code> error at the login screen.</p><p><img src="/data/images/Error-messages-in-login-process-Privacy-and-Security/twitter-github-spotify.png" alt="&#39;Twitter, Github and Spotify&#39;s login error messages&#39;"></p><p>It can be safely assumed that no user for such emails exists, yet the error messages shown by these prominent sites don’t indicate that. Do you see why?</p><h2 id="Protecting-user-base-information"><a href="#Protecting-user-base-information" class="headerlink" title="Protecting user base information"></a>Protecting user base information</h2><p>On feeding random emails, a simple login/reset password may show that the user doesn’t exist and therefore no login/reset password is possible. A hostile client may create a list of valid users from this information. Not every site cares about it though. Facebook doesn’t.</p><p><img src="/data/images/Error-messages-in-login-process-Privacy-and-Security/facebook.png" alt="&#39;Facebook login error message&#39;"></p><p>It doesn’t hurt for a site like Facebook to leak the user base because everyone’s on it, but when the site is something like Ashley Maddison it can have implications.</p><h3 id="Closing-the-loop"><a href="#Closing-the-loop" class="headerlink" title="Closing the loop"></a>Closing the loop</h3><p>People often argue that the user base is anyways leaked during the registration process, which can’t continue if the user already exists. This leak is avoidable too, by continuing the registration through an email. If the user already exists the email may say so, otherwise it may direct the receiver to continue the registration process.</p><h2 id="Deterrence-to-brute-force"><a href="#Deterrence-to-brute-force" class="headerlink" title="Deterrence to brute-force"></a>Deterrence to brute-force</h2><p>In a brute-force attack, large number of combinations of usernames and passwords are tried to get into a user’s account. A dictionary attack is faster and better as it takes advantage of human tendencies of using common passwords and re-using old passwords. Specific messages like <code>Invalid username</code> make these attacks faster by eliminating large number of combinations in a few tries.</p><h3 id="Demo"><a href="#Demo" class="headerlink" title="Demo"></a>Demo</h3><p>To quantify the difference detailed error messages can make to brute-force or dictionary attacks, I created a script, <a href="https://github.com/tarunbatra/login-attack-demo" target="_blank" rel="noopener">login-attack-demo</a> which included:</p><h4 id="Dictionary"><a href="#Dictionary" class="headerlink" title="Dictionary"></a>Dictionary</h4><p>A collection of 1575 most commonly used passwords based on <a href="https://github.com/danielmiessler/SecLists/blob/master/Passwords/probable-v2-top1575.txt" target="_blank" rel="noopener">danielmiessler/SecLists</a>.</p><h4 id="Naive-server"><a href="#Naive-server" class="headerlink" title="Naive server"></a>Naive server</h4><p>A server which gives out specific error messages based on the failing stage of the login process. If the username is invalid, it’d say <code>Invalid username</code>.</p><h4 id="Smart-server"><a href="#Smart-server" class="headerlink" title="Smart server"></a>Smart server</h4><p>A server which gives out vague error messages on failure of the login process. If the password is invalid and not the username, it’d still say <code>Invalid username/password</code>.</p><h4 id="Attacker"><a href="#Attacker" class="headerlink" title="Attacker"></a>Attacker</h4><p>A hostile client which uses the dictionary to generate a pair of username and password and uses them to break into the system. It also analyzes the error messages on the following rules:</p><ul><li>An error message saying the password was invalid, indicates the username was a valid one.</li><li>An error message saying the username was invalid, indicates no combination of password will result in a successful login.</li><li>An inconclusive error message is ignored and the next combination is tried.</li></ul><h3 id="Results"><a href="#Results" class="headerlink" title="Results"></a>Results</h3><p><img src="/data/images/Error-messages-in-login-process-Privacy-and-Security/chart.png" alt="&#39;Analysis chart&#39;"></p><p>The blue points indicate the number of tries it took the attacker to break into the user’s account with vague error messages, while the red ones are when the error messages were specific. The yellow line is the max number of combinations to try.</p><p>It is evident that in theory vague error messages make it quite tough for the attacker, sometimes as much as 1000 times tougher. However, plugging all the holes may make the UX far from ideal. In the end, it all comes to trade off between UX and security. Depending on the space you’re operating, such methods can be used to safeguard the users.</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;Most of us, while developing sites swear to the rule of making error messages shown to the end-user as specific as possible, which goes a
      
    
    </summary>
    
    
      <category term="security" scheme="https://tarunbatra.com/categories/security/"/>
    
    
      <category term="security" scheme="https://tarunbatra.com/tags/security/"/>
    
      <category term="architecture" scheme="https://tarunbatra.com/tags/architecture/"/>
    
  </entry>
  
  <entry>
    <title>Getting Started with Microservices</title>
    <link href="https://tarunbatra.com/blog/architecture/Getting-Started-with-microservices/"/>
    <id>https://tarunbatra.com/blog/architecture/Getting-Started-with-microservices/</id>
    <published>2017-07-17T23:00:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sub>Originally published for <a href="https://codebrahma.com/microservices-for-beginners/" target="_blank" rel="noopener">Codebrahma</a> on Jul 18, 2017.</sub></p><p><strong>Microservices</strong> is a vague term which usually points to small independent services which together form up an application. <a href="https://martinfowler.com/articles/microservices.html" target="_blank" rel="noopener">Microservices architecture</a> stands in contrast to Monolithic architecture, where the application is one big system. We will discuss about how to get started as a beginner and choosing the right tools for setting up microservice architechture.</p><h2 id="Rapid-Rise-in-popularity-of-Microservices"><a href="#Rapid-Rise-in-popularity-of-Microservices" class="headerlink" title="Rapid Rise in popularity of Microservices"></a>Rapid Rise in popularity of Microservices</h2><p>Microservices have recently risen into popularity, as suggested by this Google trends index:</p><p><img src="/data/images/Getting-Started-with-microservices/trend.png" alt="&#39;Google trends&#39;"></p><p>“microservices” in Google Trends</p><p>Before getting into what they are, and how to use them, let’s find out why microservices are rising into popularity even though it’s not a new concept. This can be explained by Conway’s Law which states that:</p><blockquote><p>Organisations which design systems … are constrained to produce designs which are copies of the communication structures of these organisations</p></blockquote><p>Until recently majority of companies were used to be giant enterprises, making equally giant enterprise software, or monoliths. Not anymore. Since last 5 years, companies are getting more distributed in nature. In fact, some of the new unicorns like <a href="https://automattic.com/" target="_blank" rel="noopener">Automattic</a> and <a href="https://about.gitlab.com/" target="_blank" rel="noopener">Gitlab</a> are entirely distributed. That explains why microservices are rising in popularity.</p><h2 id="Why-Microservices"><a href="#Why-Microservices" class="headerlink" title="Why Microservices?"></a>Why Microservices?</h2><h3 id="Fewer-compromises-in-tech-stack"><a href="#Fewer-compromises-in-tech-stack" class="headerlink" title="Fewer compromises in tech stack"></a>Fewer compromises in tech stack</h3><p>Choosing a tech stack is always a tough call. Skills of the team, scalability, maintenance are all important factors in this choice. But many times what’s good for one portion of the app, is not good for the other.</p><p>For example, a trading platform needs PostgreSQL due to support for transactions, the user specific data has to be stored in DynamoDB. Generally, a trade off is made. But in Microservices Architecture, <strong>each microservice owns a set of business logic and related data in the form it deem best</strong>, and provide an interface to interact with it. So there can be microservices for trades and users each, with data hosted on PostgreSQL and DynamoDB, and access to external services is allowed only through the interface. So a computation intensive microservice can be written in Python while the API Server remains in NodeJS, and so on.</p><p>A sample architecture would look like</p><p><img src="/data/images/Getting-Started-with-microservices/tech-stack.jpg" alt="&#39;Architecture&#39;"></p><h2 id="Independent-teams"><a href="#Independent-teams" class="headerlink" title="Independent teams"></a>Independent teams</h2><p>In a monolithic application, most of the people in a development team needs to know all the parts of the application even to develop a small feature. They have to collaborate with other teams on deployment schedules, versioning, data migrations, etc. On the other hand, in Microservices Architecture the teams just need to know the interface provided by other services and stick to the interface provided by theirs. Each microservice should be <strong>independently deployable.</strong> CI/CD tools like <a href="https://circleci.com/" target="_blank" rel="noopener">CirclCi</a>, <a href="https://travis-ci.org/" target="_blank" rel="noopener">Travis</a> and <a href="https://www.heroku.com/" target="_blank" rel="noopener">Heroku</a> are of great help while developing microservices. To develop/maintain a service, a small team with limited knowledge is enough.</p><h2 id="Do-one-thing-and-do-it-well"><a href="#Do-one-thing-and-do-it-well" class="headerlink" title="Do one thing and do it well"></a>Do one thing and do it well</h2><p>Microservices Architecture also resembles the Unix philosophy’s principle, Do one thing and do it well. It is a principle which has proved it’s worthiness and is one of the reasons Unix-like systems are not obsolete even after decades. Microservices should be designed to do one thing, tested to handle all the possible scenarios and then <strong>“piped” together to form a robust and flexible application.</strong></p><h2 id="Fault-isolation"><a href="#Fault-isolation" class="headerlink" title="Fault isolation"></a>Fault isolation</h2><p>Imagine error in a report generation module, takes the full trading application down. It’s terrible and unnecessary. If the application is based on microservices, the report generation module will fail, taking down only that specific feature. Users who are not generating reports won’t even notice, and <strong>the critical parts of the application will still be working</strong>. That’s a result of <strong>Loose coupling</strong> between microservices, now achievable through this architecture.</p><p><img src="/data/images/Getting-Started-with-microservices/fault-isolation.jpg" alt="&#39;Fault Isolation&#39;"></p><h2 id="How-to-develop-Microservices"><a href="#How-to-develop-Microservices" class="headerlink" title="How to develop Microservices?"></a>How to develop Microservices?</h2><p>In Node.js, <a href="http://senecajs.org/" target="_blank" rel="noopener">Seneca</a> is a widely used framework to develop microservices. But if you want to get yours hands dirty, read on.</p><h2 id="API-Gateway"><a href="#API-Gateway" class="headerlink" title="API Gateway"></a>API Gateway</h2><p>Microservices can be deployed without a main central service, but sometimes a thin central layer is usually kept to have shared libraries. Sometimes it also works as an API Gateway.<br>An API Gateway is used to provide a consistent API to the client side irrespective of the backend service, and vice versa. It is helpful when you have multiple microservices catering to clients like mobile, web, other servers, etc. Also it prevents client to make requests to multiple services by abstracting it into one request.</p><h2 id="Inter-service-communication"><a href="#Inter-service-communication" class="headerlink" title="Inter-service communication"></a>Inter-service communication</h2><p>How should these services communicate to each other?</p><p><strong>HTTP:</strong> Well, there are plenty of options. Most straightforward is to use HTTP/HTTPS and the interface can be made as RESTful APIs. Though, HTTP makes service discovery difficult and less dynamic. That’s a reason I don’t prefer it.</p><p><strong>Message Queues:</strong> Message Queuing protocols like AMQP, STOMP and MQTT allows the use of publish subscribe pattern for communication between microservices. Services like <a href="https://www.rabbitmq.com/" target="_blank" rel="noopener">RabbitMQ</a> and <a href="https://kafka.apache.org/" target="_blank" rel="noopener">Apache Kafka</a> are widely used for this purpose. I personally prefer using Message Queues as they are <strong>fault tolerant</strong> and support <strong>message persistence</strong>.</p><p><a href="https://github.com/Codebrahma/microservice-template" target="_blank" rel="noopener">microservice-template</a> is a basic boilerplate which we use in our projects based on Microservices. It’s in Node and has MongoDB configured as a data store. It connects to RabbitMQ for inter-service communication via <a href="https://www.npmjs.com/package/servicebus" target="_blank" rel="noopener">servicebus</a>. Here’s how it looks in it’s bare minimum:</p><p><img src="/data/images/Getting-Started-with-microservices/sample-logs.png" alt="&#39;Sample logs&#39;"><br>Microservice booting up and communicating</p><p>There are other concepts like <a href="https://martinfowler.com/eaaDev/EventSourcing.html" target="_blank" rel="noopener">Event Sourcing</a> and <a href="https://martinfowler.com/bliki/CQRS.html" target="_blank" rel="noopener">CQRS</a> which complement the Microservices Architecture. Event Sourcing is basically storing the changes to the data, instead of the changed state of the data. in a highly concurrent environment, <strong>event sourcing brings consistency of a higher order.</strong></p><p><img src="/data/images/Getting-Started-with-microservices/fowler-graph.png" alt="&#39;Fowler Microservices Productivity graph&#39;"></p><p>Productivity in Microservices vs Monolothic Architecture Source: <a href="https://martinfowler.com/bliki/MicroservicePremium.html" target="_blank" rel="noopener">Martin Fowler</a></p><p>But truth be told, Microservices Architecture is no silver bullet. Using microservices for fairly small apps can lead to loss in productivity, as evident in the above graph.<br><br></p><p><strong>❤️ code</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;sub&gt;Originally published for &lt;a href=&quot;https://codebrahma.com/microservices-for-beginners/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Codebrahma&lt;/a&gt;
      
    
    </summary>
    
    
      <category term="architecture" scheme="https://tarunbatra.com/categories/architecture/"/>
    
    
      <category term="architecture" scheme="https://tarunbatra.com/tags/architecture/"/>
    
      <category term="microservices" scheme="https://tarunbatra.com/tags/microservices/"/>
    
  </entry>
  
  <entry>
    <title>Pitfalls of Mocha&#39;s built-in Promise support</title>
    <link href="https://tarunbatra.com/blog/javascript/Pitfalls-of-Mocha-s-built-in-Promise-support/"/>
    <id>https://tarunbatra.com/blog/javascript/Pitfalls-of-Mocha-s-built-in-Promise-support/</id>
    <published>2017-04-19T00:11:12.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://mochajs.org" target="_blank" rel="noopener">Mocha</a> is the leader when it comes to testing frameworks in <a href="https://nodejs.org" target="_blank" rel="noopener">Node</a>, and it’s great. I use it in all my projects, and I’m sure many others do too.</p><p>Mocha added support for Promises back in version <code>1.18.0</code>. Recently while testing asynchronous code written using Promises, I was using the <a href="https://mochajs.org/#working-with-promises" target="_blank" rel="noopener">built-in promise support</a> instead of the old-fashioned callbacks oriented <a href="https://mochajs.org/#asynchronous-code" target="_blank" rel="noopener"><code>done</code> callback</a> and I found my tests were resulting in <strong>false positives</strong>. So here I’m explaining what happened and how to avoid it.</p><h2 id="Problem"><a href="#Problem" class="headerlink" title="Problem"></a>Problem</h2><p>It’s easy to see that there are four possible cases when testing Promises:</p><table><thead><tr><th align="center">Case</th><th align="center">Expectation</th><th align="center">Actual</th><th align="center">Expected test status</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">Resolved</td><td align="center">Resolved</td><td align="center">Pass</td></tr><tr><td align="center">2</td><td align="center">Resolved</td><td align="center">Rejected</td><td align="center">Fail</td></tr><tr><td align="center">3</td><td align="center">Rejected</td><td align="center">Rejected</td><td align="center">Pass</td></tr><tr><td align="center">4</td><td align="center">Rejected</td><td align="center">Resolved</td><td align="center">Fail</td></tr></tbody></table><h3 id="Case-1"><a href="#Case-1" class="headerlink" title="Case 1"></a>Case 1</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.resolve();</span><br><span class="line"></span><br><span class="line">describe(<span class="string">'the promise resolves expectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should PASS the test'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="keyword">return</span> promise.then(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'Promise resolved!'</span>) <span class="comment">//  Called</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-PASS"><a href="#Test-status-PASS" class="headerlink" title="Test status: PASS"></a>Test status: <strong>PASS</strong></h4><p>The test expects the promise to resolve and so it does. The snippet above shows that the test passes expectedly.</p><h3 id="Case-2"><a href="#Case-2" class="headerlink" title="Case 2"></a>Case 2</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.reject(<span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'some-error'</span>));</span><br><span class="line"></span><br><span class="line">describe(<span class="string">'the promise rejects unexpectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should FAIL the test'</span>, () =&gt; &#123; <span class="comment">// =&gt; Error: some-error</span></span><br><span class="line">    <span class="keyword">return</span> promise.then(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'Promise resolved!'</span>) <span class="comment">// Not called</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-FAIL"><a href="#Test-status-FAIL" class="headerlink" title="Test status: FAIL"></a>Test status: <strong>FAIL</strong></h4><p>In the case when test expects the promise to resolve, but it doesn’t, Mocha gracefully fails the test. In the snippet above, the <code>then</code> block was never executed and Mocha detected the error rejected by the code and failed the test.</p><h3 id="Case-3"><a href="#Case-3" class="headerlink" title="Case 3"></a>Case 3</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.reject(<span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'some-error'</span>));</span><br><span class="line">describe(<span class="string">'the promise rejects expectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should PASS the test'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="keyword">return</span> promise.catch(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'Rejected promise caught!'</span>);  <span class="comment">// Called</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-PASS-1"><a href="#Test-status-PASS-1" class="headerlink" title="Test status: PASS"></a>Test status: <strong>PASS</strong></h4><p>The test expects the promise to be rejected and it is caught by the <code>catch</code> block, which results in this test passing as expected.</p><h3 id="Case-4"><a href="#Case-4" class="headerlink" title="Case 4"></a>Case 4</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.resolve();</span><br><span class="line"></span><br><span class="line">describe(<span class="string">'the promise resolves unexpectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should FAIL the test'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="keyword">return</span> promise.catch(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'Rejected promise caught!'</span>) <span class="comment">// Not called</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-FAIL-PASS"><a href="#Test-status-FAIL-PASS" class="headerlink" title="Test status: FAIL PASS"></a>Test status: <del>FAIL</del> <strong>PASS</strong></h4><p>In this case, the test expects the promise to be rejected and the catch block to execute but instead, it doesn’t. The promise resolves. Mocha doesn’t throw an error here!</p><p>So while doing <a href="https://en.wikipedia.org/wiki/Negative_Testing" target="_blank" rel="noopener">Negative Testing</a>, the built-in promises support doesn’t hold up well and can result in <strong>false positives</strong>. This is not a bug and the reason behind this behavior totally makes sense, once given a careful thought, but at the very least, it’s not intuitive and causes the tests to pass even when they shouldn’t.</p><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><h3 id="Good-ol’-done-callback"><a href="#Good-ol’-done-callback" class="headerlink" title="Good ol’ done callback"></a>Good ol’ done callback</h3><p>The simplest way to avoid this situation is to always handle the rejection scenarios yourself, rather than asking Mocha to do it. Here’s how:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.resolve();</span><br><span class="line"></span><br><span class="line">describe(<span class="string">'the promise resolves unexpectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should FAIL the test'</span>, (done) =&gt; &#123;</span><br><span class="line">    promise.catch(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'Rejected promise caught!'</span>) <span class="comment">// Not called</span></span><br><span class="line">      done();                                 <span class="comment">// Timeout!</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-FAIL-1"><a href="#Test-status-FAIL-1" class="headerlink" title="Test status: FAIL"></a>Test status: <strong>FAIL</strong></h4><p>The above test will fail due to timeout as Mocha waits for <code>done</code> to be called but it doesn’t, and times out eventually.</p><h3 id="Chained-then-block"><a href="#Chained-then-block" class="headerlink" title="Chained then block"></a>Chained then block</h3><p>Another way to avoid this situation is to chain a <code>then</code> block to the existing <code>catch</code> block and assert that the catch was called.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> expect = <span class="built_in">require</span>(<span class="string">'chai'</span>).expect;</span><br><span class="line"><span class="keyword">var</span> spy = <span class="built_in">require</span>(<span class="string">'sinon'</span>).spy;</span><br><span class="line"><span class="keyword">var</span> exceptionHandler = spy();</span><br><span class="line"><span class="keyword">var</span> promise = <span class="built_in">Promise</span>.resolve();</span><br><span class="line">describe(<span class="string">'the promise resolves unexpectedly'</span>, () =&gt; &#123;</span><br><span class="line">  it(<span class="string">'should FAIL the test'</span>, () =&gt; &#123;</span><br><span class="line">    <span class="keyword">return</span> promise.catch(exceptionHandler)</span><br><span class="line">    .then(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// Assert that catch block was called</span></span><br><span class="line">      expect(exceptionHandler.calledOnce).to.be.true;</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="Test-status-FAIL-2"><a href="#Test-status-FAIL-2" class="headerlink" title="Test status: FAIL"></a>Test status: <strong>FAIL</strong></h4><p>The above test tries to assert that the catch block was called using <a href="http://chaijs.com/" target="_blank" rel="noopener">Chai</a> and <a href="http://sinonjs.org/" target="_blank" rel="noopener">Sinon</a>, and fails.</p><p>If you know other elegant ways to avoid this behavior, please let me know in the comments!</p><br><p><strong>❤️ code</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;a href=&quot;https://mochajs.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Mocha&lt;/a&gt; is the leader when it comes to testing frameworks in &lt;a href=&quot;http
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/categories/javascript/"/>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/tags/javascript/"/>
    
      <category term="tests" scheme="https://tarunbatra.com/tags/tests/"/>
    
  </entry>
  
  <entry>
    <title>Why you should use named functions in JavaScript</title>
    <link href="https://tarunbatra.com/blog/javascript/why-you-should-use-named-functions-in-javascript/"/>
    <id>https://tarunbatra.com/blog/javascript/why-you-should-use-named-functions-in-javascript/</id>
    <published>2017-02-26T23:59:36.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p>JavaScript functions can be categorized into <em>named</em> or <em>anonymous</em> on the basis of the value of their <strong>name</strong> property. A named function can be declared as follows:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(add.name) <span class="comment">// =&gt; "add"</span></span><br></pre></td></tr></table></figure><br>All other ways, including ES2015's much-touted [Arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) produce anonymous functions. One of these ways is:<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> add = <span class="function"><span class="keyword">function</span> (<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(add.name) <span class="comment">// =&gt; ""</span></span><br></pre></td></tr></table></figure>__NOTE__: If you tried the above code in Chrome Dev Tools, you would've noticed that the __name__ of the function is "add" even in the case of anonymous function. That's because modern-day interpreters are smart enough to recognize the name from the expression.<p>Now, what’s special about <strong>named functions</strong>?</p><h2 id="Make-sense-with-error-stacks"><a href="#Make-sense-with-error-stacks" class="headerlink" title="Make sense with error stacks"></a>Make sense with error stacks</h2><p>Error and call stacks are a great help in debugging code. But the use of anonymous functions reduces the usefulness of the call stacks. We all have seen the infamous <strong>(anonymous)</strong> littered over the stack trace.</p><p>Of course, one can always look at the line number of the error, but with the ever-increasing pre-processing on the code (read Babel, WebPack, Browserify), this is not a reliable method.</p><h3 id="Error-stack-using-anonymous-function"><a href="#Error-stack-using-anonymous-function" class="headerlink" title="Error stack using anonymous function"></a>Error stack using anonymous function</h3><p data-height="252" data-theme-id="dark" data-slug-hash="OpVLwZ" data-default-tab="js" data-user="tbking" data-embed-version="2" data-pen-title="Anon Func" class="codepen">See the Pen <a href="https://codepen.io/tbking/pen/OpVLwZ/" target="_blank" rel="noopener">Anon Func</a> by Tarun Batra (<a href="http://codepen.io/tbking" target="_blank" rel="noopener">@tbking</a>) on <a href="http://codepen.io" target="_blank" rel="noopener">CodePen</a>.</p><script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script><h3 id="Error-stack-using-named-function"><a href="#Error-stack-using-named-function" class="headerlink" title="Error stack using named function"></a>Error stack using named function</h3><p data-height="252" data-theme-id="dark" data-slug-hash="mWJdJK" data-default-tab="js" data-user="tbking" data-embed-version="2" data-pen-title="Named Func" class="codepen">See the Pen <a href="https://codepen.io/tbking/pen/mWJdJK/" target="_blank" rel="noopener">Named Func</a> by Tarun Batra (<a href="http://codepen.io/tbking" target="_blank" rel="noopener">@tbking</a>) on <a href="http://codepen.io" target="_blank" rel="noopener">CodePen</a>.</p><script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script><script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script><p>JavaScript ecosystem is <a href="https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f" target="_blank" rel="noopener">already confusing</a> as is and the developer can use as much help as she can get to make sense of the obscure errors.</p><h2 id="Use-methods-before-declaration"><a href="#Use-methods-before-declaration" class="headerlink" title="Use methods before declaration"></a>Use methods before declaration</h2><p>While interpreting code, JavaScript looks for statements starting with <strong>function</strong> keyword (i.e. named function expressions) and move them to the top. This is called <a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting" target="_blank" rel="noopener">Hoisting</a>.</p><p>So practically, a named function is available even before it’s declared, making the following code valid.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">add(<span class="number">1</span>, <span class="number">2</span>); <span class="comment">// =&gt; 3</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span> (<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>But the following code won’t work.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">add(<span class="number">1</span>, <span class="number">2</span>); <span class="comment">// =&gt; Error</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> add = <span class="function"><span class="keyword">function</span> (<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="Improves-readability"><a href="#Improves-readability" class="headerlink" title="Improves readability"></a>Improves readability</h2><p>It’s fairly difficult to understand a callback function’s purpose in first glance. That’s what makes <a href="http://callbackhell.com/" target="_blank" rel="noopener">callback hell</a> the problem it is.<br>Look at the following jQuery code.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">'form'</span>).submit(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>The above code provides no information on what’s going to happen to the submitted form. Adding names to callbacks improves readability and acts as implicit documentation, as the following code does.</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">'form'</span>).submit(<span class="function"><span class="keyword">function</span> <span class="title">hitAPI</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>In my opinion, there’s no reason one should not use named functions when possible. Most of the JavaScript style guides out there don’t give due importance to them. <a href="http://eslint.org/" target="_blank" rel="noopener">ESLint</a> users can use <a href="http://eslint.org/docs/rules/func-names" target="_blank" rel="noopener">func-names</a> rule in their projects to require the use of named functions, and enjoy the benefits.</p><br><p><strong>❤️ code</strong><br>️</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;JavaScript functions can be categorized into &lt;em&gt;named&lt;/em&gt; or &lt;em&gt;anonymous&lt;/em&gt; on the basis of the value of their &lt;strong&gt;name&lt;/strong
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/categories/javascript/"/>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/tags/javascript/"/>
    
      <category term="styleguide" scheme="https://tarunbatra.com/tags/styleguide/"/>
    
  </entry>
  
  <entry>
    <title>Introduction to Cryptocurrencies</title>
    <link href="https://tarunbatra.com/blog/cryptocurrencies/Introduction-to-Cryptocurrencies/"/>
    <id>https://tarunbatra.com/blog/cryptocurrencies/Introduction-to-Cryptocurrencies/</id>
    <published>2016-08-16T22:50:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sub>Originally published for <a href="https://codebrahma.com/introduction-to-cryptocurrencies/" target="_blank" rel="noopener">Codebrahma</a> on Aug 17, 2016.</sub></p><p>Unless you’ve been living under a rock, you’d have heard about cryptocurrencies or Bitcoin atleast. There’s a lot of buzz around it, but disproportionately less clarity regarding what it actually is. In this article we’ll introduce ourselves to the fundamental principles of cryptocurrencies, clear the mist of confusion which surrounds them, and debunking some myths along the way too.</p><p>It’s human nature to compare everything new with something familiar. In case of cryptocurrencies, it’s the fiat money. Money is so fundamental to our daily lives that we always manage to see through them, and seldom do we try to understand the reason we need it and the unique purpose the serve.</p><blockquote><p>Look at those paper and plastic sheets, do you feel they’re worth it?</p></blockquote><p>Now I’m not an economist, but I know few common principles which make currencies what they are.</p><h2 id="Principles-governing-currencies"><a href="#Principles-governing-currencies" class="headerlink" title="Principles governing currencies"></a>Principles governing currencies</h2><h3 id="Demand-and-supply"><a href="#Demand-and-supply" class="headerlink" title="Demand and supply"></a>Demand and supply</h3><p>Almost every financial and economic activity is affected by this principle. The more the ratio of demand and supply of a commodity, more is it’s value.</p><h3 id="Market-sentiments"><a href="#Market-sentiments" class="headerlink" title="Market sentiments"></a>Market sentiments</h3><p>Market sentiments greatly effect the value of the currencies, stocks and commodities. If the investors of a company think the company shares are going to be worth less, they are worth less.</p><h3 id="Trust"><a href="#Trust" class="headerlink" title="Trust"></a>Trust</h3><p>Trust is essential for virtually all economic activity. Banknotes often have a <strong>promissory clause</strong> which reads like this:</p><p><img src="/data/images/Introduction-to-Cryptocurrencies/bank-note.jpg" alt="&#39;Bank note&#39;"></p><p>without any gold or other precious resources to actually back that claim. (Earlier they used to back currency value to something like gold. Though it’s discontinued now, but the idea is same).</p><h2 id="Why-cryptocurrencies"><a href="#Why-cryptocurrencies" class="headerlink" title="Why cryptocurrencies?"></a>Why cryptocurrencies?</h2><p>So we already have things in place to keep the system running, why do we need these cryptocurrencies? What problems do they solve, if any? Well the features of fiat money are also it’s limitations.</p><ol><li>The banks represent <strong>a single point of control</strong> which can deem a currency illegitimate, refuting our claims to our wealth.</li><li>Apart from being a single point of control, they also represent <strong>a single point of failure</strong>. Banks have failed in the past, and can certainly fail in the future due to various reasons, which puts our wealth at risk.<br><img src="/data/images/Introduction-to-Cryptocurrencies/bank-failures-graph.png" alt="&#39;Bank failures Graph&#39;"></li><li>We have to trust the system with our wealth without any satisfactory assurance against a fraud, intentional or otherwise.</li></ol><p>Cryptocurrenies are an attempt towards liberating the monetary system, something so essential to our lives, from these issues, in a way that one can be in absolute control of one’s wealth without trusting the system.</p><p>Any discussion about cryptocurrencies is incomplete without <strong>Bitcoin</strong>. Bitcoin is to cryptocurrencies what PowerPoint is to presentation programs, Ubuntu is to Linux and Xerox is to photocopying. We will try to understand cryptocurrencies with a case study of Bitcoin, which is not very much different from other cryptocurrencies.</p><h2 id="Bitcoin"><a href="#Bitcoin" class="headerlink" title="Bitcoin"></a>Bitcoin</h2><p>Bitcoin is one of the first and certainly the most popular cryptocurrency, created by <strong>Satoshi Nakamoto</strong>(a pseudonym) in 2009. Many of the challenges which Bitcoin faced were first of their kind and success of Bitcoin paved the way for other cryptocurrencies.</p><p>Let’s see some of these challenges:</p><h3 id="Eliminating-central-authority"><a href="#Eliminating-central-authority" class="headerlink" title="Eliminating central authority"></a>Eliminating central authority</h3><p>Bitcoin protocol is based on a Peer-to-peer (P2P) network to eliminate the need of any central authority, just like how BitTorrent protocol, based on a P2P network, eliminated the need of any central authority for file sharing.</p><h3 id="Eliminating-trust"><a href="#Eliminating-trust" class="headerlink" title="Eliminating trust"></a>Eliminating trust</h3><p>When we transfer money through banks, we trust them to do so. But without any central authority, or nodes which one could trust, it was necessary to create a trust-less system. Bitcoin used <strong>blockchains</strong> to achieve this. Blockchains are a type of distributed database which lives on ever node and are used as immutable public ledger for the transactions. Blockchains are made of blocks which further consist of bitcoin transactions.  Blockchains are similar to a linked list of blocks where every block refer to it’s parent block and this fact makes old transactions very secure and incorruptible as we’ll see later.</p><p>Blockchains, themselves are greatly hyped and are considered the biggest achievement of Bitcoin, as the idea can be used in various other industries to create trust-less systems.<br><img src="/data/images/Introduction-to-Cryptocurrencies/dilbert.png" alt="&#39;Dilbert&#39;"></p><h3 id="Value-of-bitcoins"><a href="#Value-of-bitcoins" class="headerlink" title="Value of bitcoins"></a>Value of bitcoins</h3><p>If there’s no central authority, who decides the value of the currency?</p><p>Well, as we discussed earlier, the golden rule of <strong>demand and supply</strong> comes to play here too. Satoshi made the protocol in such a way that the maximum number of bitcoins that can ever be generated (minted) is fixed at <strong>21 million</strong>.</p><p><img src="/data/images/Introduction-to-Cryptocurrencies/bitcoin-price-chart.png" alt="&#39;Bitcoin price chart&#39;"></p><p><strong>Market sentiments</strong> also play a vital role. Recently bitcoin prices plunged when Bitfinex, a Hong Kong based cryptocurrecncy exchange was hacked and $65 million worth bitcoins were stolen.</p><h3 id="Verification-of-transactions"><a href="#Verification-of-transactions" class="headerlink" title="Verification of transactions"></a>Verification of transactions</h3><p>Banks have interest in processing only valid transactions and keeping fraudulent transactions out of the system. This role is played by <strong>miners</strong> collectively.</p><blockquote><p>Miners are the nodes which generate blocks for blockchains by verifying the unverified transactions and including them in their block.</p></blockquote><p>The verification is done by adding <strong>Proof of work</strong> (POW) to the block data. Block data generally contains the transactions which form the block including the coinbase transaction and the hash of previous block.</p><blockquote><p>Proof of work is a piece of data which is difficult to produce but easy to verify.</p></blockquote><p>It’s generally the hash of block data with n number of leading zeroes. Miners append a value called <strong>nonce</strong> to the block data to change it’s hash value and keep changing the nonce until the desired hash is found.</p><p>So if the block data is <code>Hello, world!</code>, and the number of zeroes required is 4, it takes 4251 tries (nonce is incremented from 0) to find the desired hash:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9.</span><br></pre></td></tr></table></figure><p>Now anyone can verify that this is a valid hash of <code>Hello, world!4251</code>, but if someone tries to change a transaction in the block, the hash will be invalidated, and a new POW has to be generated, which is impractical.</p><p>We saw, finding POW can be a complex and a resource hungry process. So why do miners do that? Miners are incentivized for every block they generate. At the end of the block, the miner adds a special transaction called <strong>coinbase transaction</strong> which writes off a certain amount of bitcoins to the miner’s address from thin air, and that’s how new bitcoins are minted. Miners also get some money from the transactions, called <strong>transaction fee</strong>. The block, which is first to arrive, gets placed in blockchain, and other miners have to scrap their work, and start again after syncing with the blockchain.</p><h3 id="Double-spending"><a href="#Double-spending" class="headerlink" title="Double spending"></a>Double spending</h3><p>Let’s say Alice bought something from Bob, and paid him in bitcoins. What if:</p><p>Alice broadcasts the transaction, but alters the transaction in her own copy of blockchain to pay herself instead of Bob.<br>Upon the verification of the transaction by the network, Bob ships the item.<br>Now Alice broadcasts her own version of the blockchain.</p><blockquote><p>Which version of blockchain should the nodes trust?</p></blockquote><p>If Alice manages to convince the nodes that her version (without Bob’s transaction) is valid, she gets to <strong>buy the item without paying anything</strong>.</p><p>Various elements of Bitcoin protocol come at play to stop this from happening.</p><p>Bitcoin nodes <strong>trust the longest blockchain</strong> and build their blocks on it. If Alice wants to invalidate the current longest blockchain, she has to re-generate the blocks after her fraudulent transaction at such a speed that her blockchain becomes the longest one. As long as most nodes in the network are honest (they should be, they’re getting paid for it!), Alice can’t corrupt the blockhain, and this is why we introduced blockhains as immutable public ledgers earlier in the article. The number of blocks a transaction is buried under, is called the <strong>confirmations</strong> of that particular transaction. Most exchanges deem a  transaction verified after 6 confirmations.</p><blockquote><p>More the confirmations of a transaction, more difficult it is to alter it.</p></blockquote><h3 id="Anonymity"><a href="#Anonymity" class="headerlink" title="Anonymity"></a>Anonymity</h3><p>Many people hail Bitcoin as an anonymous mode of payment. But the reality is quite the opposite. Every transaction made on Bitcoin is visible to everyone. Having said that, bitcoin transactions don’t necessarily link to the real identity of the user, but to a pseudonym, much like writing a book with a pen name. Thus, Bitcoin is <strong>pseudonymous</strong>.</p><h3 id="Fun-facts-about-Bitcoin"><a href="#Fun-facts-about-Bitcoin" class="headerlink" title="Fun facts about Bitcoin"></a>Fun facts about Bitcoin</h3><p>The first block of the blockchain is called the Genesis Block. Every bitcoin in circulation is either derived from a coinbase transaction or the Genesis block. See how it looked like <a href="https://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" target="_blank" rel="noopener">here</a>.</p><p>Rewards from coinbase transactions are halved after every 210,000 transactions. In fact, the latest <strong>halving event</strong> occurred recently on 9th July 2016, reducing the reward amount from BTC 25 to BTC 12.5. Check when’s the next halving event <a href="http://www.coindesk.com/51-attacks-real-threat-bitcoin/" target="_blank" rel="noopener">here</a>.</p><p><strong>51% attack</strong> is a largely feared attack in Bitcoin, where an attacker controls 51% of the computational resources of the network, allowing it to alter the “immutable” blockchain. It ain’t plain theory, Read about Bitcoin’s brush with it <a href="http://www.coindesk.com/51-attacks-real-threat-bitcoin/" target="_blank" rel="noopener">here</a>.</p><h2 id="Altcoins"><a href="#Altcoins" class="headerlink" title="Altcoins"></a>Altcoins</h2><p>Cryptocurrencies other than Bitcoin are know as <strong>altcoins</strong>, or alternative to Bitcoin. Most of the altcoins are similar in principle to Bitcoin with some minor differences. <a href="https://litecoin.org/" target="_blank" rel="noopener">Litecoin</a>, <a href="http://dogecoin.com/" target="_blank" rel="noopener">Dogecoin</a>, <a href="https://www.namecoin.org/" target="_blank" rel="noopener">Namecoin</a> and Nxt are some prominent altcoins.</p><p>The altcoins vary in terms of under lying principles. For example, <a href="http://primecoin.io/" target="_blank" rel="noopener">Primecoin</a> is a cryptocurrency which makes use of the vast amount of computational resources to find long chains of prime numbers which can contribute in advancement of cryptography as a science.</p><p><a href="https://en.wikipedia.org/wiki/Ethereum" target="_blank" rel="noopener">Ethereum</a> is a disruptive <a href="/financial-software-development-company">blockchain-based platform</a>, the highlight of which is <strong>smart contracts</strong>. Smart contracts are contracts enforced by computer code, instead of institutions set up by humans. This way, we can port whole economies and governments to digital ecosystem, let alone currencies. The possibilities are endless and out of the scope of this article.</p><p>Cryptocurrencies also vary in terms of user friendliness. More popular ones, like Bitcoin are very user friendly, while others are not so.</p><p><img src="/data/images/Introduction-to-Cryptocurrencies/mobile-wallet.png" alt="&#39;Mobile wallet - bitcoin&#39;"><br>My bitcoin wallet app</p><p>You can see stark difference in my bitcoin wallet app shown above, and my Ethereum wallet shown below.</p><p><img src="/data/images/Introduction-to-Cryptocurrencies/cli-wallet.png" alt="&#39;CLI wallet - ethereum&#39;"></p><p>My Ethereum wallet</p><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>Cryptocurrencies are really trending and have a lot of buzz. The future of cryptocurrencies is very promising. Many people have made a fortune out of cryptocurrencies, however they should not be looked merely as an investment. The ideas which these cryptocurrencies represent and the future possibilities they hold are of far greater value than their monetary value.</p><p>If you’re thrilled and want to involve in bitcoins or cryptocurrencies in general, you may like the following links:</p><p>Original <a href="https://bitcoin.org/bitcoin.pdf" target="_blank" rel="noopener">bitcoin paper</a> by Satoshi Nakamoto.</p><p><a href="https://shapeshift.io/" target="_blank" rel="noopener">Shapeshift</a> is a site to convert one cryptocurrency to another.</p><p><a href="https://poloniex.com/" target="_blank" rel="noopener">Poloniex</a> is an exchange / trading site for cryptocurrencies.</p><p><a href="https://www.coinbase.com/" target="_blank" rel="noopener">Coinbase</a> is the PayPal of cryptocurrencies.</p><p>If you liked the article and feel generous, or just want to hone your newly acquired bitcoin skills, feel free to send me some bitcoins at the following address.</p><p>17ULzN8PCaCtE16WKtBhMYc28DQxxt4ja<br><img src="/data/images/Introduction-to-Cryptocurrencies/qr-code.png" alt="&#39;QR code&#39;"></p><br><p><strong>❤️ code</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;sub&gt;Originally published for &lt;a href=&quot;https://codebrahma.com/introduction-to-cryptocurrencies/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Codebrahm
      
    
    </summary>
    
    
      <category term="cryptocurrencies" scheme="https://tarunbatra.com/categories/cryptocurrencies/"/>
    
    
      <category term="cryptocurrencies" scheme="https://tarunbatra.com/tags/cryptocurrencies/"/>
    
      <category term="blockchain" scheme="https://tarunbatra.com/tags/blockchain/"/>
    
      <category term="bitcoin" scheme="https://tarunbatra.com/tags/bitcoin/"/>
    
  </entry>
  
  <entry>
    <title>Meteor Publications and Subscriptions</title>
    <link href="https://tarunbatra.com/blog/javascript/Meteor-Publications-and-Subscriptions/"/>
    <id>https://tarunbatra.com/blog/javascript/Meteor-Publications-and-Subscriptions/</id>
    <published>2016-07-20T22:30:00.000Z</published>
    <updated>2021-02-13T21:12:25.450Z</updated>
    
    <content type="html"><![CDATA[<p><sub>Originally published for <a href="https://codebrahma.com/meteor-publications-and-subscriptions/" target="_blank" rel="noopener">Codebrahma</a> on July 21, 2016.</sub><br><br><br><a href="https://www.meteor.com/" target="_blank" rel="noopener">Meteor</a> is a full-stack JavaScript platform, in fact the <a href="http://stats.js.org/" target="_blank" rel="noopener">11th most popular</a> JavaScript project on GitHub at the time of writing. What makes Meteor so disruptive is the mode of data communication between server and client. It’s not <a href="https://en.wikipedia.org/wiki/Representational_state_transfer" target="_blank" rel="noopener">RESTful</a> but instead, Meteor uses Publish Subscribe pattern to communicate data between server and client. The protocol used for this communication is Distributed Data Protocol (DDP), which is built in-house by The <a href="https://www.meteor.com/company" target="_blank" rel="noopener">Meteor Development Group (MDG)</a>, the startup behind Meteor.</p><p>In this chapter specifically, we’re going to talk about meteor <strong>publications</strong> and <strong>subscriptions</strong>, and to explain these interwoven concepts, we’re going to use them in various scenarios and analyze their results using 3rd party tools to achieve a better understanding of how Meteor publications and subscriptions work and the ways we can use them.</p><p>Almost in every case, we’d need to publish a set of data from the server and subscribe to same in the client. Unlike conventional frameworks, Meteor server doesn’t serve HTML content, but the data which is used by the client to render the HTML. This feature is called <strong>data on the wire</strong>. The server sends a set of data to the client initially and then keep pushing new data as it changes in the database.</p><p><em>Code to publish all documents from a collection of posts</em></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (Meteor.isServer) &#123;</span><br><span class="line">    <span class="keyword">var</span> Posts = <span class="keyword">new</span> Mongo.Collection(<span class="string">'posts'</span>);</span><br><span class="line"></span><br><span class="line">Meteor.publish(<span class="string">'listAllPosts'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> Posts.find();</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><em>Code to subscribe for all documents from a collection of posts</em></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (Meteor.isClient) &#123;</span><br><span class="line">    <span class="keyword">var</span> Posts = <span class="keyword">new</span> Mongo.Collection(<span class="string">'posts'</span>);</span><br><span class="line"></span><br><span class="line">    Meteor.subscribe(<span class="string">'listAllPosts'</span>, &#123;</span><br><span class="line"></span><br><span class="line">    onReady: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// called when data is ready to be fetched</span></span><br><span class="line">    <span class="built_in">console</span>.log(Posts.find().fetch());</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    onStop: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// called when data publication is stopped</span></span><br><span class="line">    &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>If you’re new to Meteor, you’d already be sweating seeing that we just created a Mongo Collection on the client. You’re right, it doesn’t make sense.</p><p>We actually created a <strong>MiniMongo</strong> Collection. MiniMongo is a client-side data store with a Mongo-like API. When we talk about server sending data to client, it’s MiniMongo we’re talking about.</p><p><img src="/data/images/Meteor-Publications-and-Subscriptions/minimongo.png" alt="&#39;Minimongo&#39;"></p><p>Subscribed data in MiniMongo visualized using <a href="https://github.com/thebakeryio/meteor-devtools" target="_blank" rel="noopener">Meteor DevTools</a> showing the 2 posts that were pushed to MiniMongo</p><p>When a subscription becomes ready, the data is stored in MiniMongo and can be accessed by Mongo-like queries. The server keeps the MiniMongo in-sync with the data in back-end by sending additional data as the data changes in the back-end.</p><p><img src="/data/images/Meteor-Publications-and-Subscriptions/ddp-monitor.png" alt="&#39;DDP Monitor&#39;"></p><p>Syncing of MiniMongo data through DDP showing 1 item being pushed to MiniMongo as it got added on the server</p><p><img src="/data/images/Meteor-Publications-and-Subscriptions/minimongo-synced.png" alt="&#39;MiniMongo synced&#39;"></p><p>Updated MiniMongo data showing total 3 posts</p><h2 id="Readying-a-subscription"><a href="#Readying-a-subscription" class="headerlink" title="Readying a subscription"></a>Readying a subscription</h2><p>As shown in the above code, when the subscription becomes ready, <code>onReady</code> callback is called. But when does the subscription become ready?</p><ol><li>When a cursor is returned from the server in a Meteor publication, Meteor automatically makes the subscription ready after pushing the data from the cursor to the MiniMongo.</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Meteor.publish(<span class="string">'listAllPosts'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> Posts.find();</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><ol start="2"><li>To make the subscription ready manually, or without returning a cursor <code>this.ready()</code> is used as shown in the following code snippet.</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Meteor.publish(<span class="string">'listAllPosts'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.ready();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>This informs the client that whatever records which needed to be pushed initially are pushed, and subscription is deemed ready.</p><h2 id="Stopping-a-subscription"><a href="#Stopping-a-subscription" class="headerlink" title="Stopping a subscription"></a>Stopping a subscription</h2><p>There are use cases when you may want the data not to be pushed to the client and the client to know that the subscription was stopped for some reason. How can that be done?</p><ol><li>You can manually stop a subscription by calling <code>this.stop()</code> from the publish function. This will stop the subscription and call the <code>onStop</code> callback.</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Meteor.publish(<span class="string">'listAllPosts'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.stop();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ol start="2"><li>Another way to stop a subscription is to throw a Meteor Error from the publish function, which will result in the <code>onStop</code> callback being called with the error as the argument.</li></ol><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//server</span></span><br><span class="line"></span><br><span class="line">Meteor.publish(<span class="string">'listAllPosts'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> Meteor.Error(<span class="string">'some reason'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//client</span></span><br><span class="line"></span><br><span class="line">Meteor.subscribe(<span class="string">'listAllPosts'</span>, &#123;</span><br><span class="line">    onStop: <span class="function"><span class="keyword">function</span>(<span class="params">err</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// handle the error</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="Advanced-concepts"><a href="#Advanced-concepts" class="headerlink" title="Advanced concepts"></a>Advanced concepts</h2><p>Meteor publications and subscriptions work like a charm if used properly. Syncing data in the background and updating the same in real-time looks pretty good. But it offers much more. You can take control of what gets pushed, when and how.</p><p>To gain more control over the data you publish, you need to know what happens when Meteor publishes data. The following screenshot shows all the DDP messages which are exchanged between client and server of our sample Meteor app.</p><p><img src="/data/images/Meteor-Publications-and-Subscriptions/ddp.png" alt="&#39;DDP&#39;"></p><p>DDP messages showing the publication of data using <a href="https://github.com/arunoda" target="_blank" rel="noopener">Arunoda</a>‘s <a href="https://github.com/arunoda/meteor-ddp-analyzer" target="_blank" rel="noopener">DDP Analyzer</a> tool</p><ol><li>First, the client sends a DDP message to server subscribing to the <code>listAllPosts</code> publication.</li><li>Then the server pushes the first set of data using <code>added</code> message.</li><li>Next, the server readies the subscription using <code>ready</code> message.</li><li>Upon addition of data in the database, server pushes the new document using the same <code>added</code> message.</li></ol><p>Now, if you’re paying attention, you’d know that we used <code>this.ready()</code> earlier to ready a subscription. It’s responsible for sending the <code>ready</code> message. Similarly, we have more methods which can be used to send the other kind of messages.</p><h3 id="Adding-a-document"><a href="#Adding-a-document" class="headerlink" title="Adding a document"></a>Adding a document</h3><p>You can use <code>this.added()</code> in a Meteor publish function to manually send an <code>added</code> message. It’s signature is:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.added(collectionName, documentId, fields)</span><br></pre></td></tr></table></figure><h3 id="Changing-a-document"><a href="#Changing-a-document" class="headerlink" title="Changing a document"></a>Changing a document</h3><p>Similarly, you can use <code>this.changed()</code> to change a document already pushed to the client. It’s signature is:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.changed(collectionName, documentId, changedFields)</span><br></pre></td></tr></table></figure><h3 id="Removing-a-document"><a href="#Removing-a-document" class="headerlink" title="Removing a document"></a>Removing a document</h3><p>To remove a document from client, Meteor provides <code>this.removed()</code> with the following signature:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.removed(collectionName, documentId)</span><br></pre></td></tr></table></figure><p><em>Code to publish a post and then change it’s content</em></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Meteor.publish(<span class="string">"sendCustomPost"</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> doc = &#123;<span class="string">"title"</span>: <span class="string">"Post 4"</span>, <span class="string">"content"</span>: <span class="string">"4th post"</span> &#125;;</span><br><span class="line">    <span class="comment">// Pushing 4th document to client</span></span><br><span class="line">    <span class="keyword">this</span>.added(<span class="string">"posts"</span>, <span class="string">"some-object-id"</span>, doc);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Changing the 4th document</span></span><br><span class="line">    <span class="keyword">this</span>.changed(<span class="string">"posts"</span>, <span class="string">"some-object-id"</span>, &#123; <span class="string">"content"</span>: <span class="string">"custom-content"</span> &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Manually readying the subscription</span></span><br><span class="line">    <span class="keyword">this</span>.ready();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p><img src="/data/images/Meteor-Publications-and-Subscriptions/ddp-2.png" alt="&#39;DDP&#39;"></p><p>DDP messages after executing the above code</p><p>So, you can control the data you publish to the client. There are more interesting concepts, like intercepting a publication and changing the data but that’s out of the scope of this article.</p><p>Meteor publications and subscriptions make working with real time data easy and fun. To know more refer <a href="http://docs.meteor.com/" target="_blank" rel="noopener">Meteor Documentation</a> and after you’re done with that, maybe <a href="https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md" target="_blank" rel="noopener">DDP specification</a> too.</p><br><p><strong>❤️ code</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;sub&gt;Originally published for &lt;a href=&quot;https://codebrahma.com/meteor-publications-and-subscriptions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Code
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/categories/javascript/"/>
    
    
      <category term="javascript" scheme="https://tarunbatra.com/tags/javascript/"/>
    
      <category term="meteor" scheme="https://tarunbatra.com/tags/meteor/"/>
    
  </entry>
  
</feed>
