<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Juan Pablo Lorenzo</title>
    <description>The latest articles on DEV Community by Juan Pablo Lorenzo (@juampilorenzo).</description>
    <link>https://dev.to/juampilorenzo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3517%2Fd18c3f98-d58d-4449-b8a9-1d9e0564882c.JPG</url>
      <title>DEV Community: Juan Pablo Lorenzo</title>
      <link>https://dev.to/juampilorenzo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juampilorenzo"/>
    <language>en</language>
    <item>
      <title>A multi-tenant cache solution with Memcache and Python</title>
      <dc:creator>Juan Pablo Lorenzo</dc:creator>
      <pubDate>Sun, 21 Jul 2019 19:53:42 +0000</pubDate>
      <link>https://dev.to/juampilorenzo/a-multi-tenant-cache-solution-with-memcache-and-python-287d</link>
      <guid>https://dev.to/juampilorenzo/a-multi-tenant-cache-solution-with-memcache-and-python-287d</guid>
      <description>&lt;p&gt;Hello! This is my first technical post in the site. I wanted to write something about what I am doing and even that this solution tries to overcome a single use case, it was very useful for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The use case
&lt;/h2&gt;

&lt;p&gt;While developing a microservice for a Cloud-based solution, I came across the need to use a &lt;em&gt;Memcached&lt;/em&gt; cluster to cache some request responses. Simply put, I discovered that I had two problems while using &lt;em&gt;flask-caching&lt;/em&gt; (based in &lt;em&gt;Werkzeug&lt;/em&gt; cache module) and the &lt;em&gt;Memchached&lt;/em&gt; cache:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can use a key prefix when you create the MemcachedCache client in your code to separate the different application caches inside the cluster. But my surprise was that this doesn't mean that you can clear your cache without affecting other applications. If you do &lt;em&gt;clear()&lt;/em&gt;, the entire cache is dead. --&amp;gt; &lt;strong&gt;Not very multi-application&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The only way of caching resources from different tenants inside an application is to include the tenant in the key. That's logical. But again, that doesn't mean that you are capable of removing part of your application cache. Even if your cluster is used only for your application, if one of your tenants updates its data and you need to invalidate its cache, all data stored in the cache will be lost. --&amp;gt; &lt;strong&gt;Not very multi-tenant&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;We can overcome both of these problems with a few lines of application code. I thought of forking the &lt;em&gt;flask-caching&lt;/em&gt; library to provide the solution as library code. But I think that another library for this is not worth it and if you need the use case, you can add the logic in the application side.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I will work with the multi-tenant example. You can do exactly the same for a multi-application use case. In addition, you can do both things at the same time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will base ourselves in a simple concept: we will store a &lt;strong&gt;namespace&lt;/strong&gt; value in the cache for each of our tenants.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_namespace_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Get namespace current value.
    :param tenant_id: tenant id
    :return: namespace current value.
    """&lt;/span&gt;
    &lt;span class="n"&gt;stored_namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CACHE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"namespace:{}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;namespace_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stored_namespace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stored_namespace&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;CACHE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"namespace:{}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;namespace_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TIMEOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;namespace_value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The first time we need to store something in the cache, we will set the namespace value to 0 and we will add this value with the key.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Sets data to cache.
    :param tenant_id: tenant id
    :param key: key to use for caching
    :param value: value to cache
    :return:
    """&lt;/span&gt;
    &lt;span class="n"&gt;CACHE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}:{}/{}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_namespace_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TIMEOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Each time we need one key we will first get the &lt;em&gt;namespace&lt;/em&gt; value first and add it to the query.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Get data from cache
    :param key: key used for caching
    :param tenant_id: tenant id
    :return: tenant data in cache or None if empty
    """&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;CACHE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}:{}/{}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_namespace_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And what happens if we need to invalidate the cache for the tenant? We add 1 to the namespace value.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clear_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Clear cache in Memcache only for tenant data.
    Using a incremental namespace value avoid using .clear(),
    that flushes the complete cache.
    :param tenant_id: tenant id
    :return:
    """&lt;/span&gt;
    &lt;span class="n"&gt;namespace_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_namespace_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;CACHE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"namespace:{}"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;namespace_value&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TIMEOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Python 2/3 with the following requirements:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python-memcached==1.59
Werkzeug==0.15.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You can try this solution easily using a Docker image. You will have a Memchached server running and listening through your 11211 port.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker run -itd --name memcached -p 11211:11211 -e MEMCACHED_MEMUSAGE=32 rbekker87/memcached:alpine
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;You can use this Gist that contains the entire code and a simple demostration.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run the code with

&lt;code&gt;python multi_tenant_cache.py&lt;/code&gt;

and you should see:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Setting Lisboa cache...
Lisboa cached /info is: 2 days
Setting Barcelona cache...
Barcelona cached /info is: 3 days
Clearing Barcelona cache...
Barcelona cached /info is: None
Lisboa cached /info is: 2 days
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Memcached Docker image: &lt;a href="https://sysadmins.co.za/dockerizing-a-memcached-server-for-docker-on-alpine/"&gt;https://sysadmins.co.za/dockerizing-a-memcached-server-for-docker-on-alpine/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Werkzeug Cache: &lt;a href="https://werkzeug.palletsprojects.com/en/0.14.x/contrib/cache/"&gt;https://werkzeug.palletsprojects.com/en/0.14.x/contrib/cache/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>memcached</category>
      <category>cache</category>
      <category>cloud</category>
      <category>python</category>
    </item>
    <item>
      <title>Delete your code: in search of a minimalist approach to software development</title>
      <dc:creator>Juan Pablo Lorenzo</dc:creator>
      <pubDate>Thu, 30 May 2019 12:42:07 +0000</pubDate>
      <link>https://dev.to/juampilorenzo/delete-your-code-in-search-of-a-minimalist-approach-to-software-development-3gii</link>
      <guid>https://dev.to/juampilorenzo/delete-your-code-in-search-of-a-minimalist-approach-to-software-development-3gii</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVcph1yW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AHTKqg1DFILEq90zjQV8onw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVcph1yW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2600/1%2AHTKqg1DFILEq90zjQV8onw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’m sorry I wrote you such a long letter; I didn’t have time to write a short one. &lt;br&gt;
— Blaise Pascal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Software is a difficult and beautiful problem. Software engineering is the field that addresses it and although it is a young discipline, a lot of ideas has emerged trying to improve our ability to deal with software. This article is about a group of ideas on which we use to rely while developing that coincide with a minimalist approach to code and software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting point
&lt;/h3&gt;

&lt;p&gt;A good starting point is the notorious &lt;em&gt;No Silver Bullet&lt;/em&gt; essay. Within it, we find that the first attack on the conceptual essence of software is &lt;em&gt;buy vs. build&lt;/em&gt;: “the most radical possible solution for constructing software is not to construct it at all”&lt;em&gt;.&lt;/em&gt; Apart from the obvious meaning of this attack, I think that the key to this point is somewhere else. &lt;em&gt;Buy vs. build&lt;/em&gt; is a recursive solution to the simple existence of software. It says to avoid building software while you can. Three decades after the essay and we have been trying to do it. But we always get to the base case and we have to build.&lt;/p&gt;

&lt;p&gt;What I mean is this: what if we have missed the base case? We have enhanced our limits based in reducing our need to build parts of our software (using SaaS, microservices, Open Source, etc.). But what if the code we should be minimizing is the one we have already developed?&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimalism and what can it provides
&lt;/h3&gt;

&lt;p&gt;Minimalism is on trend nowadays. A group of Netflix documentaries, TED talks and writers have created a concept difficult to define. What is being a minimalist? Even Oxford dictionary has been left behind. The most accurate definition is that of the adjective &lt;em&gt;minimalist&lt;/em&gt;: “taking or showing as little action and  involvement in a situation as possible”.&lt;/p&gt;

&lt;p&gt;If you want to create a precise definition of this modern term the artistic movement of post-WWII minimalism is not very useful. We can rescue the phrase by the painter Ad Reinhardt: “The more stuff in it, the busier the work of art, the worse it is. More is less. Less is more.”&lt;/p&gt;

&lt;p&gt;If we change the subject and look into the history of thought we can find Epicurus (341–270 B.C.E.). A couple thousand years before us he said: “Nothing is enough for the man to whom enough is too little.” He searched for a happy and tranquil life, characterized by the freedom from fear and the absence of pain, living a life surrounded by friends.&lt;/p&gt;

&lt;p&gt;Such ideas traveled Western and Eastern history for thousands of years. We can have an article written only about them, but that is not the idea. How do these ideas relate to Marie Kondo? Can these ideas give any value on our work? I will end the section with Leo Babauta’s modern definition of minimalism:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s simply getting rid of things you do not use or need, leaving an uncluttered, simple environment and an uncluttered, simple life. It’s living without an obsession with material things or an obsession with doing everything and doing too much. It’s using simple tools, having a simple wardrobe, carrying little and living lightly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The quote is important because it shows that this concept isn’t about not doing things, it is about avoiding doing too much. It’s about using simple tools for simple problems. That’s our starting point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Predecessors in software development
&lt;/h3&gt;

&lt;p&gt;These ideas have been going around in software development for years. We can describe some of them:&lt;/p&gt;

&lt;h4&gt;
  
  
  Extreme Programming (XP)
&lt;/h4&gt;

&lt;p&gt;If we have to look for a predecessor of this idea, it is impossible to avoid Extreme Programming (XP). A year before Kent Beck published his book on the methodology, Ron Jeffries was writing about &lt;em&gt;You are NOT gonna need it!&lt;/em&gt;. The idea was clear: resist each time the urge to develop features that you don’t actually need. Jeffries discussed the importance of time and how the amount of code affects not only its developer but each person who reads, mantains or works in any way with that code. To be even clearer I can quote Ron: “the best way to implement code quickly is to implement less of it. The best way to have fewer bugs is to implement less code*”.* What is the idea of deleting your code more than a better implementation of that principle?&lt;/p&gt;

&lt;h4&gt;
  
  
  Worse is better
&lt;/h4&gt;

&lt;p&gt;This approach holds that in software making it is best to start with a minimal creation and grow it as needed, in “piecemeal growth”. The creator of this concept was the computer scientist Richard P. Gabriel, known for his work with the Lisp programming language. In his words, the essence of the style is slightly different to the MIT/Stanford &lt;em&gt;the right thing&lt;/em&gt; style of design. In short, they agree that simplicity is the most important consideration in a design.&lt;/p&gt;

&lt;h4&gt;
  
  
  KISS
&lt;/h4&gt;

&lt;p&gt;Keep It Simple, Stupid. The U. S. Navy left us this beatiful concept that is very close to the common phrase “everything should be made as simple as possible, but not simpler”. KISS is repeated everywhere in software engineering. It became an important principle because of that tendency among engineers to over-engineer solutions. It is better for you to build software using code that is &lt;em&gt;stupid&lt;/em&gt; simple. It creates more maintanable and flexible software.&lt;/p&gt;

&lt;h4&gt;
  
  
  Jamie Zawinski, software bloats and feature creeps
&lt;/h4&gt;

&lt;p&gt;If the previous points touched on ideas related to avoiding creating more code than is needed, has to do with problems after that happens. We have a specific name for the problem on expanding the features in our code: &lt;em&gt;feature creeps&lt;/em&gt;. Zawinski does a better job than me: “Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.”. The famous Andrew Tanenbaum also had something to say about this in his book &lt;em&gt;Computer Networks&lt;/em&gt;: “In addition, a substantial number of the problems caused by buggy software, which occurs because vendors keep adding more and more features to their programs, which inevitably means more code and thus more bugs.”.&lt;/p&gt;

&lt;p&gt;It seems that adding capabilities to a piece of software that was never thought of doing that kind of work can only lead to &lt;em&gt;software bloats&lt;/em&gt;, the complete loss of meaning of the original design, the waste of resources when using technologies that do not correspond to the scope, the inability to maintain and refactor the software, among others nightmares..&lt;/p&gt;

&lt;h4&gt;
  
  
  The No Code repository
&lt;/h4&gt;

&lt;p&gt;“No code is the best way to write secure and reliable applications. Write nothing; deploy nowhere.” It is a joke about other software topics but I can’t help but include what Kelsey Hightower did in this GitHub repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  What do we have to offer? A development approach
&lt;/h3&gt;

&lt;p&gt;What am I trying to say with &lt;em&gt;delete your code&lt;/em&gt;? I think that software should be developed thinking with the actual use of it in mind first. This must be taken into account in every step of software life cycle, not only in its design. This development approach can be summarised in three points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every piece of software must contain only the software that is being used.&lt;/li&gt;
&lt;li&gt;A piece of software must have a cohesive ammount of use between its parts.&lt;/li&gt;
&lt;li&gt;A piece of software should be designed, implemented, monitored and mantained with the above concepts in mind.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Is it even possible to DYC?
&lt;/h3&gt;

&lt;p&gt;This article could end with the possibility of a new process called Delete Driven Development (we would use DeDD, DDD is already busy) or perhaps Usage Driven Development (UDD). But I think that it is very important to think about a real chance of implementing these strategies.&lt;/p&gt;

&lt;p&gt;There are a lot of concepts that play a role in this approach, but there is one that is a key for making it possible: monitoring. You have to profile your software in production and you have to do it in a way that makes the results representative. This is not easy but it is not negotiable to have the possibility to remove part of your code. That’s why we need a solution that does not overload our software while it is profiling at least a partial time of its usage. In my opinion, the right approach is with an Application Performance Management (APM) such as those provided by DataDog or Stackify.&lt;/p&gt;

&lt;p&gt;The need is clear: you need to know how much your pieces of code are being executed. We are not only talking in terms of APIs but also in terms of classes, functions and up to lines of code. We have to know how much each piece of our code is being used to be able to delete the unused code and refactor the rest to follow the three principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  An ally: microservices
&lt;/h3&gt;

&lt;p&gt;Microservices must, by definition, be maintainable and testable. Why are microservices important to the approach? Because microservices are pieces of software that give us the ability to mantain a cohesive amount of usage. If your microservice has more than one responsability without a cohesive amount of use, you may have to split this microservice. Do you need to add a new feature in your software and are you tempted to add it to a microservice that will not correspond with its responsability? I am sure that after adding the feature it won’t have a cohesive amount of usage as the microservice previous state had.&lt;/p&gt;

&lt;p&gt;What do we want to avoid with that? Waste of resources and use of tools or technologies that only apply to a part of the functionality. The work has to be done at all levels but I believe that microservices are a great point of reference to apply the principles defined before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This article is intentionally incomplete. It is an idea that needs a lot of work to be more than a concept. It might even turn out to be a bad idea. But it is clear to me that there are many indications that lead us in that direction. We’ve known for a long time that we can expect better pieces of software using less code and we have to fully embrace that idea. So, in a nutshell: check the actual use of your software and delete your unused code. I’m sure the profits will outweigh your lost LOC.&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Jeffries, J. (1998, Apr 4). &lt;em&gt;You’re NOT gonna need it!&lt;/em&gt; Retrieved from [&lt;a href="https://ronjeffries.com"&gt;https://ronjeffries.com&lt;/a&gt;] &lt;a href="http://ronjeffries.com/xprog/articles/practices/pracnotneed/"&gt;http://ronjeffries.com/xprog/articles/practices/pracnotneed/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The Apache Software Foundation (2019). &lt;em&gt;What does KISS stand for?&lt;/em&gt; Retrieved from* *&lt;a href="http://people.apache.org/~fhanik/kiss.html"&gt;http://people.apache.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Raymond, E. (2003, Dec 29). &lt;em&gt;The Jargon File v. 4.4.7&lt;/em&gt;. Retrieved from &lt;a href="http://jargon-file.org/"&gt;http://jargon-file.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hightower, K. (2018, Feb 6). &lt;em&gt;No Code Repository&lt;/em&gt;. Retrieved from [&lt;a href="https://github.com/kelseyhightower/nocode"&gt;https://github.com/kelseyhightower/nocode&lt;/a&gt;] &lt;a href="https://github.com/kelseyhightower/nocode"&gt;https://github.com/kelseyhightower/nocode&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Tanenbaum, A. (2010). &lt;em&gt;Computer Networks&lt;/em&gt;. Asia: Prentice Hall, Indian International Ed.&lt;/li&gt;
&lt;li&gt;Richardson, C. (2018). &lt;em&gt;What are microservices?&lt;/em&gt; Retrieved from &lt;a href="https://microservices.io/index.html"&gt;https://microservices.io&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>practices</category>
      <category>maintainability</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
