[{"content":"The Quest \u0026amp; Answer We\u0026rsquo;re all on a journey, aren\u0026rsquo;t we? Searching for that elusive \u0026ldquo;ultimate solution\u0026rdquo; to better ourselves. Whether you\u0026rsquo;re focused on personal growth, spiritual enlightenment, or just trying to be a decent human being, the quest is the same.\nFor me, the spiritual aspect is paramount. Honestly, every action, every choice, can be seen as having a spiritual dimension. And in this pursuit, I\u0026rsquo;ve stumbled upon what I believe is the key: kindness.\nYes, kindness. It sounds almost too simple, doesn\u0026rsquo;t it? Want to improve? Be kind. Want to find salvation? Be kind. It\u0026rsquo;s the answer, plain and simple.\nBut here\u0026rsquo;s the catch (the \u0026ldquo;but\u0026rdquo; that makes everything a bit more complicated): how do we know what true kindness is in any given situation?\nThat\u0026rsquo;s where things get tricky. For someone like me, who believes in rebirth, I suspect it will take countless lifetimes to fully grasp the nuances of kindness. It\u0026rsquo;s a journey, a continuous learning process.\nKindness - The Path to the Path\nThe Example(!) Let\u0026rsquo;s take an example: the story of Lord Krishna and Shishupala. On the surface, it looks like a simple act of violence. Krishna kills Shishupala. How can that be considered kindness?\nWell, if you delve deeper into the story, you\u0026rsquo;ll find that Krishna\u0026rsquo;s act was one of liberation. By ending Shishupala\u0026rsquo;s life, Krishna freed him (Jaya or Vijaya) from a curse, allowing him to rejoin the divine. It was, in essence, an act of mercy, fulfilling Shishupala\u0026rsquo;s deepest desire.\nMost people, even those present at the time, didn\u0026rsquo;t understand this. And honestly, that\u0026rsquo;s unsurprising. We often struggle to see beyond the surface, to grasp the true nature of kindness in complex situations.\nThis brings us to the heart of the matter: figuring out what kindness means is incredibly difficult. It\u0026rsquo;s a lifelong, perhaps multi-lifelong, endeavour. Please don\u0026rsquo;t think that I condone murder based on this example. It is just an extreme example to make my point - knowing what is kindness in every moment is very difficult, and it can also be difficult to follow through with it.\nThe Non Answer - A new quest There is no real answer in here. All I have done is point you to another quest. To figure out kindness and act with it. So, what do we do? We acknowledge that we need help to navigate this complex path. We ask for guidance. I pray.\nLet us pray for the wisdom to recognize and embody kindness in all our interactions. Let us seek the Lord\u0026rsquo;s guidance as we strive to be kinder to all living beings.\nLord, only you can guide us. We take refuge in you.\nThis connects to ideas I explored in Bhakthi Yoga - Bhagavad Gita, particularly the qualities the Gita describes in the Lord\u0026rsquo;s favorite devotee — compassion, forgiveness, and fearlessness are all forms of kindness.\nAum sarvam SriKrishnarpanam astu.\n","date":"2025-03-07T00:00:00Z","permalink":"/the-answer.html","title":"Our Ultimate Quest: The Simple (Yet Complex) Answer"},{"content":"If you follow my blog, you probably know that I am interested in education. One of my specific goals is becoming a teacher. I even feel that I have some talent in the profession😛. In the past, I have attempted some teaching by giving sessions to co-workers (in software development topics - Architecture, TDD etc.), albiet I am not sure about their success. I have also tried my hand at some online course creation (you probably know about that one).\nThe Source Given this background, it is clear that I don\u0026rsquo;t have any formal training on teaching. No formal foundation in teaching \u0026amp; developing skills in others. So I decided to invest sometime on it. My search lead me to this course in Coursera. The Commonwealth Education Trust provides a lot of courses on teaching and I thought this could be a starting point to getting trained.\nThe course itself is for actual teachers who are practising the craft across the world. I have very limited experience teaching a classroom. Also, the experience I have, has been with fairly older students (not sure if I can call them students, since they are already in a professional setup). But I was interested in understanding how the teaching profession worked. So I started on the course.\nI have now completed 2 weeks of the course. I finished an assignment as part of the course and that made me reflect on some of my learnings in the course (a great idea for an assignment). After some thought, I decided that it will be good to share whatever I have learnt. You may or may not find it useful, but this will help me internalise the ideas. The course has a lot to offer (for anyone interested in the subject). What I cover here are just the top ideas I picked up.\nThe Lessons Aim of Teaching One of the first points made in the course is about the aim of teaching. Let me quote the sentence here:\nThe aim of teaching is not to produce learning but to produce the conditions for learning.\nThe Art of Teaching - Image by Peggy und Marco Lachmann-Anke from Pixabay\nLearning is not a simple process of just listening and memorising the ideas said by a teacher (the \u0026ldquo;teaching\u0026rdquo;). It is a multistep, multi-layered process. All learning is social, emotional \u0026amp; intellectual and hence giving a lecture cannot directly create learning. Teaching is more an attempt to create an environment and a set of circumstances which help students learn. It is not a transfer, it is a facilitation. We need to create multiple mechanisms which acts as conditions for learning. Before the course, I did not think of teaching and learning in a holistic sense. It\u0026hellip; made sense!\nThe Learner\u0026rsquo;s mind The course talks about how the thinking about learning evolves in the mind of the learner - the student. The learner will need to think about:\nWhat do I know about learning? How am I smart? What learning mechanisms work best for me? What helps/hinders my learning? Who do I learn best with? Where and when do I learn best? A Learner's mind - Image by Gordon Johnson from Pixabay\nThese questions trigger 2 thoughts in me:\nAs a learner (both my current profession \u0026amp; teaching need learning), I need to answer these questions for my own learning process. As a teacher, I should try to answer these questions for my learners. If I can do the second one at an individual level, it would be ideal. But, it may not be practical. In a classroom setting where the teacher and her students have a longer association (in terms of time spent together), individual attention might be possible. Then again, this also depends on how big the class is - teacher to student ratio.\nAll said and done, this is another aspect to look at to become a better teacher and learner.\nThe Unknown hinderances I am listing out some hinderances in learning. I call these unknown because I was unaware of it myself (you might already know). They are subtle in nature:\nHinderances in my student's mind - Photo by Ann H\nSelf-doubt \u0026amp; self talk in the learners mind: Learners have a lot of things running in their head which can reduce the acquired learning. This is mentioned in the context of kids, but I think it applies to elders too. I can relate to it in my own learning attempts. When a topic become tough, our mind starts doubting our capabilities and starts talking negatively, which hinders the learning further. As a teacher, I need to be aware of this and be able to empathise with learners.\nInappropriate medium: If we just talk through a very visually rich concept, it is obviously a poor medium to convey the message. A crude example is me trying to explain a Picasso or Ravi Varma painting verbally instead of showing a picture. It could be better to use more than one medium (multimedia) to convey lessons. This can also help different kinds of learners (who are partial to different mediums) to grasp the concepts that are explained.\nMisconceptions: Many a times, when we are trying to learn a concept that is related to another known concept, our understanding of the new concept is shaped by our understanding of the known concept. But, if we have misconceptions on it, then our new learning suffers. For example if I start learning statistics and have the misconception that average and mean are the only ways to measure central tendencies (which is wrong in more than one way), then I am going to find it harder to properly grasp the concepts of central tendencies.\nLack of prior knowledge: Trying to understand Machine learning without knowing the basics of Statistics is probably going to backfire on us. For any learner trying to learn something, it is important to know the pre-requisites. As a teacher it is imperative on my part to clarify this clearly to the learner.\nPeer norms and pressure: In a social setting (which is where all learning happens), the effect of peers on the learner is very high. All learners want social validation and want to confirm to peer norms. If the social setting moves the learner away from learning, my efforts as a teacher may not really bear any fruit.\nAll these have to be seen in the context of individual learners. Every learner might not have all these issues, but they might have different subsets. So it is critical to provide individual attention to the extent possible. I am not sure if this is practical in all situations, but it is the ideal to strive for.\nA teaching/learning technique The course introduces a good technique that can be used to teach and learn. It is a 3-step process:\nConnect, extend and challenge - Image by Tung Nguyen from Pixabay\nConnect - Connect new information to what they (or you) already know. Extend - Think or explain, how the new concept builds on top of what they (or you) know Challenge - Think or discuss, how it challenges what they (or you) know, think and do This kind of learning allows for active inquiry, assimilation and understanding of the material. The learner understands the applicability of the learnings too. It can help break misconceptions which we already have. I plan to apply this to my own learning process. I feel this is very similar to the ideas explained in the Zettelkasten method. More on that some other time.\nLearning is mediated by emotional centers I had some inkling of this idea before. I had noticed that whenever something worth learning has a story attached to it, the recollection of the material is better. The story has to be appealing - have an emotional connect. This applied to my own learning as well as a few times when I had an opportunity to teach others. I did not know that there is a formal understanding that learning has an emotional component. This is new information which connects and extends my understanding. Going forward, I should add something in my teaching which will evoke an emotion in the learner.\nThe challenge I see in doing this, is that I need to figure out a way to control this in a classroom/teaching setting. It should not distract the learner from the core topic and take him to unplanned areas. Venturing into unchartered areas might be good at times, but it could also lead to challenging situations where the core ideas that need to reach the learner get replaced by ancilliary thoughts which may not add the necessary value to the learner. This is something I will have to watch out for and mitigate.\nA teachable moment The modules talks about an idea that learning happens at a teachable moment and that teachable moment cannot be pre-determined by the teacher. It varies with different learners. There is a stress on the idea of repeating the learning material from time to time so that a teachable moment occurs for the learner to grasp it.\nA teachable moment is a learning moment - Photo by Kampus Production\nI have seen many teachers repeating their content, but always felt that doing it, would unnecessarily cause boredom to the listener. Now I understand that this is not true always. The repeating of lessons and ideas is required so that learners get multiple attempts at grasping them. It also explains why many teachers tend to include small sections in their class where they reiterate previously learnt concepts. I also intend to apply this technique down the line. I will ensure that these interludes are brief (and to the point) in nature so that it does not feel overly repetitive \u0026amp; tiresome to the learner.\nLearning by teaching This is something I have observed myself. Any topic which I try to learn takes time. More importantly the nature of the effort I take to learn the topic, matters. When I am learning to teach someone (through a session or through writing), my quality of learning improves by leaps and bounds. I crystallise on thoughts, concepts and ideas better. Also, sessions with learners bring in more questions which makes me think in directions which I had not thought of earlier.\nWhat I learnt from the module is the fact that this technique could be extended to children or learners. If we provide opportunities for the learners (kids) to teach their peers, it can help them learn better. The challenge I see is that, this could be a big ask for some learners since they might be intimidated by the idea of teaching someone else. I will have to figure out ways to make this attuned to their own comfort. Also, I need to work on getting more learners to participate in the process so that many can benefit from it.\n\u0026ldquo;What makes you say that?\u0026quot; This idea from the module struck me as a profound one. While I keep focusing on whether the learner(s) have grasped the ideas of the lessons, I have not really delved deep into their thinking and reasoning behind it. Simple questions like \u0026ldquo;What makes you say that?\u0026rdquo;, \u0026ldquo;What do you think you know?\u0026rdquo; pushes me into the realm of the learner\u0026rsquo;s thinking process and helps me understand where they are coming from. It helps me to get deeper into their psyche and ensures that I don\u0026rsquo;t stay at a superficial level.\nQuestioning our thinking leads us to deeper understanding - Image by nugroho dwi hartawan from Pixabay\nAs I think more, I feel that the question \u0026ldquo;What makes me say that?\u0026quot; is one I should ask myself more often, so that I can delve deeper into my own understanding of topics.\nA living curriculum Earlier I have been restricted to the idea of looking at a curriculum as a fixed one. I have come up with curriculums for teaching certain topics in my brief experience as a teacher.\nThe idea that the curriculum is a living one that needs to change as per the observations I make, and the needs expressed by learners was new to me. But it makes a lot of sense once I think about it. I will have to figure out how much of this idea I can implement under various circumstances. If I work on my own courses, the curriculum can be changed at my will. Other times I will have to look at innovative ways to keep the curriculum live in spite of the restrictions.\nConclusion Thes are the top points from the modules which I connected to and was able to extend my thinking and also identify some challenges. These are my first set of lessons in this journey. I hope to learn more from the course (and other courses) and also by sharing it with you all. Please do share your thoughts and comments on this.\nAum sarvam SriKrishnarpanam astu\n","date":"2023-12-17T00:00:00Z","permalink":"/teaching-lessons-1.html","title":"Learning Teaching - Chapter One"},{"content":" TL;DR\nDeveloping \u0026amp; open sourcing a locust plugin that pushes performance test metrics to AWS CloudWatch using locust event hooks and boto3 client. I developed a simple locust plugin and open sourced it. Your questions answered:\nWhat are you talking about? Let me give you some context. I needed a performance test setup for one of our important services in Simpl. My tool of choice for load generation was Locust. I had my reasons and I will discuss that in a different post.\nOk, so what? Why a plugin? Locust is a great load generation tool. It has been around for a long time, has a good community, fairly performant and supports a lot of features for load generation. But, there was still one problem that needed to be solved for our case - performance test reporting the way we wanted it.\nLocust does allow us to generate reports from the UI, but that approach did not work for us since we were running it in headless mode (part of the CI setup). I also wanted the reports to live for much longer than the duration of test runs since it helps in comparitive analysis. So I decided that we need to send the metric information elsewhere to store and track them. AWS Cloudwatch metrics was a good solution for Simpl\u0026rsquo;s setup - a lot of our metrics go there.\nTo make this happen, we needed some software which will take the metrics measured by locust and send it to AWS Cloudwatch. The idea is not a new one. If we look at listeners in the locust plugins repo, we can see solutions for this for other metrics collection systems. Timescale is one such example. I decided that a cloudwatch listener plugin is the way to go.\nWhat does this plugin do? The plugin is simple. It hooks into the events generated by locust, gathers the data from the event hooks, converts them into metrics and uses a client (boto3) to push it into Cloudwatch.\nGive me more details buddy\u0026hellip; Locust provides a set of event hooks, which can be used to track various actions \u0026amp; events of locust.\nThe cloudwatch plugin works primarily using 2 event hooks (it actually uses 4, but 2 are important):\nWhen locust initialises, it calls the init event hook. Our plugin is bootstrapped as part of the event hook. The user of the plugin does this step. Checkout an example for Application Insights. The cloudwatch plugin also does it in similar manner:\nWhen each request is completed (successful or unsuccessful), the request event hook is called. All the data related to the request like request type, URL of the request, response time etc. are passed as parameters to this call. This is the primary source of data for creating and publishing metrics of a performance test. The plugin registers this event hook when it is instantiated as part of bootstrapping. Application Insights example here - focus on line 26 (last line). The cloudwatch plugin does it this way (line 168):\nNow the data is all available, so all the plugin has to do is to push it to Cloudwatch. Sounds easy right. It is easy, but the plugin does a little trick:\nInstead of just passing the metrics to Cloudwatch at the end of each request, the plugin batches them. Why? Because posting metrics to Cloudwatch costs money at request level. So, instead, it is better to batch them \u0026amp; send it. Cost reduction is always a good idea!😄🤩 Also, this approach optimises the time spent in publishing these metrics.\nThe request data is encapsulated into an object RequestResult which provides methods to convert locust raw data to meaningful Cloudwatch metrics.\nDig more using view raw. This object is stored in gevent.queue.Queue - line 200.\nOnce a batch of requests has been queued in, the plugin will create metrics out of them and send them to cloudwatch in batches (lines 203-204). Two constants govern the limits of this behaviour.\nThe first one focuses on the limit of actual requests batched. The second one is focused on batch size of metrics sent to Cloudwatch - (one request can lead to more than one metric record - request count, response time, failure count etc.).\nThat is it! If you want to look at the code in full, check it here\nWhere does the plugin run now? The plugin (a version of it) has been running in Simpl perf environments for one of the services for more than a year. More teams/services within Simpl are adopting it now.\nThe version which is running inside Simpl has some support for configuring AWS Cloudwatch response time alarms as well. But we have not open sourced that yet (hopefully can do it soon).\nWhere is the code now? The pull request was submitted to the main github repo, and it got approved and merged into the master branch. It was released on 18th Oct as part of Release 4.1.0. You can track all releases here. The locust plugin repo has other useful plugins as well. So you should check it out fully.\nHow did the process of open source contribution go? I had thought of contributing this plugin sometime back in January 2023. I raised a Github issue and discussed with my CTO Puneet Singh to get his approval- He was all for it. But before taking the next step, life got in the way and I dropped the ball; the issue got closed.\nI picked it back up in the last couple of weeks and actively started the contribution process. Lars Holmberg, the maintainer of the plugins repo and the main locust repo helped me through the entire process.\nWe had very useful and timely interactions on the locust Slack channel. Apart from the plugin code, I created an example usage file (referred above) as well as a basic test for the plugin. Lars suggested and helped me with creating these. He also helped me improve the code of the plugin to make it easier to understand and to conform to the policies followed by the locust development process. And in quick time, the plugin code got accepted. It was a swift, constructive and satisfying process.\nI have not made too many open source contributions till date, but this experience makes me want to do a lot more of it. Thanks Lars Holmberg for helping with this.\nConclusion This is my first significant open source contribution. I know it is very late in the game, but it better late than never. This experience has made me believe that this process is a worthwhile one. My journey has only started, and I hope to do more. Also, hopefully this post will encourage you to do more of this and not wait for long like me. Wish you a happy time doing open source!\n","date":"2023-10-22T00:00:00Z","permalink":"/locust-cw-plugin.html","title":"Locust statistics in AWS Cloudwatch"},{"content":"You must be thinking: \u0026ldquo;Forget Why! What the h*** is DDAT?\u0026quot;.\nWhat is DDAT? DDAT is an acronym for Developer driven automated test. The term is a mouthful, so I will use the acronym in the rest of the article. And maybe it will catch on. Wishful thinking!\nDDATs represents tests, which I, as a developer, write to test my own code. These are tests that run automatically and are built by the developer for her/his own need.\nI know the next question in your mind - \u0026ldquo;Why not just call it unit tests?\u0026rdquo;. That is the name I also started with. But the term Unit testing is so prevalent, and it means different things for different people. So DDAT is almost like a Unit test, but more flexible to represent what I need from my tests as a developer. Having said that, if you substitute DDAT with Unit test, I am fine with it.\nOne of the reasons for not calling DDAT as a unit test is because it may not strictly fit into definitions of Unit tests, as widely held in the community. For example, many unit testing aficionados clearly recommend that unit tests should not be touching databases. There are very good reasons for it (primarily speed of execution) and I agree with those reasons. But what should I do when I am testing the data access layer:\nShould I create a unit test which mocks out the actual database from these tests? If I do that, then what am I really testing? What is the value of such a test? Should I just ignore tests for the layer? Can I live with that uncertainty? Some people would say that we should just write an integration test for the data access layer. And hence, I moved to my own term - DDAT. DDATs are just good tests which allow developers to write good code in a confident manner. It allows developers to do refactoring with peace of mind. They might be unit tests or integration tests as per the need. But they serve their masters - the developers of the code.\nThis post is not about\u0026hellip; This post is not going to provide a recipe or tutorial for creating DDATs or Unit tests. There are numerous articles on the subject. Down the line, I will write about my own learnings on the topic. But this post is not going to cover it. This post is focused on Why DDATs?\nBefore Why? I have already established that DDATs are a close cousin to Unit tests. There are a lot of detractors who site the disadvantages of Unit testing. So these qualms apply to DDATs too. Let us look at a few prominent ones:\nExtra work and extra time spent on tests. Have to keep them well oiled. These can give a false sense of security. These can be brittle and keep breaking. All these are valid concerns, and we need to know them and manage them.\nThere are also patrons of Unit tests. What do they say?\nUnit tests are great at busting bugs They allow fearless refactoring of the code. They promote better collaboration between developers by acting as documentation. Good tests ensure that debugging issues can be much faster Improve the stability of the code. These are true on the whole, but there are things to take care.\nNow that, we are finished with thoughts shared by others, let me start with my own why\u0026rsquo;s.\nWhy? Feedback! DDATs provide feedback to improve! - Image by Freepik\nThe cornerstone for creating a system of continuous improvement is Feedback. DDATs provide feedback during execution, but it doesn\u0026rsquo;t stop there. While reading DDATs and the code \u0026amp; interfaces that these helped us to create, we get feedback on how the solution has been developed. We get feedback on our code design when we write the tests. The quality and readability of tests also tell us how good our code is.\nTo reiterate, feedback is how we create new and better things - ask any person who has built anything of significance. In development, instead of thinking up all the design ideas all the time, we can look at the code and its tests and these can reveal new responsibility owners \u0026amp; roles (as feedback).\nEarlier we get feedback, faster we can improve a system. We can figure out mistakes faster. Debugging is faster with DDATs because it reduces the time you spend on debugging at the first place.\nDDATs are a living feedback system. That is why!\nWhy? Modularisation DDATs modularise to manage. Image by Freepik\nAnother aspect about writing DDATs is that we end up modularising our software. Whenever we have code that does a lot of things, it becomes very difficult to test them. So we split them up. For example, we take out stuff which deals with, say, external systems or databases into separate classes so that we can test the business logic without worrying about those concerns.\nDDATs help us to develop a nose for overcrowded (non-cohesive) and coupled code. If we are mocking too many objects to test a System Under Test (SUT), it tells us that we have too many dependencies and the SUT is probably dealing with too many aspects of the system - time to split it up.\nWhy? Independent Development Developing anywhere anytime on our own with DDATs. Photo by Andrea Piacquadio\nA very important thing that DDATs enable me to do is, I can test things independently and move forward with development. I don\u0026rsquo;t have to depend on other systems or other people.\nAs long as a test can run within the confines of my machine without having to reach a network, I find that test to be useful. It is ok to touch a file or db within your machine (this is my opinion and also why I call it a DDAT). If I am traveling and cannot connect to a network, I am still able to run my DDATs and hence make progress.\nHaving this ability gives me a lot of power and convenience. I can confidently move forward and don\u0026rsquo;t need someone to endorse things. Also passing tests act as visible proof of things working instead of just a mental level confidence. Great programmers may not need this, but for a normal developer like me, this is a good thing. As an added bonus, failing tests give me a quick and focused way to debug my code.\nWhy? A client perspective Simple interface before a complex system - a client's perspective: Image by Freepik\nDDATs test our code by acting as a client to your code. This means that when we write them, we are not really thinking of the implementation, but about how the code is going to be used - the interface. It might not look like a big deal, but thinking in terms of interfaces - to think about what to do (instead of how to do) - is a key technique to creating quality software.\nSeasoned developers do this interface based thinking automatically, but it is always good to have a tool in our box which helps us stay the course. For budding programmers this can be very handy. A more pronounced version of interface-based thinking is observed when you do Test First (TDD) - at least that is my experience. But even if TDD is not your cup of tea, DDATs written after can still be useful for achieving this.\nWhy? To conquer fear DDATs help conquer fear and make refactoring work: Image by Ulrike Mai from Pixabay\nA good battery of DDATs means that we have protection to refactor our code. This means that I can go ahead and improve the quality of my internals without the fear of breaking something.\nThere are too many times (can\u0026rsquo;t keep count), when my code got better by 2x or more after refactoring. Without DDATs, I wouldn\u0026rsquo;t dare touch working code. Just like we need insurance in other aspects of life, DDATs provide us with the same effect when writing code.\nIt\u0026rsquo;s not all hunkydory! DDATs might offer us a lot of good. But it does not mean that it comes for free. These are work - both in terms of quantity and quality.\nWhen running against time (which happens in many startups and sometimes other companies too), creating DDATs is extra work. Also, they have to be done with our thinking caps on:\nWe need to think through scenarios that need to be tested (especially the failure ones - we are particularly bad at it as developers). DDATs need to be written in a way that they are not too coupled with implementation details (which makes them brittle and render them useless). The tests need to be written with care so that, when they fail, the error messages make sense. The mental effort is there. There are a bunch more things to keep in mind and that is probably a topic of another post. AND all this effort is not one time, it is something you have keep doing (keeping it well oiled). So I agree with what others said earlier.\nOne thing though - this effort is an investment for getting those benefits mentioned above. Also, if we do this regularly, we will build the mental muscle and the sensitive nose required for becoming better developers!\nAnother aspect that comes into play, is the language or platform or ecosystem that you are working in. Some platforms/ecosystems have a very rich set of tools and libraries which allow you to create DDATs with low effort. Others can make it a very laborious and tedious process.\nSo when you make choices of tech platforms, testability should be very important criteria in their selection. Neal Ford from Thoughtworks categorically mentioned this in one of his talks that I attended long time back. If you are stuck with a primitive platform (in terms of testing capabilities), you might be tempted to skip DDATs. I can\u0026rsquo;t blame you, but in my opinion it is worth sucking it up and doing the work. It will add value.\nDDATs might touch files and call other systems like databases. To me this is useful and manageable in the context of local testing in my machine. Using the same in a Continuous Integration (CI) setup can be a little more challenging.\nHaving said that, with technologies like containers (e.g. Docker) this is no longer a deal-breaker. I think with a bit of work, we can get things working in our CI setup as well and that makes DDATs super useful for the entire team. I have done this myself many times and so can you.\nDDATs are not a silver bullet. They are useful to get the benefits like feedback and independent development, but that does not mean, you completely rely on them and forget everything else. For example, if we use DDATs as the only source of feedback and don\u0026rsquo;t have a QA team doing exploratory testing then we are shooting ourselves in the foot. If we become brash about our independence and don\u0026rsquo;t get the code independently tested and reviewed then God save us and our code.\nA word of general caution: No form of testing (not just DDATs) will eliminate all bugs. Expecting that is asking for perfection which is an impossible task and a fool\u0026rsquo;s errand.\nConclusion If you have read this article you probably already know what I am going to say next. For others, the gist is:\nUse DDATs since it provide critical benefits - feedback, independence, modularisation etc. But using them doesn\u0026rsquo;t come cheap. And I would always use these.\nAum sarvam SriKrishnarpanam astu.\n","date":"2023-09-22T00:00:00Z","permalink":"/why-ddats.html","title":"Why DDATs?"},{"content":"Programming is already a very important skill in today\u0026rsquo;s world. It is not a stretch to say that it is an essential skill. Professionals from all areas want to learn a bit of programming to get an edge. Kids are excited about learning programming and schools are encouraging them by either having it in their course curriculum or as a differentiating aspect of their training. And learning programming using the Python language has been all the rage for some time now.\nI have had this thought for some time. So, sometime back, I created a video course (in YouTube) on Python fundamentals, which is aimed at kids. The intention of the course was to give the learner (who has no programming experience), the fundamentals of Python and a basic sense of programming. This post describes the details of what I covered in these video sessions.\nPykidz Course Curriculum The course focuses on the following areas:\n1. Introduction to Python As the name goes, this is an introduction. It starts talking about why one should learn programming, and why learn python.\nThen, I provide a brief idea on how you can install python in your machine. I also talk a bit about python versions. Then I get hands-on and demonstrate the usage of the Python shell.\nThis video also covers how we can do calculations (on the shell). You get an understanding of the operators in python. The most important concept covered in this session is variables.\nAll of this is covered in a single video! At the end, you will know why programming and python and how to get started.\nFirst (and only) Video: Notes \u0026amp; Slides: Pykidz Sessions - Session 1 Notes Slides\n2. Basic Data Types The second session / video covers all the basic data types supported by Python. This includes numeric types (integers - int and floating point numbers - float), strings and booleans. I demonstrate operations on these different data types to provide a deeper understanding on them (special focus on strings). At the end of the session, you will know the various kinds of data that you can work with in Python.\nFirst (and only) Video: Notes \u0026amp; Slides: Pykidz Sessions - Session 2 Notes Slides\n3. Fully Hands on: A Get your hands dirty session! After a couple of sessions that were a little heavy on theory \u0026amp; concepts, I made this session (consisting of 4 videos!) to help learners get their hands dirty with working code. The intention of this session is to get you to write a couple of simple working programs.\nThe first video is about taking user input interactively in the program. This is useful for writing dynamic programs - they can do things based on what users want. The next video is about getting you to know, how you can write code in source files instead of just working with Python shell. The python shell or REPL is great for trying things out quickly and learning stuff, but if we want to write programs that we want to keep around and run multiple times, then using source files are the way to go. The third video is about using imports - a way for you use code others have written. I demonstrate this by importing functions from the standard library. This is a key learning. After discussing these learnings, I build the two programs which I initially talked about. You can attempt them yourselves before you look at the video and follow along. First Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 3 Notes Slides Source Code\n4. Python Lists After completing the sessions till now, you, the aspiring developer, have a basic idea on python data types and have written some programs. You know how to take input from the user, and manipulate that data. You have got your feet wet in the world of programming.\nIn this next set of videos, I briefly introduce the different data types that allow us to store more than one item of a given type.\nLet me give a couple of examples: a collection or list of fruit names or a list of subject scores etc. These session videos (4 again!) focus on a specific collection type called lists. I demonstrate how you can define them, access elements or items in them, slice them, add/remove items, membership etc. Before I dive into the details of lists, I cover comparison operators in Python (we already covered basic operators in the second session) which are very important for you to know down the line.\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 4 Notes Slides\n5. Other Composite Types This session content is split into 3 videos. Each covers one of the remaining main collection data types in Python. We start with tuples, which feel very close to lists but has a very significant difference. The second video covers dictionaries which are not just a collection of things, but a collection which is indexed by a key - hence key value pairs. The last one covers sets which is a collection of unique elements only. For each of these composite or collection data types, I describe typical topics like definition, access, membership etc. I also cover properties \u0026amp; operations that apply to that specific type. By the end of these two sessions, you will know all that is to know about working with collections of data.\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 5 Notes Slides\n6. Conditionals Most computer programs which we use, demonstrate the ability to do different things in different situations - decision-making. They have an ability to check things and ask for corrections. For this to work, it is important for a program to execute alternative steps depending on situations and conditions. This is where conditionals come into play. The session is split into 5 videos. These videos explain the key conditional statements like if, else, elif. But, they don\u0026rsquo;t stop there. Key python concepts like blocks, the None keyword, the importance of whitespace are also covered in these videos. I end this session with a couple of problems for you to solve. Now you can make decisions within your code.\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 6 Notes Slides Source Code\n7. Loops We started on the path of controlling flow when we learned conditionals. Another great power of a computer is to be able to repeat a set of tasks as many times as you need without committing any errors. We humans get bored with repetition, so it is a good thing that computers don\u0026rsquo;t. I am sure you will appreciate this!\nLoops in python allow us to do that. A more technical term for looping is iteration. In these set of 15 videos (phew!), I start with explaining the term iteration and then get into its details. After that, you will the basics of while loops, and dive deep into the break and continue statements. I then cover infinite while loops and nested while loops as well.\nAfter covering while loop in detail, I explain for loops. I cover iterators, and provide specifics of how the for loop works. I go through all the related topics just like I did for while loops. Finally, I close the session off by giving a problem for you to solve.\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 7 Notes Slides Source Code\n8. Modular Programming The next key concept to learn is modularity. I go over functions \u0026amp; modules in python in a set of 13 videos!\nFunctions are a fundamental concept in programming and I cover its importance in good detail. You will understand the mechanics of defining \u0026amp; calling functions. I discuss passing arguments in a lot of detail and then complete this section with an explanation of the return statement. Now you know to write code that you can reuse again \u0026amp; again in other parts of your code.\nThe next set of videos cover python modules. It explains the concept first. It then shows how you can create them and use them using imports. More module details like executing it as a script, reloading it etc. are also discussed. I also have a short mention of python packages.\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 8 Notes Slides Source Code\n9. Exception Handling The last session of the course is about Exception Handling. I feel this is an important lesson to learn for all programming beginners. When you do any kind of development, you will hit upon errors. Having an understanding of what they are and how they work is key to progress with the program. It is an essential skill you need to develop as a programmer.\nThis session consists of 6 videos. I start off discussing syntax errors and exceptions - what they are and how they work in real code. I then show you how to raise exceptions and how the flow works when exceptions happen. After getting a runtime understanding of how exceptions work, I dive deep into the way we would be handling exception in code. I cover an important gotcha (crime!) before closing the session with the finally block (pun intended!).\nFirst Video: NOTE: Links for next videos of the session are present description in this YouTube video.\nNotes \u0026amp; Slides: Pykidz Sessions - Session 9 Notes Slides Source Code\nConclusion That is the high level overview of the entire course material. If you want to just get at the entire set of videos of the course, checkout this YouTube playlist.\nIf you want to get hold of all the notes, slides and source code, they are in GitHub. You can also download it here.\nMy ulterior motives The initial reason for starting the video course was that it could be useful to my daughter and for other kids like her. These videos have been out there for some time, but I don\u0026rsquo;t think they have reached many people. So I decided that I will write about it here (I have a small audience here, You), so that people who visit my blog (you) can take advantage of the course if they need it.\nThere is another reason for doing this. This is my first attempt at creating a video based course (learned a bit of video editing - it is hard work!). I am sure that there is a lot of scope for improvement. I want to get more feedback from you on this attempt.\nMy daughter has already given one key feedback - my individual videos are too long! I tried to change that in the later sessions, but did not always succeed. There could be a lot more feedback, and I would be very grateful for your help. I hope to make a better version of the course soon. And God willing, I will attempt to make other courses in the future.\nAum sarvam SriKrishnarpanam astu\n","date":"2023-08-10T00:00:00Z","permalink":"/pykidz-basic-course.html","title":"Pykidz!: My Python Course"},{"content":" TL;DR\nA spiritual code for me to live by. Geethopadesam: IM3847, CC BY-SA 4.0 , via Wikimedia Commons\nI made the choice I attend a Bhagavad Gita Satsang every Saturday. On that day, Kothai Ji (our Satsang convener) was asking us to volunteer for RRE (Repeat, Recall, Enjoy) sessions. The choices were the chapters 10, 11 and 12. For some moments, there was silence. I had mentally made my choice, but was hesitating for some reason. As soon as Anand Ji picked chapter 10, I immediately pounced on chapter 12 (choice verbalized). Ravi Ji picked the remaining.\nWhy did I pounce on Chapter 12?\nAt the Satsang, we had just concluded this chapter. The chapter is comparatively a small one. It has only 20 slokas. Ravi Ji commented that, during recitation classes (which he had attended earlier), this chapter is picked up first because of it is simple and musical in nature. \u0026ldquo;It is easy to pick up\u0026rdquo;.\nBut these were not the reasons for me to pick the chapter. We had spent six 1 hr sessions on the discussion of this small chapter! It is a fascinating chapter. It is packed with so much relevant information for me that I felt compelled to pick it up for the RRE session.\nI have now finished the RRE session. But I thought I could do more. I am going to talk through the ideas on this chapter in this post. It would be my own understanding of it. Don\u0026rsquo;t worry, I am not going to write a bunch of Sanskrit verses here. I don\u0026rsquo;t have a good handle on the language anyway. My focus is only on the meanings and stories which I heard or read when I went through those slokas.\nHow do I render it? When I was preparing for the RRE session, I was initially not sure how I should conduct it. I could go through it sloka by sloka and tell the meaning and move forward. But the time available was only for an hour or less. I was not sure if I can finish it inside the time with that approach. So I decided to use a different technique.\nI will still go in order of slokas in the chapter, but I split the chapter into three themes:\nThe two paths of worship The keys/techniques to reach the Lord How does the Lord\u0026rsquo;s favorite devotee \u0026ldquo;look\u0026rdquo; like? I will cover these themes here. The intention is not to cover every sloka but to focus on these themes.\nThe Two Paths of Worship Arjuna has just seen the Vishwaroopa of the Lord (Chapter 11). While he felt it was awesome, he felt some apprehension too. Lord Krishna had also told him that without devotion, the path to god is not available. So, Arjuna asks a question:\nWho is the better yogi? One who worships you in your current personal form or the one who worships your unmanifest, unthinkable, immovable, unchanging form?\nWhen I prepared for the RRE, I came across the names to call these separate \u0026ldquo;versions\u0026rdquo; of God. The personal form is called \u0026ldquo;Bhagavān\u0026rdquo; and the unmanifest one is called \u0026ldquo;Brahman\u0026rdquo;. There is a third version called \u0026ldquo;Paramatma\u0026rdquo;, which I don\u0026rsquo;t clearly understand yet. So we will just stick to the two.\nSo Arjuna\u0026rsquo;s question is who is the better bhaktha, the one who prays to Bhagavān or the one who prays to the Brahman.\nThe Lord replied:\nThe ones who worship me with supreme faith and is always devoted to me, with mind and intellect fixed on me; they are the best yogis. That said, the ones who worship Brahman with complete devotion by staying equanimous, showing firmness of mind and doing good to all beings, they also reach me.\nThe takeaway is - both paths work. The \u0026ldquo;qualities\u0026rdquo; mentioned for the Brahman devotee were intriguing.\nThe Lord does not stop there though. He goes on to say that \u0026ldquo;the path to Brahman is not easy for embodied beings\u0026rdquo;.\nI think this is subject to multiple interpretations.\nOne interpretation is that humans like us can understand and relate to other beings who have a body. We can wrap our mind around them. The unmanifest, unthinkable Brahman as a concept, is not easy to grasp experientially and to follow on a day-to-day basis. I feel this is important. I think I understand the concept of Brahman intellectually, but I am not even sure of my intellect, and it is also not always in control of me. Sometimes, I am lost in my mind or my body. Understanding or knowing the Brahman in all these dimensions is not easy at all. This is what I felt.\nThere was another interpretation I read. The path to realization is a very difficult one. One needs to grace of God to make this possible. But the Brahman is called \u0026ldquo;Nirguna\u0026rdquo; or One WITHOUT attributes, and that means the path to Brahman is tougher because Brahman cannot provide you grace. This is probably controversial, but it appealed to me for some reason.\nOne of my references compared the two paths or the two versions of God as a monkey mother and a cat mother. The child (us) of the monkey mother (Brahman) has to hold on to the mother whatever happens. The mother itself will move all over the place but will not offer any help to the infant. The onus is on the infant to cling on. On the other hand, the cat (Bhagavān) holds the kitten with its mouth and takes it wherever it goes. The kitten gets all the help to take the path with the mother. So it is much easier. I felt it was a nice metaphor to understand the difference.\nOverall, the path of Bhakthi to the Brahman is tougher, and it could be beneficial to try an easier path. The easier path is not a cakewalk. It is tough (as you will see soon), but it is easier in comparison.\nKeys/techniques to reaching the Lord Lord Krishna talks about the 4 techniques to reach Him.\nApproach 1 \u0026ldquo;Fix your mind on him and surrender your intellect to him.\u0026quot;\nThis means that you are in complete unison with the Lord at all times. You are thinking of Him, and you are feeling Him all the time. There is nothing else. This approach is very difficult if not impossible (at least for me!).\nApproach 2 So the Lord gives the next technique which is relatively easy.\n\u0026ldquo;Regularly practice meditating on Him through the mind and intellect\u0026rdquo;.\nMeditation: Photo source from PublicDomainPictures.net taken by Charles Rondeau\nhttps://www.publicdomainpictures.net/en/view-image.php?image=288318\nThis is similar to the previous one, but in this there is an acknowledgement that it is tougher to stay always in unison with God, for a being like me (us?). There is also the concept of practice invoked here. So a regular meditation practice where you are meditating on the Lord, is a good way forward.\nThere are no details specified, like how long the practice should be etc. My interpretation is that we start the practice in a small manner. As we practice we get better, and we will be in the meditative state for longer durations.\nApproach 3 If you are unable to practice meditation, then the next idea is to\nBelieve and think that you are working for Lord Krishna himself.\nThis means that, when we are performing actions in our day-to-day life, we do them for the Lord. For example, if you are working to feed your family, you can imagine that you are doing this to feed God\u0026rsquo;s children.\nMy own alternate interpretation is that by feeding my family, I am keeping them alive so that they can make progress in their own pursuit to reach God.\nAgain, this technique is no cakewalk, but for people like us who have to perform actions daily, this seems a more feasible approach.\nApproach 4 The Lord is kinder and offers a simpler way. If we are not able to even think that we are doing actions for the Lord, then the next approach is\nDo the action and take the results of the same and offer it to Krishna. This means that I don\u0026rsquo;t have to think of the Lord at the time of action. Once the action is done and the results or consequences (good or bad) come, I offer it to the feet of the Lord.\nThis can be offering all your mistakes and misdeeds to the Lord as well. Having said that, I don\u0026rsquo;t think this entitles us do horrible things and then put the blame on God. It means, we realize that the outcomes of our actions (even good ones) are not in our control, and we readily offer them to the Lord so that we can be at peace.\nWhen I look at these 4 techniques, I felt that they are steps in a progression. If you are able to first give up the fruits of action to the Lord, then slowly I expect to be able to start thinking of the actions as being done for the Lord himself. Given that my mind is fixed in the lord when I do actions, that leads me to a practice of meditation even when I am working. When the meditation practice reach its zenith then I am completely immersed in the Lord through mind and intellect. A progression!\nMy own path has been to attempt all the last 3 techniques whenever \u0026amp; wherever possible. I have set up a reasonably regular cadence of meditation albeit for a very short time. I try to regularly remind myself that I am doing God\u0026rsquo;s work before I start something(not very successful in this). The giving up the fruits of the action is tougher because of the deep-seated Ahankar in me. The hope I have is that, the regular practice will help in all these counts.\nThe next section is about qualities of a true Bhaktha. This is a long one but it is my favorite.\nLord\u0026rsquo;s favorite devotee Lord Krishna discusses the qualities of his favorite devotees in 7 slokas (12.13-19). I am classifying these qualities into two aspects:\nHow the favorite Bhaktha thinks internally or looks inward? How the Lord\u0026rsquo;s favorite Bhaktha treats others? Internal thinking The Lord talks about many qualities about mindset of his favorite bhaktha. I am going to enumerate some key ones:\nEquanimity \u0026amp; Equipoise A beloved bhaktha of the Lord will act with equanimity in both joy and sorrow. She doesn\u0026rsquo;t get too excited or exuberant when she is happy. Similarly, when it is a time of sorrow, he doesn\u0026rsquo;t get downright sad and weepy. Visually speaking, true bhakthas are able to look at both with a slight smile in their lips.\nI know this is easier said than done. During our Gita session, Kothai ji reminded us (paraphrased by me) \u0026ldquo;One cannot be perfect on this. The important thing is to reduce the frequency (F) of the highs and lows, reduce intensity (I) of these moments and reduce recovery time (R) (come back to normal state)\u0026rdquo;. I created an acronym for this - FIR. So reduce FIR. This needs practice (Abhyasa).\nRamakrishna CC BY-SA 3.0 via Wikimedia Commons\nA story of Ramakrishna is apt for this point of dealing with sorrow or handling tribulations.\nRamakrishna was a great bhaktha of Goddess Kaali. There was a time when he was diagnosed with cancer!\nHis followers loved him and did not want to lose him. So they got together and asked him to pray to Goddess Kaali to cure it.\nRamakrishna replied with a smile \u0026ldquo;Right now, my mind is full of the devotion for the Goddess. Why would I want to change it to think about cancer?\u0026rdquo;.\nFor Ramakrishna Paramahamsa, the ailment of cancer did not cause trouble. He was too immersed in Bhakthi to care about it. This level of Bhakthi is not easy to achieve but once you get there, there is no looking back.\nThe related idea here is that a beloved bhaktha is not worried or tensed about anything. This does not mean that they don\u0026rsquo;t care about people or don\u0026rsquo;t have compassion. It does not mean that they are apathetic - that will be a tamasic quality.\nI think this state of a calm mind comes from the fact that you realize that results are not in your hand, and you can only do your actions in the best way possible (\u0026ldquo;Nishkama Karma\u0026rdquo;). So as an aspiring beloved bhaktha, my interpretation is, I will be receptive to feedback as a way to improve my actions and not as a way to characterize my ego (as good or bad). A beloved bhaktha has renounced both good and evil and laid it at the feet of the Lord.\nThe Lord also talks about being alike to friend and foe. To me, this means that we stop looking at people as foes. If all are friends then you will treat them the same way. This is not easy for mere mortals like me. In the Satsang, Guruji\u0026rsquo;s words said \u0026ldquo;Whomever you consider as enemy (they have done some actual harm to you - my words), start thinking and praying for their wellbeing on a daily basis\u0026rdquo;. The idea is to actively replace feelings of hatred with feelings of love and care. This feels like \u0026ldquo;active forgiving\u0026rdquo; (my term) and will lead me to a better path to treat them also as my friend.\nGuruji mentions the same idea to be used for people we are jealous of (they have not done any actual harm but our ego perceives so, because of jealousy). Why would these people need forgiveness from us? It did not make sense to me. So, I changed its meaning to think that this act is a chance to forgive ourselves and get into a better/calmer state of mind.\nThe Lord talks about being alike to honor and dishonor. In my own petty and silly ways, I have had these feelings of loss of honor, and they have taken me for a spin. If I can treat them with equipoise then I will be closer to the Lord. Guruji gives the example of the \u0026ldquo;Bahu\u0026rdquo; in serials who goes through so many bad situations which causes her to be dishonored, but finally getting vindicated at the end. This was a fun example and very relatable. Having said that I felt, if I am truly equipoised, vindication is not a feeling I will need or even identify with. Doing this is not easy and again practice is key.\nContentment The Lord says that his dearest bhakthas are contended. They are contended with what comes their way. They don\u0026rsquo;t have wants - they want nothing. He expresses this multiple times in the slokas.\nWe discussed this in the Satsang. Kothai ji came up with an acronym here - ZCC - Zero Cribs and Complaints. This means that whatever life throws at you, you move forward without cribbing or complaining about it or about others. I feel that this is about reducing (if not eliminating) expectations. I also feel this is related to our ego.\nAn example which came to my mind was about our own need to impress people. Whether I am giving a talk at our office or attending a Gita session, my mind wants to do actions which impress people and make them think that I am good. I can do whatever actions I want, but my expectation of people getting impressed by them is not guaranteed. So I get disappointed. If I am able to just give my talk with my utmost ability and welcome whatever feedback comes out of it with the right mindset then I have a chance of feeling contended. Else I will always feel disappointed.\nSant Kabir License - Devendra Jaiswal, CC BY-SA 4.0 via Wikimedia Commons\nThe other related aspect is reducing our needs for things, which can lead to contentment. This does not mean that we avoid basic needs. There is a doha from Sant Kabir which expresses this nicely:\nmālik itanā dījiye, jāme kuṭumba samāya\nmaiṅ bhī bhūkhā na rahūñ, sādhu na bhūkhā jāya\n“O Lord, give me just enough for the bare maintenance of my family’s bodily needs, and for giving alms to the sadhu who comes to my door.”\nThis is also difficult to do, but we can slowly make progress. My tryst with minimalism (see my earlier blog post) also talks about reducing material needs. Hopefully, I will make progress on this and be on the way to become a good bhaktha to the Lord.\nI have also started a habit of maintaining a Gratitude dairy. This was suggested in the Satsang and I have also heard about it in a lot of other places. I have started this practice to identify the many good things that are happening to me, which can lead me to contentment.\nSubduing the mind The Lord mentions subduing the mind or controlling the mind many times. I think this as being self-disciplined. As part of the Guruji\u0026rsquo;s commentary and the Satsang\u0026rsquo;s discussion, we discussed pushing or training the mind to do the opposite of what it wants to do. Few examples :\nTake a cold water bath in the winter. Start watching a serial or a movie and drop it abruptly. Not checking slack in the morning (my addition). Subduing the mind - Take a cold shower: Photo from PxHere It is like working a muscle. You keep training it regularly to strengthen it. The mind is like a muscle. This has come out of scientific research too.\nThe practice of meditation where I am focusing on the breath is a way to train my mind. The mind still wanders, but I am training it to focus on the breath on a regular basis. I think I am making only a small amount of progress, but since I am in it for my lifetime, I am ok with the speed.\nIn the context of being a beloved Bhaktha, quietening the mind when needed, is an important trait.\nFirm resolve on the Lord Lord Krishna says his true Bhaktha is firmly resolute. This resolve or conviction is key to help her tide over the difficulties that will come in the path she has chosen.\nAlso, our conviction helps us to convince others without forcing them. Who am I talking about? I am talking about my family members or friends who I think will benefit by taking this journey. My firm resolve will demonstrate to them how this path can make someone strong. That can lead them to chose the path without any gifted salesmanship from us.\nFirm resolve is not demonstrated by words. Actions are required. That said, we need to understand that words are a starting point. Good words lead to good thoughts and good thoughts lead to good actions. Eventually, our actions speak louder than words, so if you want to show conviction, then act with conviction.\nFearless Lord Narayana says my beloved bhakthas are fearless. How to make this happen? I think this is possible if we have a lack of desire and if we are not attached to things or even people.\nThis is a tall order. I might be able to cultivate detachment from things with a lot of effort but being detached from the people I love is going to be difficult - because of my ego. Detachment does not actually mean that you stop loving them. It means that you love them without thinking that they belong to you. In a detached state, I care about their happiness and wish them well without thinking that I should be the reason for the same.\nThere is a saying that I have heard - \u0026ldquo;If it is yours, release it, and it will come back to you\u0026rdquo;. This sounds nice, but if you are really detached then you realize that nothing is really yours, and therefore it does not matter if it comes back to you. This is not easy, but it is an ideal state worth striving for.\nIf I make my mind like this then fear vanishes. If I feel that the bike I am using is not truly yours then I will not be worried about it after parking it somewhere. I say this because I do worry about this sometimes!😟 But if I can practice thinking like this then I can get to a true state of fearlessness.\nPure-minded A true Bhaktha of Bhagavān is pure minded. The Lord talks about both outer (take a regular bath man! 🤦‍♀️) and inner purity.\nI am focused on the mind related purity because it is a lot harder to achieve that. Our mind is made impure of different kinds of thoughts. Thoughts related to our ego, envy, anger, greed and lust come to us very easily. Most times we don\u0026rsquo;t even realize that we are caught in these thoughts since they pervade our entire consciousness.\nThe first step to changing this is to watch our thoughts. If I build some mindfulness and start watching my thoughts, I will at least become aware when certain kind of thought takes hold of me. One can be the judge of what kind of thoughts these are and take corresponding action.\nOnce you are aware, you can take steps to improve your thoughts. And as good thoughts are the way to good actions, we can make a difference to the world.\nAnother trick to having good thoughts is to read or listen to life and stories of good people or saints. This will lead us to better state of mind - purity.\nSkillful The Lord says, \u0026ldquo;My dearest Bhaktha is skillful\u0026rdquo;. I did not understand this initially. What has skill got to do with Bhakthi? After we discussed this in the Satsang, and after I thought a little more, an idea came to me. If I think that I am doing God\u0026rsquo;s work and show great dedication to it, then I automatically do a very good job at it. I am attentive to detail and want to persevere so that I do the best work for the Lord. If I do my work like this then I become skillful in it. So it became obvious that a true bhaktha is skillful.\nA related thought is being a \u0026ldquo;nimmitha\u0026rdquo;. This means being a tool for the Lord. Once you are just acting as a tool, then Lord will do the work through you and the work will be skillfully done. I was reminded of the movie Kantara. When the hero becomes a tool of the Lord, he is bestowed with so much strength that no villian is able to stand in front of him. He is just the medium, the Lord is actually doing the work.\nContemplative Contemplate: Photo by Verena Yunita Yapi on Unsplash Krishna mentions in one of the slokas that his dearest bhaktha is contemplative. This is another one which I did not find easy to comprehend. I can only talk about it through personal experience. Whenever I have been a contemplative mood, there is the feeling of a deeper force working in me. The mind is calmer and is able to wrangle through tough questions. Instead of the cacophony of discussions, a few hours of contemplative thought has led me to get better insights on anything. It could be even work projects. That is the way I understand this.\nRemove sense of ownership The Lord says that my beloved bhakthas have given up the sense of ownership. We know that, all things including our body have to be left behind when one dies. When I look at the world like this, the idea that I own houses or vehicles etc. doesn\u0026rsquo;t make much sense. But we always live with the thought that whatever we have will always be with us (including our loved ones) and our body itself is not something which will be destroyed since we own it.\nIf we are able to remove our sense of ownership of these things, then we have diminished our ego, and we will surely reach a better state.\nUnattached to Home In the 18th Sloka, Krishna says that my favorite Bhaktha is not attached to their home. The way I interpreted it is that such a bhaktha is NOT beholden to any of their identities. They don\u0026rsquo;t hold on to their caste or religion or language or any other form of identity. They realize that they are part of the grand union of the lord and hence identifying themselves with a particular aspect does not make sense.\nAlso, the life we live and the situations we are born into are so arbitrary (from the perspective of identity) that there is no point in being attached to them. Having said that, this is not easy to do. Throughout our life we have been attached to our family name (there are people who do honor killings for this). We are also identified with our language or our country. While it is ok to show love to your country men or your community men, it does not make sense to hate others. The concept of us and them is meaningless to a true bhaktha. Since all of us come from the Lord, there is only us and no them. The whole world is our kin.\nHere ends my discussion on Bhaktha\u0026rsquo;s inner state.\nTreating others Never have malice One of the first things the Lord says about his beloved Bhaktha is that they don\u0026rsquo;t show malice to other people or even other life forms. This means that I don\u0026rsquo;t carry malevolent thoughts towards other people or other living things.\nMy thoughts went to two places. With respect to living beings - mosquitos. I am not sure about you, but I have sometimes taken it as my life goal to eradicate all mosquitoes in my bedroom. I have gone on sprees trying to smash them to smithereens. After listening to this, I am not sure if this was a good thing. Why do I need to actively look for mosquitoes and kill them? It felt like I am doing it out of malice. It is different to kill a mosquito that is biting me, but my mind, actively trying to seek and kill them feels wrong. Even using a mosquito repellant seems better than to actively seek and kill. The intention is mellower, and it is to drive them away so that they don\u0026rsquo;t cause harm instead of actively causing harm to them. I will try to change this in my mind.\nNext is on people. Given my big fat ego, I sometimes harbor malicious thoughts about even my family members or co-workers. If my daughter does not listen to my advice on studying, a malicious thought about bad results does come to my mind. Similarly, if a co-worker comes with a counter-proposal at work, I think about how I want it to fail. Both are these are driven by my ego and my want to be correct. If I can suppress this, then there is a chance for me to be benevolent.\nWhile the Lord wants us to be not malicious to all in the world, I think we can start with our family and friends. If I can treat my family, friends and co-workers in a good way then I go a long way towards showing no malice to the world.\nBe Friendly and Compassionate The Lord says that we should be friendly to all. My \u0026ldquo;kutharka bhuddhi\u0026rdquo; immediately asks if Krishna was friendly to Duriyodhana. But when I think more deeply about it, I remember a lot of situations where the Lord actually tries to push Duriyodhana in the right direction but without success. When you try to be friend to all, it does not mean that they will reciprocate. But your own feelings to them should be friendly.\nSimilarly, being compassionate applies to all. Compassion shouldn\u0026rsquo;t be restricted to specific people and identities. That said it is difficult to show compassion to people who you are not even meeting. If I can show compassion towards the people I interact daily then I think I fulfill this aspect of a true Bhaktha.\nAlso, whether it comes to being friendly or showing compassion, we need to do it without feeling proud about it or wanting recognition for the same. That will just feed into our ego and build expectations in us. We need to show compassion like an old man planting mango saplings. He will not be able to reap the fruits (literally) of it, but he does it without any expectation of returns.\nOne aspect that Guruji brought up here was the need to be practical. We can\u0026rsquo;t really show compassion to terrorists. I am split about this. While I agree with Guruji that this is practical and sensible, I also wonder if deep compassion has the capability of making even a terrorist change. I am not sure, but compassion is not easy anyway, so let me start with showing it at least to my near and dear ones.\nForgiving Forgiveness is a virtue that a true Bhaktha has according to Lord Krishna. I have covered this a little in the previous section. It is important for us to forgive our enemies actively and not just forget about them. Actively send them loving wishes will ensure that our own mind is in a better state.\nForgiveness does not mean that all murderers need to be forgiven. There will still be need for punishment, but this act is done for betterment of society and not to inflict our hate and anger on others. It is done with a sense of duty. An executioner or even a judge is handing out punishment to an offender not because she hates them, but because she needs to uphold his duty. That mentality is required to practice forgiveness.\nDon\u0026rsquo;t annoy and don\u0026rsquo;t get annoyed In our day-to-day life, we don\u0026rsquo;t get angry all the time. But we do get annoyed. While this seems innocuous to us, this feeling builds on to increase our ego (this is for sure) and will potentially lead to anger at some point in time. And the thing is that we get annoyed on very small things and with even our loved ones.\nWe sometimes get annoyed by the actions of our children or the actions of the people who work for us. It is important to treat them well and with respect, so that we don\u0026rsquo;t give wings to these stupid thoughts of annoyance. Respect is a good antidote. That said, if your servant is not doing his job well, it is our duty to set things straight. Taking action respectfully to get better work, but without getting annoyed is good. It will lead to better outcomes for all involved.\nA completely different aspect is that we could have habits that cause annoyance for others. I have this bad habit of making weird noises with my closed mouth. It annoys everyone in my family. Sometimes I do it purposely for fun but most times this happens without me being conscious. A little more mindfulness can help in trimming this out.\nWe also annoy our children by giving them advice on a regular basis. We think that it is for their good, but it only leads to sense of annoyance for them. Especially for kids who are in their late teens, who are trying to figure out their personality, this kind of constant advice is very off-putting. Guruji\u0026rsquo;s says that it is criminal to offer corrections to anyone above 16 years old, unless they ask for it. I am trying to digest this and incorporate it in my life. That is the only way for me to ensure that my daughter will be willing to seek me out for help when needed, and the help I provide will reach her without causing annoyance.\nSant Eknath licensed under the Government Open Data License - India (GODL)\nThere is a story of a saint (Sant Eknath) who used to take bath in Godavari daily before his prayers. One person in his village was not fond of him. He decided to express this by spitting on the saint as soon as he came out from the bath. The saint returned to Godavari to take bath again. On his way back, this wily person spit on him again. The saint returned again to take bath only to be spat on again. This happened for 108 times. The wily person was flabbergasted and finally fell on the feet of the saint asking for forgiveness. The saint lifted the man with a smile and thanked him for giving the opportunity to bathe in the Godavari so many times to purify himself.\nThis is a story that demonstrates a lot of qualities of a true Bhaktha. This level of maturity is very difficult to achieve for me. That said, the story acts as an inspiration and as a reminder for the work that needs to be done.\nImpartial The Lord says that we need to treat all people impartially and based on their merit. While this is a fairly straightforward to understand, we need to take care that we determine merit without the lens of our own selfishness or ego. If we forget that, the meaning of impartial gets completely lost.\nConclusion I have explained the Bhakthi yoga chapter of the Bhagavad Gita in as much detail I can. Couple of last thoughts:\nThough this chapter of the Gita is said to be a small one, I felt that it is profound and filled with insights and pointers for me that it is difficult to take it all in. So I decided to read this chapter on a daily basis. The Guruji of the Satsang has also suggested the same idea (I realized it later on). So I have started doing this on a reasonably regular basis in an audio form. I am not sure if it will work for others, but I feel that this can add value to me.\nI had earlier asked you to take note of the qualities of Bhakthas of Brahman as specified by Gita in the first section. If you notice the qualities elaborated in the true bhaktha section above, you will realize that these are succinctly described by the same verse earlier. So it does not matter whether you are worshiping the manifested Bhagavān or the un-manifested Brahman, the qualities of the Bhaktha are similar in nature.\nWith this thought I will leave you to contemplate and digest this. If these ideas connect with you, I\u0026rsquo;ve continued this thread in Our Ultimate Quest: The Simple (Yet Complex) Answer — a shorter reflection on kindness as the core of the spiritual path.\nReferences Jivanmuktas \u0026lsquo;Amazing Simple Gita\u0026rsquo; - The Gita book we use in the Satsang Holy Gita - Found it as a useful preparation tool for my RREs even before Bhagavad Gita by Eknath Eswaran - A very sophisticated and succinct version of the Bhagavad Gita The Essence of the Bhagavad Gita: Explained by Paramhansa Yogananda - Just tasted this chapter \u0026amp; it was good. Chapter 12 BG video - My daily chapter learning/listening aid. Aum sarvam SriKrishnarpanam astu.\n","date":"2023-01-14T00:00:00Z","permalink":"/bg-bhaktiyoga-bhaktha.html","title":"Bhakthi Yoga - Bhagavad Gita"},{"content":" TL;DR\nEducation is the key to a better world for me \u0026amp; all my peers - the world. This is my first deep-dive to figure out what I can do in education. I have begun an introspection journey, and I am sharing it with you.\nA bit about me I have always felt that I need to do something in the field of education. Right from my time at college, I wanted to be a teacher. That did not happen. I started working in the Chemical Engineering field, but left it 1 year. Rest of my working life, I have been a software engineer.\nSo what have I done in teaching?\nI have conducted few sessions to teach something on software development or some business domain concepts to my fellow engineers. Always liked those sessions, but I have not done it for quite some time. I did a course on programming on Youtube as well. It was a lot of work, but it was satisfying. I learned a thing or two when doing it. I have taught my daughter some subjects when she was young. Teaching my kid - An illustration - Image by Daniela Dimitrova from Pixabay Teaching always felt good!\nEducation is more than teaching In later years, I felt that education is a much bigger idea than just teaching. Teaching is an aspect, but work on education needs to happen in multiple areas.\nPeople say \u0026ldquo;Being literate is not equal to education\u0026rdquo;. I agree, but recently, I realize that being literate is probably the first step to education.\nI also used to think that being educated means being good. You might say, \u0026ldquo;That is foolish \u0026amp; naive\u0026rdquo; and you are right. For someone to be good, they need not be literate or educated. Goodness can come from good practices, good conduct at home, etc. More than once, I have gotten clear proof that education and goodness have little connection.\nSo what is the purpose of education? What is the meaning of being educated?\nI think, it is ability to think for yourselves and know that there are choices in life at every moment. And also know that there are ways to find those choices and then exercise those choices. The true goal of education is to enable this for the educated.\nTo put it another way, education is necessary (but not sufficient) prerequisite for making good decisions in life. Every aspect of life needs decision-making.\nOk. I have got a working definition of what education is.\nNext, if I have to get educated or to get someone educated, what do I need to do?\nHow to get educated? I thought a lot about this and got one \u0026lsquo;clear\u0026rsquo;(🤔) answer. Life is probably the best way to educate us. Life experiences mold us and change us in many ways. Having said that, Life is not a great way because it leaves too much to chance. The results are unpredictable. Also, life happens to us anyway, so there is no real work required. So let me just drop that useless philosophical thought (🤯) into the trashcan and move to the next thing.\nWhat about acquisition of knowledge?\nIf I know more about things that happen in the world about ways to think and analyze the world then I become more educated. The key word is \u0026ldquo;know more\u0026rdquo;. How can I know more?\nLiteracy is a key step here. Basic literacy can enable anyone to read and know about anything of interest. When combined with the knowledge of using internet - a huge enabler - I can know more. And knowledge is power.\nBefore I dive deeper into knowledge, I want to be clear. I don\u0026rsquo;t think having a lot of knowledge is a guarantee to become educated. There are other aspects, but I am not clear on what they are. But having knowledge is a necessary condition.\nAs of now, my way forward is to focus on knowledge acquisition and knowledge transfer as a way to push all towards being educated.\nKnowledge acquisition levels I am thinking in terms of levels here. This is a categorization that I came up with. It is probably too rudimentary or naive. I am sure there is more refined ways (maybe you can help me with ideas and references in the comments), but I have to go with what I have:\nEnable basic literacy among people: I am talking about language learning and basic math capabilities. Both are required as a foundation to build anything. Enable basic internet literacy: Internet is the key resource of our information age. If I can help people to get on to it and navigate its waters then, it is a great step forward for them. Fine-tuning on providing basic skills: Once the basic access is created, fine-tuning both these areas is very challenging. I need to work on the quality of these interventions as it applies to recipient needs. Building higher order capabilities: The next big leap would be to cater to folks who have already got the basics right, but now need help to get to higher order abilities. There are different aspects to this one: Getting access to information \u0026amp; books to increase knowledge. Finding ways to help people use these resources to get some economic benefit. Training people to acquire higher order skills and into full-fledged professions Building a leader: The final step is where we can start changing a person to inspire others to follow their path. Some ideas to contribute Before I get to ideas, there are things to consider in the above-mentioned levels.\nWhich level is the most important one? Which is the level that will have maximum impact? At what level do I want to contribute and can contribute?\nWhat is the kind of impact I want to make. Do I want to impact more people broadly and in a shallow manner? Or do I go for a deeper \u0026amp; focused impact on a smaller set of people.\nWith these questions \u0026amp; considerations still buzzing in me, I came up with some ideas. I am using these ideas as a way to figure out what I want to do, and what I can do. These are going to be top of the head ideas - nothing researched or detailed.\nI will start off with ideas that have deeper impact on a smaller set of people. Again, this is just brainstorming and asking myself on how this could work for me. How I could do some good work? So please expect lack of clarity. This is pretty much a brain dump, so expect some ugly lumps.\nFocus on basic literacy and create deep impact on a small set of people How can I do this?\nBasic literacy for small kids - Photo by Yannis H on Unsplash\nI could join a primary school in a small town or village. I have never taught small kids (discounting teaching my daughter). So if I need to do this then I have to pick up the skills. I assume teaching at that level needs a lot of patience. That could be an advantage since I am generally considered patient, but I know that certain activities have tried my patience before. So the jury is out.\nIf I set aside the skill \u0026amp; effort needed, and focus on the outcome, then the idea has merit. If I am able to make 10-20 kids better at basic math and language, which allows them to step up to higher capabilities, it can be extremely rewarding. One key aspect I need to inculcate, is building some kind of regular discipline and cadence for the kids to learn. It is a key ingredient to be taught to all people if they want to do anything with life including learning. My wife has a knack of doing this. I could probably learn from her. I could probably involve her directly in this.\nThis idea has some legs and I need to think deeper on it.\nFocus on basic internet literacy \u0026amp; create a deep impact on a small set of people This one plays a bit more to my strength as a heavy internet user. That said, I see that lot of the younger generation are catching on to the internet faster than petrol catching fire.\nThis can be a fire hazard (pun intended) and lead to catastrophe for these young people. But I don\u0026rsquo;t think I am equipped to stop that from happening. It is difficult to control \u0026amp; monitor the activities of your own kid (a very bad idea, but I am just talking about feasibility). Here I am talking about controlling the activities of kids who are just students coming to a class - no authority, no accountability, potentially crossing all sorts of lines. That is a lot of mess!\nThis idea has some legs and I need to think deeper on it. Let us move forward.\nThis idea might work with a set of older people (middle-aged \u0026amp; above) who also need to get basic internet literacy. Once literate, they can better handle \u0026amp; guide the next generation (their kids) who they deal with on a regular basis. To do this, I would need to set up an adult education center and also need a bunch of used computers to be used by the attendees. Again it makes sense to do this in a village or small town setting (or even a slum like setting in a big city). This variation of the idea may work for me.\nWorking on alternative pedagogical techniques for basic literacy I could work to improve the quality of basic literacy efforts using different/innovative techniques \u0026amp; solutions. I have heard of some players in this social space like Pratham, Kanavu etc. They are trying to get plugged into existing schools to try \u0026amp; improve their output.\nThe ideas could be newer ways of learning, better tools (hardware or software), better processes etc. I need to explore this area a lot more. I feel, I could make meaningful contributions here based on my knowledge and experience. Having said that, I might be whistling in the dark. Need to dig in, to figure this one out.\nWorking on higher order skill development for a small set of people I could focus on slightly older kids already going to schools in small cities \u0026amp; towns and give them exposure to extracurricular learning \u0026amp; knowledge.\nHigher order capabilities learning - Photo by javier trueba on Unsplash\nThese could be areas like interpersonal communication, leadership, self-discipline, personal finance management, risk taking, career guidance etc. As a kid, I feel that I did not focus on these aspects and had to build (and still building) a lot of it over the years. Many students and their parents are not even aware that these areas are important.\nThere could be various ways to do this:\nCreate a small used books library containing a good collection of relevant books that these kids can borrow and read. I could augment it with discussion sessions or presentations which could encourage, inspire and help them understand the topics covered in these books. Create summary content on these topics from great books (like KukuFM). This can be difficult for me to pull off alone though. But do I need to do it alone? Work on career \u0026amp; higher education guidance programs which can help youth to figure out the avenues where they can add value to themselves and the society. LMES is a good example, but I think they are big and broad based. Instead, I could choose my work to be more focused by conducting \u0026amp; managing seminars to a smaller group of people. Speaking of LMES; that kind of setup can allow me to do such work which is of higher breadth and lower depth.\nMaybe it is time to explore those type of broad based ideas.\nWorking on improving basic literacy but in a large scale Solving basic literacy at a large scale but with lower depth is truly a scale and resource problem.\nOne naive idea could be to create a free mobile app which helps people to learn alphabets of specific languages and may even provide math lessons. This app has the potential to reach a lot of people. But expecting the app to create a deep impact (or any impact) in even a small set of people is not something I can count on. That said, this is an idea I could work with since I have some basic skills in this area (or at least I can build them relatively quickly). I still need to gain some pedagogical knowledge to make the intervention useful. The key thing is that it is very difficult to figure out the depth of impact with this idea and that can be a deal-breaker.\nWorking on improving internet access \u0026amp; literacy but in a large scale Building something which will provide basic internet access at a large scale needs a lot of money. Companies like Google and Facebook tried this (and failed or slightly succeeded). I need a lot of resources to do this. Or I need to come up with a revolutionary idea/tech, which is fantastic to be funded by somebody huge, and benevolent (or has the business acumen) to make this accessible to all. While they say nothing is impossible, this one is pretty close from my perspective.\nCreate high quality content for a lot of people Creating high quality content to build knowledge \u0026amp; skills for people to receive benefit like jobs or higher learning is a good idea. I can\u0026rsquo;t do it for all areas, but I could do it for some areas. Potential ideas are to build apps or make courses (attempted one without much success - not high quality I suppose!), which can reach a lot of folks - there are lots of platforms for that. Again, will they truly be useful and cause any meaningful change is difficult to figure out.\nFor large scale stuff, I am not able to think anything beyond creating apps or courses (online access based). Really seem to have dearth of ideas.\nStopping now Ok. At this point I have run out of ideas. Also, I have run out of steam to figure out more on this. Need a recharge. Besides some of these ideas need me to dig and research more. Without doing that, a decision is difficult to make.\nOne note for myself - I don\u0026rsquo;t have to pick one idea. I could pick more than one from above. Will I be able to do multiple things? - is different question. As of now, I will leave it here. Once I have some more clarity, I will be back to share my mind - on education and where I need to go.\nPlease do share you thoughts and ideas with me.\nAum sarvam SriKrishnarpanam astu\n","date":"2023-01-14T00:00:00Z","permalink":"/education-me.html","title":"Education \u0026 me - State of mind in 2022"},{"content":" TL;DR\nA good stand-up is always about the team. A team which shows ownership, respects each other and works with an agreed structure will do great. For many years, I have been part of teams that follow the agile methodology and practises some kind of scrum. One of the key practices in agile scrum is the Daily Stand-up or Scrum meeting. The DSM is done in different ways, and it is really up to the team to do what works best for them. That said, there are certain characteristics which are important to maintain, irrespective of the team which is following DSM. I explain these characteristics as I understand them and see fit.\nA typical Daily Scrum Meeting A Virtual DSM: Photo by Chris Montgomery on Unsplash\nIt is 11:30am in the morning. Every one from the \u0026ldquo;Delta\u0026rdquo; team has assembled in the virtual meeting room. Out of 13 member team (11 developers, 1 product owner and 1 engineering manager), only a few of them had turned on the video. Some kind of construction noise is heard in the background. Ram, the manager opens the scrum dashboard and filters the cards for Hasina, a team member.\n\u0026ldquo;Ok Hasina, can you please share your update\u0026rdquo;\n\u0026ldquo;Sure Ram. Yesterday, I was working on these items but got stuck on some testing issues. Ram, what is the priority of this task?\u0026quot;\n\u0026ldquo;Hasina, this needs to be delivered by the end of this week. So we need to plan accordingly\u0026rdquo;\n\u0026ldquo;Got it Ram. What about this other requirement? Should I pick that as well now or later?\u0026quot;\n\u0026ldquo;Let us do that later.\u0026quot;\n\u0026ldquo;Ok Ram. Other than that, I was able to close out this story NZ-202. I will be picking up new story today from the TODO lane\u0026rdquo;\n\u0026ldquo;Thanks Hasina. Can anybody who is not talking turn off their mikes? There is too much noise\u0026hellip; Gagan, can you share your updates.\u0026quot;\nHasina turns off her video. Also, the background noise dies down. \u0026ldquo;Ok Ram. I am facing some kind of strong migration issue.\u0026quot;\n\u0026ldquo;Can you give some context on this Gagan?\u0026quot;\n\u0026ldquo;Oh sure Ram. Yesterday, I was working on the status check API story and was trying to do the DB model changes. That is when I faced the problem.\u0026quot;\n\u0026ldquo;Can you explain the details of the issue?\u0026quot;\n\u0026ldquo;So when I try to deploy the migration script locally\u0026hellip;. blah\u0026hellip; blah\u0026hellip; blah\u0026hellip; \u0026ldquo;\nVikas, a developer joins the call. \u0026ldquo;Have you tried to close the console and start a new session\u0026rdquo; chimed in Winston\n\u0026ldquo;That did not help\u0026rdquo; said Gagan.\n\u0026ldquo;What about trying to restart the laptop?\u0026rdquo; Winston countered.\n\u0026ldquo;Come on, that is not a solution buddy!\u0026quot;\nVidya starts fidgeting with her keychain as this happens. Shanti (the Product Manager) lets out a muffled yawn.\n\u0026ldquo;There is an option in the library to turn off specific test cases. You could use that Gagan\u0026rdquo; said Abdul.\n\u0026ldquo;Thanks Abdul. I will try that out\u0026rdquo;\n\u0026ldquo;Can you continue with the update, Gagan\u0026rdquo; said Ram.\n\u0026ldquo;Sure Ram. So I will continue working on this issue today and I will try to close it out by EOD today\u0026rdquo;\n\u0026ldquo;Thanks Gagan. Vidya, can you give an update\u0026rdquo;\n\u0026ldquo;Sure Ram. Let me see\u0026hellip;. What was I working on?\u0026hellip; Yeah, I worked on the validation story\u0026hellip; no that was day before\u0026hellip; sorry. Yes I worked on the transformation story yesterday\u0026hellip; blah\u0026hellip; blah\u0026hellip; blah\u0026hellip; \u0026hellip;\nThis goes on for 40 minutes and at 12:10 pm, Ram asks Shanti\n\u0026ldquo;Do you have any product updates for the team Shanti?\u0026quot;\n\u0026ldquo;Nothing from me Ram.\u0026quot;\n\u0026ldquo;Great. Have a good day folks!\u0026quot;\nThis is a typical Daily Stand-up or Scrum meeting I observe in my world. I am sure many of you have experienced something similar. I want to dissect this example, but first I want to give you some historical context on Stand-ups and Daily Scrum meetings.\nOrigins The daily stand-up originated from the annals of Extreme Programming (XP). Kent Beck made this methodology famous through his book by the same name (almost). The daily stand-up was just one of the practices/rules in Extreme Programming (dig more here). Our focus is only the daily stand-up.\nLet me add some quotes from the source\nA stand up meeting every morning is used to communicate problems, solutions, and promote team focus. Everyone stands up in a circle to avoid long discussions. It is more efficient to have one short meeting that every one is required to attend than many meetings with a few developers each.\nDuring a stand up meeting developers report at least three things; what was accomplished yesterday, what will be attempted today, and what problems are causing delays. The daily stand up meeting is not another meeting to waste people\u0026rsquo;s time. It will replace many other meetings giving a net savings several times its own length \u0026hellip; Source\nI think this is a good description for us to work with.\nLet us move to the Daily Scrum meeting which comes from the Scrum methodology. Again, I am going to the source:\nThe purpose of the Daily Scrum is to inspect progress toward the Sprint Goal and adapt the Sprint Backlog as necessary, adjusting the upcoming planned work.\nThe Daily Scrum is a 15-minute event for the Developers of the Scrum Team. To reduce complexity, it is held at the same time and place every working day of the Sprint. If the Product Owner or Scrum Master are actively working on items in the Sprint Backlog, they participate as Developers.\nThe Developers can select whatever structure and techniques they want, as long as their Daily Scrum focuses on progress toward the Sprint Goal and produces an actionable plan for the next day of work. This creates focus and improves self-management.\nDaily Scrums improve communications, identify impediments, promote quick decision-making, and consequently eliminate the need for other meetings.\nThe Daily Scrum is not the only time Developers are allowed to adjust their plan. They often meet throughout the day for more detailed discussions about adapting or re-planning the rest of the Sprint’s work.\n\u0026hellip; Source\nThough these two processes have different origins, you can surely notice similarities. I will list the ones which strike me:\nThey happen on a daily basis, preferably in the morning. One of their main purpose is to eliminate other meetings. They are expected to be short (you can potentially stand through them). They are owned by Developers, allowing them to manage themselves as a team. You talk about progress made and impediments faced/facing in both cases. Goal is to work on a plan and improve focus and self-management. There could be more, but these stand out to me. Using these sources as the main reference (I will include other ideas if required), let us dissect the example DSM (of the Delta team) which I described before. I am treating the name stand-up (XP) and daily scrum meeting (DSM) as synonyms. If you see one, I mean either.\nBefore you look at my thoughts below, spend sometime dissecting the Delta stand-up and share the same in comments below.\nThe \u0026ldquo;Delta Team\u0026rdquo; DSM biopsy Disecting the Delta DSM - image by Ri Butov from Pixabay\n### The \"Good Parts\" There are good things happening in the *Delta* team stand-up. The stand-up happens at a regular daily cadence. Developers have the ability to bring up their impediments and get solutions to move things forward. There is free-flowing conversation happening between developers. There is an explicit section for the PM to chime in and add thoughts. This is not prescribed in any of the original guides, but I like this idea as long as it is kept short. They are using the common scrum dashboard to drive the meeting. This allows people to get on the same page quickly, and they have the reference to dive deeper if required. Some people are turning on video for the call and that is good thing. More about this on the other sections. I have not elaborated the above good parts because I think they are self-evident. Let us get into some not so good parts now.\nThe time The Delta team stand-up starts at 11:30 am. I am not sure if that can be called morning. That is closer to the afternoon. There could be legitimate reasons for this - people working in different time zones. Also in today\u0026rsquo;s world of flexible work timings this is probably unavoidable.\nHaving said that, if you ask me, I would prefer the stand-up to start much earlier - sometime around 9:30 am. My reason is that the stand-up is supposed to help you create an action plan for the day (this is not really planning but to get clarity). It is better to have this clarity earlier in the day, so that team members know where they have to focus on.\nOther aspect of time is the duration. 40-45 minutes of stand-up time is very high. The reason why extreme programming suggests the stand-up should be done standing up is to keep it short (it is actually not necessary for people to stand up as long as the duration is kept in mind). Similarly, the scrum guide also suggests that the DSM should be 15 minutes long.\nIn my experience, when a team gets together for the stand-up discussion, there are times when it needs a little more time (than 15 minutes). But not always. A steady 45-minute stand-up is a smell (like a code smell) to be addressed. We will look at some remedies soon after the biopsy.\nThe ownership Carefully observe (means read again if required) the DSM conducted by the Delta team, and tell me who is the owner of the meeting. I feel that the meeting is owned by Ram who is actually a manager. In scrum terms, we could probably treat him as the Scrum master.\nRam governs the flow of the conversation. Everyone is talking to him in the stand-up. This is really wrong. A practice like this converts the daily stand-up meeting into a status meeting. Once this happens, the team is just answerable to the manager. Self-management, team spirit and team ownership go out of the window. People will not enjoy going to these meetings since they are afraid that the manager will judge them. Real impediments may not get discussed. This is a very bad situation and needs remediation. The Delta team may not be in this situation yet, but they are in-route.\nAnother thing that adds to this issue is that the Delta team is fairly large. A 13 member team can be pretty crowded and intimidating especially for junior developers and new joinees. This is only a passing mention. Its implication \u0026amp; solution is beyond the scope of this article.\nThe rambling The Delta team stand-up is very ad-hoc in my opinion. Everybody seems to be talking all the time. There is no structure to the conversation. The Extreme Programming stand-up actually prescribes a structure to the conversation. The Scrum DSM is little more flexible but has essentially advocated similar kind of information to be shared - Work progress, Impediments, Plan for today etc.\nIn the Delta team stand-up, Gagan starts his conversation with mentioning an impediment. Ram draws out the context and eventually multiple others (Winston and Abdul) jump in to try to suggest a solution and this drags on leading to others getting restless. The availability of help is a good thing, but the lack of structure leads to rambling and others tuning out of it. This kind of rambling conversation is also why the stand-up stretches out for such a long time. This also leads to people tuning out of the conversation.\nAnother source of rambling is the lack of preparation of the team members when they come to the stand-up. Vidya keeps stumbling to figure out what she needs to talk about. This again leads to wastage of time. It also sends a wrong message that there is no respect for people\u0026rsquo;s time. Bad!\nWhat Goal? Another thing missing in the DSM is the absence of discussion or tracking to check team\u0026rsquo;s progress towards their Sprint goal. Typically, teams look at a burn-down chart to figure out where they are with respect to what they planned for the sprint.\nScope discussions should be related to already defined goals and if they need to be altered. In the Delta team, the priorities seem to be unclear and getting figured out in the stand-up. While this is better than not getting clarity, the ideal place for this is the Sprint planning meeting.\nRude? I am not saying that the Delta team folks are talking rudely to each other or behaving badly. But there are some subtle things to look at.\nRight at the beginning of the meeting, there was noise coming in to the stand-up meeting. Only after Ram called it out, the relevant person muted their audio to stop the disturbance. While this is not outright rude, it just tells that the team members are insensitive to others. Also, this might be a one off and if so, we could ignore it. But if this happens regularly then it means that the team is not following basic etiquette.\nAnother similar incident in the Delta stand-up is Vikas joining late. This again sets up a bad precedence for the entire team. I am not talking about being late by a few seconds or a minute.\nIn my opinion, it is better to send an offline update to the team rather than joining the stand-up after minutes of its starting.\nRemedial Ideas Now that the biopsy and diagnosis is complete, it is time for some remedial actions.\nRemedies for improving the DSM - image by Angelo Rosa from Pixabay\nTransfer Ownership to team The first thing I want to address is the aspect of ownership. While other aspects are important, this one is critical. There are a couple of things that Ram (the scrum master) can do to change the situation:\nAsk everyone to explicitly address the team instead of addressing him (the manager/ the scrum master). This might seem silly, but doing this sends a signal. The mindset created is that as a developer, \u0026ldquo;I am responsible to the whole team. We as a team own this\u0026rdquo;.\nThere is need for someone to govern the flow of the conversation. So get developers to take turns (round-robin) at playing that role. I have successfully tried this with my teams and found that it helps. Doing this helps to reinforce the feeling that we are a team and are responsible for each other. This technique also helps groom team members to act like owners and help in governance. As a side benefit, the shy developers get a chance to express themselves in a safe environment.\nA key thing to note is that ownership \u0026amp; accountability comes only if one has a say on how things go. This means that Ram shouldn\u0026rsquo;t be dictating all the decisions of any process (including stand-up). The members of the team must have a say, and they need to feel heard. Decisions have to be taken jointly. While this might be more time-consuming, decisions taken this way stick better.\nOnce these are done, ownership is no longer with Ram but with the entire team. Team is empowered to own its destiny, Ram (the manager) is just a guide in the process. This drives ownership back into the team.\nCreate a structure The second key thing to address is the rambling. We do this by providing some structure to the stand-up discussion. The team can do a couple of things:\nMake every member to stick to a common structure of providing the updates. The team could adopt the XP style or a variation of it as decided by the team. It is the job of the team as a whole (or the current week coordinator/scrum master - not the Manager) to ensure that the team members follows the structure when they provide updates.\nWhen a developer is stuck and needs help or discussion then they can announce a \u0026ldquo;Post Stand-up\u0026rdquo; discussion that is needed after stand-up. Some of you might have heard this term before; I will explain it down the line.\nEnsure that we look at where we are with respect to the Spring goal. Discuss progress using burn-down charts etc. to ensure that everyone understands where we are and where we are going.\nHow a Post Stand-up works? As part of stand-up, I mention that I worked on a particular task/story yesterday and I plan to either continue on it or pick another one today. I might have an impediment for which I need help or want a discussion to clear out some ideas. For doing this I state that I need a \u0026ldquo;Post Stand-up\u0026rdquo; discussion after everyone goes through their own updates. The stand-up is complete once updates and sprint progress discussions are complete. For the Post stand-up discussion, relevant \u0026amp; interested people can stay and others can drop off. This saves time for many developers who are not connected to the discussion. Also, the post stand-up allows the stand-up discussion to be more focused, structured and short. Since only relevant people need to be present, the post stand-up discussion itself could become more focused.\nThere can be a concern that if we create post stand-ups then the team could lose out on learnings that might come from knowing about the impediments \u0026amp; solutions. This is a valid concern, but post stand-ups don\u0026rsquo;t eliminate participation. It only makes it a choice for the person which respects their time and pressures. In my experience, I have found that this works well for teams.\nAgain, remember that the Post Stand-up is a good broad idea. You can use it, tweak it and make it your own.\nI also want to emphasize that we need the stand-up to be a place where developers can have free-flowing and open conversations. The structure is only to help the developers, but if that structure becomes a problem then we obviously need to change things up. As I said earlier, this should be done as a team.\nOnce you have a structure and start having post stand-ups, the duration of stand-up will come down (provided some of the below etiquette are followed). You can (and should) measure it so that we know how we are doing. I have done this with one of my sprint teams (after discussing with the team of course) and it helped us to look for ways to fine-tune the stand-up process. Measurement is almost always a good thing.\nGood etiquette It always pays to be well-mannered and nice to each other. It also helps to be prepared. The following list of things are simple rules which ideally developers / team members should follow. The scrum master / manager should also nudge the members when required:\nAlways join the stand-up on time. Punctuality is a good thing. Mute yourselves when you are not talking. Actively listen though Prepare for the stand-up before it starts and not when another team member is giving their updates (you need to listen at that time). This will just take 2 minutes. Show yourselves - be on video. This helps you and the team in many ways. Conclusion/Closing thought Tweaking things to make it work for you is very much in the spirit of agile. We still need to ensure that the fundamental philosophies are not compromised by our innovative techniques.\nThis ends my own observations/learnings of one of the key processes in today\u0026rsquo;s agile development world. What are you thoughts? Do you agree? Or do you think this is all b*l***t? Your comments are welcome below.\nReferences Daily Stand Up Meeting - Definition source Scrum Guide - Daily Scrum - Definition source Scrum Org: Daily Scrum discussion - A discussion on differences Daily Stand-up: Why it’s time to ditch the ‘3 questions’ - A good article on what we can focus on in standup Scrum Practices: The Daily Standup - Good set of tips to follow Daily stand-ups for agile teams - An Atlassian perspective on standups - good tips on remote standups How to detect Scrum anti-patterns? - Good write up on anti-patterns of agile itself. You can focus on DSM like me. Aum sarvam SriKrishnarpanam astu\n","date":"2023-01-14T00:00:00Z","permalink":"/daily-scrum.html","title":"The Daily Scrum/Stand-up Meeting"},{"content":" TL;DR\nWe have seen divisive politics around us for some time now. It seems this has seeped into the bureaucracy, which is more interested in posturing than doing their job. Representing Bureaucracy: Photo by © Jorge Royan / http://www.royan.com.ar / CC BY-SA 3.0\nSometime back, I heard the news of municipalities using bulldozers to raze done illegal constructions. \u0026ldquo;Illegal\u0026rdquo; is supposed to be clear term, but recently there seems to be nuances to it that I was not aware. But I let it go.\nThen I heard about policemen flogging people in public. This was really disturbing; the comparisons with Taliban did not feel misplaced.\nThen the bridge broke down killing a lot of people. That hurt. I could no longer remain quiet and decided to dig deeper. But, I couldn\u0026rsquo;t get to it immediately. But better late than never.\nDismantling Bulldozer These events happened long time back, but the internet always has the answer. You still have to know where to look. ThePrint has been one of the publications that I have been following for a long time and I trust them. So I decided to try there first (references at the end). I had heard about these bulldozer events in their podcast, but the context had slipped away.\nThe Bulldozer culture seems to have started in UP where the CM Yogi used it as a tool to bring law and order changes. He eliminated powerful criminals doing this and was rewarded by the people by getting re-elected. That seems to have started the trend.\nOther BJP state CMs took notice. Now, we come to the part where the problem starts. Multiple incidents seem to be reported in Madhya Pradesh, where the CM used the Bulldozer to penalize criminal activity or rioting. There is no law to do this, and the excuse given seems to be demolition of encroachments. As per the law (which varies from state to state), the minimum requirement is that the evicted person must be given notice. ThePrint says that this was not the case.\nOther BJP managed states followed suit and the trend seemed to be clear. The Bulldozer acting on \u0026ldquo;illegal construction\u0026rdquo; is going to be the tool of choice to \u0026ldquo;discipline\u0026rdquo; certain sects of people. At least that is the feeling I got after reading these articles.\nBut let me step back. May be, I am biased in saying the above statement. One thing is clear. The municipality (bureaucracy) demolition of illegal construction for any reason, without giving notice, is a breach of their contract with the people. Something is out of whack.\nPublic Flogging The flogging incident had a left a bad taste in me from the time it happened. The place it happened was Gujarat - Ground 0. I again dug through articles on ThePrint and this is what I gathered.\nThe Sarpanch of the village had promised to conduct a Garba for the people, and he decided to fulfill the promise. The location was close to a mosque and the folks from the mosque asked to ensure that the Garba shouldn\u0026rsquo;t disturb their Id preparations. The Garba happened. It is not clear how much of a disturbance it was, but there was some stone pelting. The police caught some people who were alleged to have done this. At this point, it seems that this was a regrettable incident.\nBut then it turned into a catastrophe.\nThe policemen (couple of people) took 3 of the alleged muslim youth and flogged then in public to the cheers of surrounding public. The Sarpanch was also egging them on. The \u0026ldquo;people egging on\u0026rdquo; makes me feel sick, but the police flogging citizens of India is down right heinous. In movies, I have seen police brutality, but those are shown to be done in the confines of the cell or lockup. Here we are talking about creating a public spectacle. This is gross misuse of power and completely unconstitutional.\nThe overarching signal I got was that government officials wanted to make a name for themselves in the context of religious extremism. Instead of doing their job of controlling crime, they were committing crime in the open, to earn brownie points from the majority population or their powerful leaders.\nWhile Shekhar Gupta in his article laments about the lack of political voice to call out this atrocity, my worry is that the bureaucracy is not just corrupt now (which I think it was to a good extent). They have become bigoted and vain in the context of religion \u0026amp; minorities. There is a commission ordered for probe, but I don\u0026rsquo;t think there has been any real action taken. This makes me feel that the norm is changing. I am worried.\nBroken Bridge The reports on the bridge collapse were heart-wrenching. I have included some reports below which are really disturbing. The failures were at multiple levels.\nThe maintenance contract of the bridge was given to a watch company. I really can\u0026rsquo;t understand the sensibility in it. When the bridge was opened after maintenance, there was no checking or certification done by the Municipality. The crowd control on the bridge was not done properly. Many of the victims complain about delay in providing rescue. This shows corruption and lack of any responsibility by the authorities at multiple levels. It looks like the municipal authorities were \u0026ldquo;busy\u0026rdquo; doing other things. I am not aware of what these are, but I have to wonder.\nWhat do I make of this? I have related 3 different incidents happening in a chronological timeline. While these are disconnected incidents, there are a few thin strands. All have the bureaucracy involved it in some way. These incidents show corruption in the system (which has been there for long), but they don\u0026rsquo;t stop there. I feel there is some kind of posture change involved here. There seems to be misuse of power to target certain sections of society based on \u0026ldquo;specific criteria\u0026rdquo; instead of the earlier universal application of corruption. I am extremely worried about this.\nThe Bureaucracy seems to think it is important to send the right signals to specific communities instead of ensuring that real work gets done, and the safety of people is ensured. I hope I am wrong, but the smoke does exist. If you think I am wrong, I would love to hear about it.\nReferences Dismantling Bulldozer\nThePrint: Bulldozers go after ‘illegal encroachments’ from MP to Delhi, but the law requires a notice ThePrint: Big hit with BJP, bulldozers now rolling in Gujarat \u0026amp; Uttarakhand, coming soon to Karnataka ThePrint: Bulldozers in Shaheen Bagh, but no demolition: How residents averted ‘law-and-order situation’ Wikipedia: Bulldozer politics TheWire: The Bulldozer Is Reshaping Our Cities and Our Imaginations Public Flogging\nThePrint: Gujarat police chief orders probe into Kheda flogging incident; outfit sends legal notices to DGP, govt ThePrint: New sarpanch vowed to start garba in village, sparked clashes, Undhela’s Muslim residents say ThePrint: Gujarat flogging: Muslim villager’s affidavit blames Kheda DSP, BJP MLA, Undhela sarpanch Press mute for Indian Muslims — how Gujarat flogging shows up ‘secular’ silence of Indian politics Broken Bridge\nThePrint: The ‘ruckus’ that led to Gujarat’s Morbi bridge collapse \u0026amp; the challenges facing rescue teams ThePrint: ‘Kept calling but nobody came’: Morbi bridge survivors’ stories of terror \u0026amp; abandonment ThePrint: Morbi bridge dents not just the Gujarat model. It’s an infrastructure hole India can’t unsee Morbi bridge collapse incident highlights cronyism perpetuated in Gujarat, says Cong SC terms Morbi bridge collapse as an ‘enormous tragedy, asks Gujarat HC to periodically monitor probe Gujarat Bridge Collapse: “It was heart wrenching…” eyewitness recount Morbi horror Aum sarvam SriKrishnarpanam astu\n","date":"2023-01-14T00:00:00Z","permalink":"/flogging-bulldozer.html","title":"The flogging bulldozer which broke the bridge"},{"content":" TL;DR\nMinimalism is a journey that can make life about living more by having less, and making it sustainable for everyone. Thanks to Leo Babauta for starting me on the path. Minimalism as a concept has intrigued me for a long time. I bought a book, but did not read it. Then I watched a video on Netflix, and it was nice, but the concepts did not stick in my mind for long. Then I came across a book by Leo Babauta - The Simple Guide to Minimalist Life. I had read his blog before and found his writing interesting. Hence, I decided this was an opportunity for me to wet my toes into this world.\nI read through the book, and there were several ideas and tips that I loved. So what is the next step. Writing about it is a good way for me to internalize some key ideas in it. Practising some of these ideas and sharing my experience with others, and getting thoughts and feedback would make things better. So here we are.\nThis is not a review of the book - I am not a reviewer at any level. This is just a post written to learn and appreciate some aspects of the book which appealed to me and some of the learning I got when trying to follow some of these ideas.\nThe Mental Picture A minimalist instead embraces the beauty of less, the aesthetic of sparseness, a life of contentedness in what we need and what makes us truly happy.\nMinimalist room: Photo by Alexandru Acea on Unsplash\nThat quote describes a person I would aspire to be. It appeals to the romantic part of my mind. The line also makes me introspect. What makes me truly happy? It is a hard question to answer but a good one to reflect on. There is a lot of work to do, but I have gotten started. 👇\nMy current work desk at home- I hope that is not too bad - except the wires!\nThings I own - my focus for now Leo covers a couple of aspects of minimalism in the book. One is about the things you own, and the other is about what you do. In this post, I am focusing on the \u0026ldquo;owning things\u0026rdquo; area. I will probably cover the other big piece in a different post.\nThings I own - Right Thinking \u0026amp; My Problems The key idea to think and internalize in this space is Contentment.\nI have enough!\nActualizing this idea is tougher than it looks. Let me talk about myself. I am pretty contented with what I have for the most part. I have a house to live in (though I live elsewhere); have a small car which I drive with my family. There is a reasonable amount of furniture, and I am not aspiring for anything fancy. I think I live well. There are small items which could be added (couple of good chairs wouldn\u0026rsquo;t go amiss), but it is not urgent. But there are gray areas where I falter, and I will discuss them down the line.\nOne related idea which Leo talks here is the ability to differentiate between needs vs. wants. I confuse the two, not because I can\u0026rsquo;t identify the difference, but because there is some greed in me, which pops out when I am not cognizant of it. For practicing contentment, this ability to differentiate needs from wants needs to be high at all times. That does not happen, and I get carried away and make mistakes. Especially in those gray areas. Let us get to them.\nThere are two areas where I am very bad at following the rule of contentment . One is books. Whenever I come across a book, I have the itch to own the book. I don\u0026rsquo;t literally mean every book, but any book which is even remotely interesting piques my interest. It starts with the thought that I would like to read them. Now, I cannot read them all because there is only so much time, so I decide to buy them for reading later. To sum it up, I hoard books.\nThe other gray area is gadgets \u0026amp; their accessories. I buy gadgets because I like them. But that is not all. I buy them because I want a backup in case things break. My fear of things breaking is my excuse for buying more. You would say that \u0026ldquo;I could live without it for sometime till I get a replacement\u0026rdquo;, and you would be right. But my stupid mind thinks differently.\nThe other problematic thought is about not wanting to spend a lot of money on these and ending up buying multiple cheap gadgets. This leads to clutter. Leo mentions that \u0026ldquo;A minimalist values quality, not quantity, in all forms\u0026rdquo;. So my cheap gadget mentality does not help here. I am trying to change this, but it will take time. There is a whole other rant on quality which I want to get into, but now is not the time.\nMy set of bluetooth headsets\nOn the subject of gadgets, I have another related idiosyncrasy. I keep broken gadgets. Many times it is because I don\u0026rsquo;t spend time checking for broken things. Other times, I have checked it, but I can\u0026rsquo;t let go of it. An example is the green one in the above picture.\nI probably have other shortcomings in this space and in my thinking. But these are at the top of my mind. Next let us move from thinking to actions.\nThings I own: The actions I took or can take Garbage overwhelms us and hence we need to take some action. Leo suggests first decluttering to reduce stuff, and then talks about how to maintain the rest.\nDecluttering For decluttering my setup at home or work, I need to do 2 things\n1. Identify the essential.\n2. Omit needless things\nFor doing this, contentment needs to take center-stage in our minds. We already discussed contentment (keeping it DRY!) and I know I have work to do there.\nWhen we practically sit down to do this process of decluttering, we invariably will have some concerns. Leo calls it fears, and he lists them out:\n1. Fear of needing it again I have faced this fear whenever I have sat down to weed out things. Let me take an example: There is an HDMI port to HDMI port connector which I had used at some point for connecting my laptop to TV. I don\u0026rsquo;t use it anymore, but it is still lying around. I could actually get rid of it, but I have the fear of needing it again.\nOne rule of thumb which Leo suggests here is to check if you have used it in the last 6 months. If you have not used it then you can throw it away. I could follow this rule and potentially throw it away. But if my fear persists then there is the next technique - \u0026ldquo;The maybe box\u0026rdquo;.\nThe may be box is a place or container where you keep things which you may need at some point and are not willing to throw away. Ideally this is kept in a place which is away from your normal living area - the attic. I did use this hack, but there is a demerit here - I have not truly decluttered my life, but have just hidden it. Unless I have a regular cleaning routine I will soon have an overflowing attic!\nPart of my attic\nTo counter this risk, I do allocate time for attic cleaning, but I have to set up a monthly schedule to make it consistent.\nLet us get to the next fear.\n2. Reluctance to waste something valuable\nI felt that this was a valid fear, in the beginning. My grandmother used to quote the below line to me in Tamil - சிறு துரும்பும் பல் குத்த உதவும் . It literally means, even a small piece might be useful as toothpick. So theoretically it is valid concern. But something else happens in practice.\nWe see something which is useful and keep it stored somewhere. It sits there collecting dust, eventually starts degrading and loses its value (stops working). While it may not be a good idea to throw a useful thing, it might be better to give it to somebody who can use it. But my childhood conditioning makes it very difficult for me to follow this. There are cases where I have practised this, but it is not always possible. One problem in practising the giving away part is that you don\u0026rsquo;t find any suitable recipient for the same. In such cases I keep it around, only to find later that the item stopped working, hence no longer useful, and can only be thrown away. This is why this fear needs to be overcome.\nLet us move to the last fear stated by Leo.\n3. Not wanting to let go of sentimental things, because of emotional connection\nI am not a very sentimental person, but there are occasions where I start seeing connection in things. It is primarily nostalgia. I still hang on to my eating plate even though it is a bit banged up because it was something which my father used.\nThe plate I use to eat my food - broken in places and bent in others\nAs you can see the plate is very basic, but it is still usable. I don\u0026rsquo;t have another plate to use and that is by design. At some point the plate might become unusable, and I have to figure out a way to let it go. Leo has a good idea for this. He says that we could take a photo for remembrance’s sake and then let go of the thing. I guess it could work. I may never look at the photo again, but at the moment when I have to part with the thing, it might offer me some kind of solace that I can look at its image later on. You could try it out and let me know if it works for you.\nKeeping things well Now that we have identified the essential and omitted the unnecessary things, what is the next step in the process of becoming a minimalist in terms of owning things.\nThe key idea which Leo mentions is to \u0026ldquo;find a place for everything you need\u0026rdquo;. This is pretty good, but I feel the process has 3 steps:\nDetermine the things you need (only): This was covered in the previous section (decluttering), but I am reiterating it here because if you have not done this then the next step does not work. Find a place for keeping those items: This is what Leo said (mentioned earlier), and it is a pretty clear. There is a controversial statement which Leo makes in this context - \u0026ldquo;Minimalising is the end of organizing\u0026rdquo;. The act of finding a place to keep the things you need feels like organizing to me. Having said that the actual work does not stop there. Have the discipline to keep the items in its place all the time: For me this is a vital step if not the vital step. If I am not disciplined to do this, then the previous steps don\u0026rsquo;t matter. I will pretty much be living in a cluttered place. Clearly Minimalism needs discipline and that is something we cannot forget. There is one tip I want to throw in the context of the decluttering process based on my experience. Whenever I embarked on this process, if I had good energy levels and a stable emotional state, I made better choices on keeping only things that are really necessary and throwing the rest. The decluttering process involves decision-making and if you are not in the right state, you will slow this process down to make it laborious and useless.\nSustainability One of the key themes which Leo talks prominently as a benefit of minimalism is \u0026ldquo;Sustainability\u0026rdquo;. The world is stretched to its limits by the acts of humans like me. We really consume a lot of the resources available in the world. I don\u0026rsquo;t have numbers to quote, but my own life progression tells me that I am using a lot of resources.\nLeo says \u0026ldquo;Step lightly upon this world\u0026rdquo; and I think it is a mantra for me to remember and follow:\nSustainability: Photo by Noah Buscher on Unsplash\nCreating macro changes to improve sustainability is difficult for me to do, but I can perform actions at my level. I can live with less. I have small house and a small car, but I can probably do better by reducing the other stuff I use. While there is the idea of using better materials (more earth friendly), I think there is an easier argument for using less.\nAs part of his actions to take, Leo says, \u0026ldquo;Make everything count\u0026rdquo;. Making everything which I have chosen to use, must be used well without wastage. And what is not useful should be given away so that somebody else who needs it could use it. This can also help with improving sustainability in the world.\nClosing thoughts The best idea which Leo talks about in the book repeatedly is this:\nEdit, edit. Minimalism isn\u0026rsquo;t an end point. It\u0026rsquo;s a constant process of editing, revisiting, editing some more.\nEditing life: Photo by Suzy Hazelwood\nThe clear point conveyed here is that Minimalism is a journey. I need to start somewhere and keep going. Things may not be perfect in the beginning (and it probably will never be), but as I progress, I can keep editing and refining the process to improve myself and the surrounding lives. It is a process of continuous improvement. The key ingredient needed to make this happen is self-discipline.\nI have started a routine of regularly decluttering my areas in the house. I have also found good places for the things I use. Now I need the discipline to make it stick.\nI will write more about minimalism in terms of what I do at some point. In the meantime I want to listen to your thoughts on minimalism. Do you think the idea has any legs to stand? Are you already following it and if so what has been your experience? Please share as it will help me in my journey.\n","date":"2022-09-07T00:00:00Z","permalink":"/minimal-first-brushstroke.html","title":"Minimalism - My first brushstroke"},{"content":" TL;DR\nThere is no simple formula to figure out the right size of a microservice. There are different considerations, which affect size in different ways. This is illustrated in Fig 4 and 5. These figures provide you a bird\u0026rsquo;s eye view on the considerations you have to keep in mind. Origin Note\nI had given a session to my engineering team at Simpl on this topic as part of our Bi-Weekly Tech talks. Decided to create a blog post out of it since I (and others) can refer to it later. I have been working with microservices for some time. There is one question that keeps coming back when I work with them or discuss them with people. How small or big a microservice needs to be? The below blog post is my attempt to explain (\u0026amp; understand) the concepts around this \u0026amp; express my opinions/inferences along with it.\nAt the outset, I need to establish some context about microservices. A very short journey into history \u0026amp; a foray into the realm of definitions will help us understand the core topic better.\nBefore microservices there was\u0026hellip; Microservices have been around for some time now, but they are relatively nascent compared to these older fellows which I am going to describe now.\nAt the beginning of time there was Client Server architecture! Ok, that is not the truth, I have only gone back a few decades here. There were other architecture styles before, but they are not relevant to our conversation. Also, I am not explaining the entire computing history. The two relevant architecture styles are listed below:\nN-tier architecture (client/server?) Service Oriented architecture Let us dig a little deeper.\nN-tier Architecture This architecture started off as the basic client server architecture which is two tiers. It was just a thick client which talked to a server typically for data storage. This obviously had some problems \u0026amp; hence things evolved. Cutting things short, we get to the final (or at least prevalent) incarnation of this architecture: the 3 tier architecture.\nThe tiers in a 3 tier architecture are:\nA thin client, like the browser A thick middle tier server component, which held all the business logic A data store, which held all the data. Fig 1: N(3) Tier Architecture\nI am sure this is familiar to all of you as it is a valid architecture style even today. Monoliths were/are basically 3 tier applications in all their pomp \u0026amp; glory (and extra cheese!). Actually, many of the microservices today follow the same architecture.\nThe 3 tier architecture was embraced wholeheartedly by the software community. Advanced middle tier components called application servers got built with tonnes of features, to make it easy for developers to deploy 3 tier applications. This lead to creation of highly capable applications which can deliver a lot of useful functionality to multiple thin clients.\nLo \u0026amp; Behold! The Monolith was born!\nService Oriented Architecture I think this architecture\u0026rsquo;s inception happened like this (purely a figment of my imagination) :\nSoftware people always want to reuse code \u0026amp; leverage functionality in other existing applications without having to change them much (so use them remotely). Software people always like to componentize things. These folks come across XML \u0026amp; figured out that this language can be used to represent any piece of data \u0026amp; can be read by any tech (Side note: there was a platform war going on at that time in tech history just like now there is cloud war going on). Then they put all these together \u0026amp; SOA was born. I am just making this up and hence will be missing a lot of details (the individual aspects mentioned here are true but the story itself is fictional).\nOne key thing I did not specify yet are the Service Design principles which are very important (according to me). So let us focus on them:\nStandard contract \u0026amp; Service abstraction Service autonomy (implementation \u0026amp; location) Service discoverability Service statelessness Service composability Service reusability If you look at these principles, they all make sense even today. Don\u0026rsquo;t they? I would even wager that they make even more sense today. Especially in the context of microservices.\nFig 2: Service Oriented Architecture\nWhile the SOA principles were (/are) very strong, the real world implementations got ugly soon. Given the enterprise focus of SOA, things changed for the worse. Enterprises already had a lot of software applications lying around \u0026amp; working in silos. Software Vendors took the SOA\u0026rsquo;s promise of reusability \u0026amp; interoperability \u0026amp; created all sorts of products (read ESB 😖) which were supposed to help these enterprises to leverage these siloed apps. This did not go as planned since such a transformation requires a lot of fundamental change in how these enterprises work, which mere tools can\u0026rsquo;t make happen. Enterprises made a lot of upfront investment on these vendor products expecting them to do some kind of magic. Of course, they did not get much out of it in the timeline they wanted it on. Not only that, these products became single point of failures (both from a dev \u0026amp; runtime perspective).\nApart from the above progression, there was one more issue. To solve a wide range of problems in these products \u0026amp; in general within SOA, many standards were evolved (WS*). While this effort was admirable, it did not sit well with developers since it meant a lot of complex artifacts added, which felt like boilerplate since they did not add visible value.\nAll said and done, I don\u0026rsquo;t think SOA is dead. It has just morphed to what is called microservices now (my opinion).\nWhy microservices (instead of monolith) I am not going to explain the microservice architecture since in today\u0026rsquo;s world everyone has a pretty good idea about it. Instead, I am going to explore the reasons why microservices are preferred over monoliths. I get into this, because these attributes come into play when we eventually want to figure out the right size of a microservice. Remember when a microservice gets too big, it becomes a monolith. (When it gets too small then it becomes a nano/pico service).\nThere are some well known reasons for preferring microservices:\n1. Independent Deployment Microservices are fantastic because they allow for independent deployment of specific changes. When a feature requires localized changes on a particular module (or code path), a microservice (which represents that module) will allow us to deploy that part alone (by deploying the microservice) instead of deploying the entire functionality (app) which is required in case of a monolith. This plays out in many business scenarios.\nThis is a pretty crucial aspect of a microservice. If this is not realized then the point of having microservices is lost.\n2. Freedom of tech choices Given that microservices focus on a smaller cohesive footprint, they allow for more flexibility in tech choices. As they say, you can use the right tool for the job!\n3. Easy replaceability The ability to take a microservice out \u0026amp; replace it with a new one, in a relatively short amount of time, is cool. This is of course not possible with a monolith. This is another key aspect of a microservice. It allows us product developers to make mistakes \u0026amp; correct them.\nHaving said that, in the real world, we forget this \u0026amp; expect that everything works perfectly, the first time. Rewriting or replacing is always considered as an unacceptable thing. This defeats one of the great benefits of microservices - the ability to make a mistake \u0026amp; learn from it.\n4. Shorter time to market Microservices allow for a focused approach. Whenever the business wants to create a new feature, the focus of the corresponding team \u0026amp; its microservice(s) allows them to independently build out the feature \u0026amp; release it. This means that we are faster to market.\n5. Independent scaling In my experience, this is the favorite reason people think about \u0026amp; give others, when wanting to create microservices. Scaling is a problem everybody wants to have \u0026amp; solve. The microservice architecture\u0026rsquo;s capability of making this happen is the most important reason for everyone to flock to this architecture style.\nMany times this solution leads people down the path of very small services (nano/pico services) which may not really solve the actual scalability problem. That said, no one can refute that microservice architecture when applied correctly can provide you ways to independently scale different parts of the bigger system, and that, is surely an advantage.\nNow that the obvious ones are done, there are some advantages of microservices which are important but not appreciated as much:\n1. Organized around Business Capabilities The premise of a microservice is that it is organized around business capabilities. For example, you might create a microservice for payment management (\u0026lsquo;Payments\u0026rsquo;) \u0026amp; another for order management (\u0026lsquo;Orders\u0026rsquo;). Each of these are distinct business capabilities and have different concerns, interactions \u0026amp; business focus. This type of organization leads microservices to evolve independently based on what a particular business team (domain experts) wants to do in that specific area.\nFor example, if we want to use a different payment gateway because it provides better success rates, it is the \u0026lsquo;Payments\u0026rsquo; microservice which will work \u0026amp; evolve this feature. The \u0026lsquo;Orders\u0026rsquo; microservice does not bother about this.\nAlso, by doing this there is easier alignment of engineering teams with business goals, and it helps the team to build domain specific knowledge, which can help in making quicker \u0026amp; better decisions during development.\nSome earlier mentioned benefits like shorter time to market, independent deployment etc. work because of this aspect of microservices.\n2. Strong Interfaces Once you go down the path of microservices, we would have split a large app into smaller services. The interactions between them need to happen remotely through an interface. This interface has to be clearly defined, is generally coarse grained, and all interactions happen only through it.\nWhile we don\u0026rsquo;t want too many such interactions happening for fulfilling a single user action, when these calls do happen, they happen in a well-defined \u0026amp; clear manner. This reduces coupling between systems. Also, with proper microservices we reduce the creeping up of multiple concepts within a single service which removes cognitive overload.\nIn summary, two different microservices or sub-systems always talk to each other through strong well-defined interfaces. This leads to a lot of good things in the life of developers of both systems.\n3. Decentralized governance We already covered the fact that there is freedom of choice in terms of technologies used when we use microservices. That is part of governance, but that is not all of it. With microservices, individual microservice teams can even choose different processes \u0026amp; tools to run their development.\nWhile, there needs to be a set of guidelines \u0026amp; some basic oversight to ensure that the fruit does not fall too far away from the tree, the need to govern everything through committee is reduced. This means that the dimensions of freedom for teams are much higher, leading to a more agile engineering organization.\nWhat does “micro” mean? Now that we have covered why microservices, let us move back towards the question of this write-up. What does \u0026ldquo;micro\u0026rdquo; mean in a microservice? What is the right size of a microservice?\nThe rest of the blog post is about answering that in detail. But to start off, I thought that I could briefly cover some points which people say about size of microservices. I am mentioning the extreme ones here because that has been my experience. More reasonable ideas on the right size of microservices will be presented down the line.\n200 Lines of Code 😖 One of the metrics people use to talk about microservice size is lines of code. There are claims that microservices should be only 200 lines. There are others who say it can be 500 or 1000 lines. These absolute values don\u0026rsquo;t make sense to me, because lines of code can vary a lot depending on the language platform \u0026amp; the frameworks used in development. If I am building something using say, the RoR stack, a few lines of code would be enough to create a complete CRUD app. If I use direct Golang or C to build the same app the line of code required might be order of magnitude higher. So defining microservice size using lines of code count does not make sense to me.\nA person per service 😕 Another famous one I have heard about the right size of a microservice is that it can be managed by a single person for the most part. This again does not make a lot of sense to me. Microservices are supposed to represent business functions. Typically, in any normal business function (unless you are very small startup), the processes followed are involved \u0026amp; are typically managed by multiple people. One developer catering to all these needs does not sound feasible to me.\nAn endpoint per service 😩 The third kind of logic I have heard is to split things up in such a way that a service only serves one endpoint. The argument is that one can scale this independently \u0026amp; hence it gives us a lot of advantage.\nFor me this setup does not make sense most of the time. If there is a business domain that only serves one API endpoint, I would be very surprised. There are potential niche domains for which this might happen. Even so, one API endpoint is cutting it too small. In my experience, I have never seen such a domain \u0026amp; I would love to hear from others if such domains exist.\nThere are other ideas of splitting the same domain into multiple services (since the domain needs more than one endpoint). This is a valid idea but when I probe deeper with these advocates, I find them expressing the idea of sharing a data store (database) across all these services. Once that happens, I find it difficult to stay with them. Sharing a data store breaks one of the fundamental principles of microservices - autonomy. That is not acceptable to me. So I walk away from the idea.\nNone of these ideas on the right size of microservices are good according to me (making it explicit in case my subtle hints were not clear enough), though I have heard them often. Now I will start describing some better ideas to figure out the right size of a microservice. But before I do that ( not again! ), I want to take an important digression. This digression is about Domain driven design, and to me, it is one of the vital ideas in the area of microservices.\nDomain driven design Domain driven design is a methodology or approach of developing software that focuses on a creating a software based model of the actual domain it is representing, thereby making the software model rich in concepts, processes \u0026amp; rules of the domain. It all started with a book created by Eric Evans.\nFig 3: Domain Driven Design by Eric Evans: Model Integrity Patterns\nThis book focused on a bunch of concepts which I will describe very briefly in this write-up. I am touching this area of study because I think it is relevant to our topic - microservice \u0026amp; it\u0026rsquo;s right size. A detailed description is just not possible in this post. Given that more than one books have been written on the topic, there are multiple articles, courses etc. (and also communities), I will ask you to dive into one (or more) of them. May be down the line I will attempt to write something about it . Let us move to the crash course on the subject:\nBounded Contexts One of the key ideas in domain driven design (DDD) is to organize large systems according to their business domains. As soon as I say this, I am sure you would realize that this is fantastic in the context of microservices. Microservices are also organized around business capabilities, so this seems like a good match to start with.\nWithin the context of a business area, we can define a domain model that makes sense within that context. Outside that context these domain concepts generally don\u0026rsquo;t make clear sense. Or at least they make different sense in different contexts. This boundary is defined as a \u0026ldquo;Bounded Context\u0026rdquo; \u0026amp; it is focused on a single domain. If you think a little, this idea is the foundation of microservices. A bounded context can be built using one or more microservices.\nUbiquitous Language The next important concept of DDD is called the Ubiquitous Language. As the name suggests this means a language that is used across teams and disciplines - ubiquitous. It is a common language for developers \u0026amp; domain experts and is used to express business concepts \u0026amp; rules of the domain. The same language is also used to express concepts/rules in the software domain model. Let me reiterate: The idea is that software uses the terminology present in the business domain \u0026amp; makes it easy for business experts to understand the software as well.\nThis one does not contribute too much to the microservice architecture discussion, but I mentioned here because it is of fundamental importance in DDD. Context maps Any given business organization or super system is made up of multiple bounded contexts. There needs to be a way to describe how interactions between different bounded contexts happen. In the context of DDD, this interaction is expressed as Context maps. Context maps are very powerful to understand the business systems. It can also be very handy in figuring out our microservices. A context map could help us understand how our microservices work together, how they interact, their communication patterns, build and runtime dependencies etc.\nAggregates There is one more important idea in DDD that I need to discuss here: \u0026ldquo;Aggregate\u0026rdquo;. This is one of the tactical design patterns presented in the DDD book. An aggregate represents a composite domain object which can contain one or more \u0026ldquo;entities\u0026rdquo; or \u0026ldquo;value objects\u0026rdquo; (these are other tactical patterns in DDD which I won\u0026rsquo;t cover) \u0026amp; ensures that invariants across these composed objects are kept intact. It also represents a consistency boundary.\nAn example could be an \u0026lsquo;Order\u0026rsquo; \u0026amp; its \u0026lsquo;LineItems\u0026rsquo;. One of the rules/invariants could be the value of the order should be equal to sum of the values of its line items.\nThese are some key ideas of DDD \u0026amp; I have described them only as much as I require for explaining how they affect microservices \u0026amp; their size. There is a lot more to dig deeper in this area \u0026amp; I will provide references for the same, later in this write-up.\nWhat is the right microservice size? - Considerations Now that we are done with all the ceremony, we can get into the main discussion. Though I call it ceremony, I think the previous sections are relevant \u0026amp; will make this section much simpler to explain \u0026amp; understand. The following are the ideas, which we have to keep in mind when we think about the size of a microservice - how micro is micro?\nBounded Contexts I covered bounded contexts in the earlier section. As I mentioned there, a microservice can contain a maximum of one bounded context. A bounded context represents a business domain \u0026amp; hence having a microservice representing more than one business domain defeats the main purpose of microservices - independence \u0026amp; autonomy. If two bounded contexts are present within a single microservice and one business team focused on a particular context wants changes on their aspects, then that will need to be synced with the needs of the other team \u0026amp; their bounded context. While keeping separate microservices does not guarantee that different business teams can work independently all the time, it takes it towards the best possible outcome.\nTransaction Boundaries \u0026amp; Consistency While the bounded context acts as a force on the upper bound of size for a microservice, the need to ensure that transactions work properly \u0026amp; data consistency is maintained in a given use case acts as a force on the lower bound.\nThere was a time when Java EE world thought they solved distributed transactions with 2 phase commit \u0026amp; everyone should be happy. But everyone was not happy. Scalability challenges \u0026amp; complexity of the architecture did not help the cause. Also, the solution of platform specific and everyone did not want to move to the Java EE stack for their own valid reasons.\nAs of today distributed transactions are not a solved problem at a tech level (there are patterns like Saga which help, but they add to the complexity). So if we want a user interaction to be properly managed as a transaction \u0026amp; consistency to be maintained for the data, then that interaction must not span microservices. It should begin \u0026amp; end within one microservice. If that does not happen then data consistency \u0026amp; good user experience cannot be guaranteed. Somehow in today\u0026rsquo;s world these things have become important! So this is a criterion to keep in mind to keep the service big enough.\nThe concept of an aggregate plays well in this aspect. Since an aggregate is a consistency boundary, a microservice that contains at least one entire aggregate and no partial aggregates, can meet this criterion. If an aggregate is split up into two microservices then it can cause havoc. So aggregate size acts as a lower bound to the size of a microservice.\nInfrastructure Aspects A new microservice typically needs a set of infrastructure components. There are the basic compute, memory \u0026amp; network needs and things generally don\u0026rsquo;t stop there. Most of these microservices will need other elements like databases \u0026amp; caches, and those need to be considered as part of infrastructure needs. And it does not stop here.\nIf you are going to develop \u0026amp; run a microservice, then a team needs to work on it. It needs to build, test \u0026amp; work with it. This means more infra needed for various environments like development, staging, testing etc. Keeping this in mind, creation of tiny microservices means adding to overhead in terms of infra needs. Our IT or Devops team may not be happy about it.\nHaving said all this, the current cloud based world (with spot instances \u0026amp; server-less infrastructure) makes this somewhat easier to manage or handle. But I still think it involves significant work \u0026amp; hence cannot be treated as a non-reason when it comes to creating microservices \u0026amp; their corresponding small size.\nSo before you think that I will split up the service to make it smaller keep the infra requirement in mind.\nIteration speed \u0026amp; Agility One of the key purposes of creating microservices in an organization is to be able to improve its agility \u0026amp; iteration speed. An ideal microservice, which focuses on a specific business function, allows that function to quickly add new changes that can be shipped to customers to get quick feedback. This ability to ship a product/feature \u0026amp; get quick feedback is the hallmark of agility. This increased iteration speed is what allows organizations to keep ahead of their competition. The microservice architecture\u0026rsquo;s key benefit is to allow this to happen.\nIn terms of \u0026lsquo;right-sizing\u0026rsquo; the microservice, this is another guiding principle. If the microservice size still allows our team to deliver in an agile manner then we are safe with its size. If it is slowing things down then it is potentially time to look at making changes to the size of the service (either split them or combine them). This consideration is slightly indirect but if we track our agile processes properly then this can be an eye-opener to determine microservice size.\nCouple of opposing forces to note in this context:\nTypically, when services grow big, testing all the scenarios takes more time. So testing time increases with the size and hence it pushes services down to make them smaller. If a feature change needs developers to work with multiple services (within the same team) to release it, then overall development time increases. Developers have to work with all the services individually, test against their contracts (with \u0026amp; without mocks/stubs), deploy in different environments in a co-ordinated manner and also ensure distributed communication scenarios are handled. So if we want development time to be reduced within a context of business team it might be better to have a bigger service that caters to that business function fully. Team Size (Two Pizzas team) This criterion speaks a lot to engineering managers. Every manager wants to have a clear idea on the right (or good) team size for managing a microservice. The accepted intelligence out there is that a microservice team has as many members as can be fed by \u0026ldquo;two pizzas\u0026rdquo;. This means a size of around 6 - 10 members (few indicate that it can be up to 12 members). The original quote of \u0026ldquo;Pizza teams\u0026rdquo; came from Jeff Bezos.\nFrom an agile team perspective, who constitutes a team? Is it the set of developers in the team? What about testers? What about engineering managers \u0026amp; product owners? In the literature out there, this aspect is not clear. So I am going to wing this part, based on my experience \u0026amp; intuition.\nFor me, an agile team which takes care of a business focus area or a domain should be the set of people who interact \u0026amp; communicate about it on a daily basis. Developers, testers \u0026amp; product owner(s), all form part of that team. Developers are focused in creating the feature, the testers are focused on ensuring quality of the feature \u0026amp; the product owner is the one responsible for envisioning the feature (I say \u0026lsquo;responsible\u0026rsquo; to differentiate the fact that she does not have to be the only person doing the thinking, but she takes charge of the process). These members focus on the service/business area day in \u0026amp; day out. Another important criteria of an agile team is that they are self-managed.\nIf these two criteria are met, then those are the team members that manage the bounded context \u0026amp; they can be as big as 6 - 10 members. Let me summarize the types of people in the team so far (they are just in alphabetical order):\nDevelopers Product Owner(s) Testers You might ask: What about the engineering manager? If the engineering manager is solely focused on the team \u0026amp; contributing to the teams work on a regular basis then they could also be considered in the 10 member gang. But if they have a broader focus \u0026amp; are indirectly involved with the team and engage at higher level, then I would consider them to be sitting outside the 10 member team. Similar approach can be applied to members from Devops, Security etc.\nBack to the microservice size question. This agile team is focused on a bounded context/domain \u0026amp; hence need to manage one or more services within itself. It is ok for the team to manage just one service which takes care of all of business functions. Or the team might decide that it needs to manage it using 2 - 4 services. Either way, things work.\nWhat does NOT work is this: For managing this domain specific service, if we start needing a team bigger than 10 people, then it may be time to split things up. This splitting up is not just about the service. If I need a team bigger than 10 people to manage a business subdomain then it means that the domain is more nuanced and/or broad. So the business needs to look at how to split the business function up to provide better focus on each of these parts. This part is purely my own opinion \u0026amp; hence subject to disagreement. I am ok with that.\nThe one thing we should not forget from this section is that team size acts as an upper limit determinant of microservice size and pushes it down.\nModularization The concept of modularization is well known to a lot of us. We want modularization because it helps us to understand things easily \u0026amp; reuse things. Also, modules operate with each other through contracts, and contracts are always a good thing. Creating small modules to make a big system is not a new idea. It has been around for long.\nMicroservices take this to the next level where they are reusable deployed modules which can be used by others through an API contract. When a developer is working within a module, she doesn\u0026rsquo;t have to keep in mind a lot of other (external) concepts but can focus on only the ones that make sense in the given context.\nWhen people use normal modules (that are not microservices) in an application, they tend to be less disciplined in their usage of other module code. They just import it anywhere they want \u0026amp; start using it as they like. This increases the coupling between modules. Microservices stop this kind of undisciplined usage since calling a microservice is a network call (there are associated costs) \u0026amp; it is generally done through a very strict contract (interactions typically happen using a specific pattern - client). This means that developers will adhere to module boundaries, and will be deliberate about module usage.\nFrom a size perspective, small modules are always good. So as per modularization, small microservices are also good. That said modules need to be cohesive things which expose a single responsibility (or a single set of them). That applies to microservices too \u0026amp; if you can find the smallest cohesive set of functionality then we can make it into a microservice. In summary, modularization tend to make services smaller and push on upper bound to make things smaller.\nThe story does not stop here. Let us continue to the next one.\nRefactorability Refactorability as a term feels odd from an English perspective, but makes some sense from a perspective of developer. The way I understand it is that, it refers to the ability of a codebase to lend itself to easy refactoring. This ability depends on a lot of things. Generally good IDEs \u0026amp; editors provide this ability \u0026amp; they generally work better in the case of statically typed languages.\nAs a developer, refactoring code within a project, to create some clean \u0026amp; readable code has been one of the best joys I have experienced in my career. It rivals (even beats it sometimes) the feeling of building something completely from scratch.\nNow back to the process of refactoring. Irrespective of the development platform, most of the IDEs allow you to refactor code within a project. They generally don\u0026rsquo;t allow you to refactor code across multiple projects. This is even more true in case these multiple projects refer to different microservices which are integrating over a structured contract made up of say JSON and are potentially implemented in different platforms.\nWhile from a modularity standpoint, creating smaller \u0026amp; focused microservices is a good thing, when you do that, you tend to lose out the ability to easily refactor code. This again increases development time and hence something to consider.\nSo don\u0026rsquo;t make microservices so small that refactoring is very difficult. This generally won\u0026rsquo;t be problem if the concerns of microservices are quite separate (then they won\u0026rsquo;t have much commonality to refactor). To sum up, modularization is great, but it needs to be balanced with refactorability.\nScaling One of the key reasons for creating microservices is the ability to independently scale small services as per their needs. Please take special note of the word independently in that sentence. When we say we can \u0026lsquo;independently\u0026rsquo; scale, it should not just be a theoretical possibility. Creating small microservices that can scale separately since they deal with independent business use cases, is a good idea. But if that is not the case then there is a problem.\nLet us take a counter example:\nLet us say that a single business use case (which might include multiple user interactions) is spanning three services. Also, let us say that these services primarily serve this business use case only. So when you want to scale to serve more users of the business case concurrently, you will have to scale all the three services involved in a corresponding \u0026amp; related manner. This is really NOT independence of scaling. What this is, is a case where you don\u0026rsquo;t have any true independent scaling, but you have incurred all the cost of having a distributed system.\nWe need to keep this in mind before we decide to split things up to small services. So, while the idea of independent scaling will push the size of the service to be smaller, please keep in mind that unless things are truly independent, the point is lost.\nI will even take an audacious step to say that we should not use scaling as a criterion for determining microservice size. I think the other concerns will anyway guide you in the direction of achieving maximum possible scale. Again this could be controversial to some, and I am open for discussion.\nReplaceability We talked about this criterion as a key advantage of microservices. Microservices allow engineering teams to build a first cut or pilot version of some functionality, and then throw it away, and replace it with something better. This promise makes a lot of sense for startups \u0026amp; even for established companies who are trying to innovate \u0026amp; stay ahead.\nFor doing this, the size of the microservice better be small so that we developers feel that it is ok to throw it out \u0026amp; build something in its place. If we have a microservice which is large \u0026amp; holds sizeable functionality then it becomes more difficult for developers to dismantle it. We won\u0026rsquo;t feel comfortable to quickly replace it. It will take a lot more effort \u0026amp; when that happens, teams tend to forgo the change. It becomes a case of not wanting to deal with the regression that the replacement might cause. So if we want replaceability, then the size of the microservice needs to be small. So this criterion pushes down from the upper limit.\nDistributed Communication We just learned that small microservices are great for replaceability. But small does not mean good all the time. When we have small services, we invariably need to communicate between them to get work done. Distributed communication is a very hard thing to do.\nAll of us have experienced working with distributed systems in one way or the other, and we all are aware of the fallacies of distributed computing. There are dozens of patterns that we can use to bring reliability in distributed communication (entire books have been written on them) but as the first law states to never distribute objects if we can get away with it.\nSo distributed communication comes with its own bag of issues (reliability \u0026amp; latency related). If we can keep this communication to a minimum then our systems will be better off. So this drives the size of microservice to be bigger - pushes up from the lower limit.\nSize of a microservice - Summary We looked at a set of considerations above which act as forces governing the right size of a microservice. Whether you are trying to design/architect a new microservice or evolve one from a monolith, these considerations should be kept in mind. Obviously this is not very easy. There is no simple formula to arrive at an optimum size of a microservice. (I know it feels like a letdown after reading this for such a long time. I am sorry! 🥺) That said, giving a set of descriptions on these ideas is not an effective way to keep track of this information. In this section I will try to depict the above considerations into a more usable form in terms of quick reference. The idea is that once you understand the above considerations, this section could act as an easy reference for you to do the actual work of architecture.\nThe key considerations can be treated like forces. These forces act on the upper \u0026amp; lower limit of the size of microservice:\nForces which push the service to be bigger, push at the lower limit not allowing it to get smaller. Forces which push the service to be smaller, push at the upper limit to not allow them to get bigger. Fig 4: Key factors shown as forces affecting size of a microservice When the service tries to shrink down, the lower limit factors push to expand it. Similarly when the service tries to expand out, the upper limit factors push to shrink it down. I am also tabulating these factors along with the limit they influence for easy reference.\nFig 5: Key factors affecting size of a microservice tabulated Hopefully these aids will help you remember/refer to the key ideas which these thousands of words are trying to convey.\nClosing remarks We have come to end of this long write-up. At the end I want to leave you with some informal ideas. When deciding to build (or building) or carving out a microservice:\nFocus on Business capabilities \u0026amp; Service boundaries Don’t look at Lines of Code (LoC) Get a clear understanding of the user interactions involved in your service and related services. Focus on enabling agility within \u0026amp; around the engineering team. Use techniques like Bounded contexts, Aggregate design, Event storming etc. Err on the side of bigger - It is relatively easier to split it up later rather than the other way around. Be cognizant of nano/pico services. They are only useful if they are very simple utilities It is not an \u0026ldquo;in vogue\u0026rdquo; thing, and you don\u0026rsquo;t have to join it if you don\u0026rsquo;t want to! That\u0026rsquo;s it. We have come to the end. I have listed down all my references, so that you can go read \u0026amp; explore more. Please share your thoughts, comments, insights with me so that I can also learn from your experiences. Ciao!\nFor more on practical microservices challenges, I\u0026rsquo;ve also written about caching strategies in microservices and used a fictional bar conversation to explore timeouts and cascading failures — both connect directly to the distributed communication concerns raised above.\nReferences \u0026amp; Explorations Microservices article in Martin Fowler blog Book: “Microservices: Flexible Software Architecture” by Eberhard Wolff Article: \u0026ldquo;What’s the right size for a Microservice?\u0026rdquo; by Kyle Brown Article: \u0026ldquo;How big is a microservice?\u0026rdquo; - by Ben Morris Book: “Domain-Driven Design: Tackling Complexity in the Heart of Software” by Eric Evans Book: \u0026ldquo;Domain-Driven Design Distilled\u0026rdquo; by Vaughn Vernon Article: Event Storming ","date":"2022-07-30T00:00:00Z","permalink":"/micro-service-size.html","title":"The Right size of a µService?"},{"content":"Product \u0026amp; Engineering - Peers Product \u0026amp; Engineering are two sides of the same coin. Together, they make things happen. One without the other is meaningless or can be considered as leading a half life. We can broadly compare them to the role played by Legislative \u0026amp; Executive in a nation\u0026rsquo;s governance. One does not sit above the other, they sit to the side of each other. Equals. Peers.\nThe 3 levers That said, the perspectives they have and what they control are different. So let me start with the point that I want to make.\nThe common goal of all product development is to improve the product in question by working it and adding new features to it. This benefits the Customer. And a customer always wants quality. Both Product \u0026amp; Engineering teams aspire and work towards quality from different directions. Quality is the one thing we really can\u0026rsquo;t compromise (at least in the ideal case).\nStepping back a bit, we need to understand that when we deliver a feature in software (or anything in software), there are only 3 levers we can control:\nQuality Scope Time Now given that quality as a lever is taken away from both the teams, how do we use the left over 2 to manage the delivery of software?\nWho controls what? We are finally here.\nIn my opinion, Product team gets to control scope and the Engineering team gets to control time. The product team figures out what makes up the change (the feature) which is the scope and hence it belongs to them. They can add or remove things as they see fit. The engineering team figures out how to execute the change and it controls the time that is needed to make it happen.\nProduct figures out the what, but Engineering figures out the how and hence controls the when. Product can change the scope to effect the time but they can\u0026rsquo;t change time directly. Engineering can dictate the time but it cannot change the scope (directly) to suit its needs.\nIf one of the two crosses the boundary, the lever that gets affected is quality and that is the most detrimental for the customer. And everyone knows that Customer is King (or Judge?).\nThat is it. What do you think? Please share your thoughts.\n","date":"2022-04-30T00:00:00Z","permalink":"/product-and-engg.html","title":"Product:Scope::Engineering:Time"},{"content":"This is a write up on how I feel about my India changing in the context of religion. This is just a representation of how I feel. If it makes sense to you then you can consider listening to it, else you can surely ignore it (not that I need to say this 😅).\nMy life \u0026amp; religion I generally don\u0026rsquo;t parade the fact that I am a Hindu. I am not ashamed of it, but I don\u0026rsquo;t think it is relevant in most situations that I face. I love my gods - still find it difficult to decide who is the best between Lord Krishna and Lord Shiva. I love my epics and I do delve on the philosophies and ideas presented in them. The stories present in them have been a part \u0026amp; parcel of my life.\nIt is not just thoughts. There are also some actions I do in this regard. I pray everyday in the morning. I apply ash to my forehead everyday (even though I am supposedly an Iyengar). I observe some of the rituals like \u0026lsquo;Tarpanam\u0026rsquo; regularly. I celebrate all the regular Hindu festivals with puja and eagerly consume all the goodies prepared at those times.\nDoes all this make me a staunch Hindu? Some might say yes and others might say no. I personally feel that while these aspects have a place but there is more to following hinduism. There is one thought that stands out. I have never felt the need to assert my religion anywhere in my life. I hope it stays that way always and that is another part of what I like about being a Hindu. There is no need to prove to anyone that I am a Hindu (I am not speaking of other religions because I don\u0026rsquo;t know much about them).\nRecent events That is all good. But for the past few days, things happening around me are disturbing. For me they are just disturbing, but for the people involved it, they are painful. There are a few of them I want to mention here.\nThe first issue that comes to my mind is the Hijab row. This has been discussed a lot in the media and elsewhere, so I am not going to be able to add any more information to the discussion. The only thing I would like to express here is a thought which came to me on this whole issue. Everyday when I used to go to my office, I would apply ash to my forehead. I attend meetings and discussions with all my team members wearing it. Nobody has asked anything about it. I wear it also when I visit malls or other areas. Again no issues. I have worn it when I visited my school or college in the earlier part of my life. This applying of ash is surely related to my faith. In my mind, I believe that it will protect me. Now the question in my mind is: If I am allowed to do that all the time, I am not sure why a girl can\u0026rsquo;t wear a hijab to her school if she wants to, based on her faith. How is it different? Again, much more learned people and esteemed institutions might differ with me and I am no one to question to them - I am just expressing what I feel.\nThe next incident was about a student\u0026rsquo;s namaz prayer video shared by another student and that causing an uproar. After this, the student\u0026rsquo;s institution ruled that the student should no longer do the prayers in the premises. I have seen my friends performing their prayers in workplaces of different companies that I have worked in. No one has ever raised an issue about this. If workplaces can be accomodative, I am not sure why it is a problem in a college. Also in the context of this student, she has been performing the prayers for a long time before. And now this has changed. Why?\nThere is also the incident related to linking hindu festivals to vegetarianism and that leading to violence (while I am a vegetarian, Hindus in general are not - to me it is a choice). Recently I heard about attacks on religious processions and subsequent complaints about targetted demolitions. In both these cases, it is very difficult to know the full truth for a ordinary person like me. There are news reports claiming all sorts of things and it is difficult to know what the truth is.\nBut whatever the case is, these incidents don\u0026rsquo;t give me any good feeling about the country I belong to and live in. It seems that suddenly hindu people need to assert themselves (or even force upon others) as being hindus. Why?\nMy way of being a Hindu I am repeating myself but I have to say that all of these incidents don\u0026rsquo;t give me a good feeling. I am not a very learned person (especially in the context of religion). But the persona I have seen to exist in \u0026ldquo;my world\u0026rdquo; - my country, is a loving one. That persona can accept people for what they are and respect their choices.\nI care as much for all my friends whether they are named Amar, Akbar or Antony (not real names) and that is essential in my mind. I have learnt a lot from all my friends and I am grateful for it.\nI can\u0026rsquo;t speak for everyone in the world but I speak from my own roots and my own experience. Based on that I say this - I am part of a religion with 33 crore gods and a concept of ishta daivam (favorite diety). That religion does not need me to think that there has to be only one way. It seems counter-intuitive to me.\nLast word This life is precious. Every life is precious. Instead of propogating \u0026ldquo;the one idea\u0026rdquo; as the only idea, it is much better to have a confluence of many ideas and allow people to chose theirs and live their own lives with it.\n","date":"2022-04-25T00:00:00Z","permalink":"/india-extreme.html","title":"My India changing"},{"content":"A warm welcome to you! I am back from my long hiatus and I want to share a change of plan for this blog.\nTill date, this blog held my thoughts and my accounts on experiments I tried with on technology \u0026amp; software developement. And that was good. But I realise that as a software engineer and a person, it is not the only kind of thing I do. Please don\u0026rsquo;t think that the realization came to me only now! I just did not have the guts to act on it i.e. sharing more.\nLife is more Life is about a lot of things. I am a human in the profession of software engineering that I practice in India. I am part of a family. I have friends and I work in teams. I am also figuring out the bigger questions of life. I have some hobbies too. I have struggled with \u0026amp; enjoyed a lot of things and I still do. Given the different facets of my life, a blog on it can talk about more of them. I want to create a fuller account of my life here (finally some courage! 😅) .\nLife is same \u0026amp; different My life at a macro level is very similar to you and many like us. The broad strokes are similar and boring. But the details and minutae are different (I am almost certain of it :thinking:). So when I write about the things I care about and the events that happen in my life, there will be something new \u0026amp; familiar. The stories I write are always going to be my perspsctive, but there could be many other perspectives.\nA weblog is log or diary on the web and that is the aspiration. That said, there are limits on what I can put out here (don\u0026rsquo;t have that much courage yet 🤔). Hence this will still not be my entire diary, but I promise to make a honest effort.\nLife events can be small or big Life events can be small or big but they have there own characteristics irrespective of the size. The new blog entries can also vary in size. But they will surely provide at least one specific thought or viewpoint from me. That is the only thing I offer you.\nLife is interactive Life is about interaction of thoughts, ideas and people. I hope to capture that interaction. I also hope that this blog becomes a place where I can interact with you.\nSo going forth and conquering! Hope to express myself fully and interact with you to learn.\np.s.: Apologies to anyone who thought this was an article about the concept of scope in software development and associated ideas like scope creep etc. !\n","date":"2022-04-12T00:00:00Z","permalink":"/blog-direction.html","title":"Increasing Scope"},{"content":"The agile manifesto says people come above processes. But every team I have worked with has always followed a process framework. The usual suspects are of course Scrum and Kanban. Why do they do this?\nA process I would like to move away from the context of agile. For me, a process is something more fundamental. Processes are not something which only teams follow. It can be applied at a personal level as well. So let me state the definition of the word (Googled it!)\nA series of actions or steps taken in order to achieve a particular end This definition captures the essence of the concept of process for me. Processes exist in all shapes and sizes. I follow a daily routine or process to start my day and get to work on time. I follow the process of TDD - Red, Green, Refactor when I do any worthwhile development.\nWhy process for me I am sure you are asked to follow certain processes in day to day work. Or there could be these process gurus who are asking you to follow some new shiny process. And, you are either verbally or non-verbally quoting the agile manifesto to convey your disgust about following this process. In your mind - processes are a waste of my time! . I used to belong to this same gang.\nThen something changed. May be old age (read experience, gray hair etc.) changed me. Once you get to a position where raw energy is not enough to accomplish something, I think the concept of process kicks in. At least that happened to me. Also raw energy is better harnessed with a process of steps that can be followed to meet an end. Just my experience. That said, I always remember that process is never bigger than the end it is trying to get to. It is a set of steps that one can follow to get there hopefully and it is also something which needs attention and tweaking.\nWhy process s**ks for you Let us turn back the attention to you and your complaints. You ask me - Why do processes s**k?. I have also felt it sometimes (even now feel it sometimes). In my opinion, processes suck for two reasons.\nOne: Most of us adopt a process so that we can move faster. I follow this process and my delivery speed will double or triple. So I am going to do this. Within a week or two, you see you have slowed down to half the rate. WTF! This process sucks. and this is the problem. In my opinion, the primary purpose of adopting a process is not speed. It is to get predictability in terms of outcome and results. Let me repeat that - Process helps make things predictable. And believe me that is a more useful quality than speed. Predictability allows us to plan and decide; to ensure that we get where we want to get to in a well known time. It helps us make right choices. In a word it makes us effective.\nSpeed is about efficiency and that is good to have. But first you need to be effective. The main purpose of process is to drive that. It might eventually lead to speed or efficiency and that is great. But seeking speed instead of predictability is sure shot way to ensure that a process never works for you. It will s**k!\nTwo: A process becomes effective only if person(s) following it give it a chance. Giving it a chance means\nbeing involved in the process - look at the steps - its motivations and purposes, understand them, observe them, and giving it time. When I started TDD, it felt very taxing and time consuming, even time wasting. I am sure many of you felt that way. Once I started following the process, observing the details and kept doing it for sometime, something changed. Now it has become my natural way to do development. Am I faster? I am slower than if I am just \u0026lsquo;spike\u0026rsquo;-ing, but if I am developing anything worthwhile (that implies with tests), then TDD is faster. More importantly I am not looking for just speed. I now have a predictable way to write good quality code and allow me to think through things. And lo and behold the process works!\nAnother good example of a process is a standup. A standup is where the team get together and share what is happening (that is a very simple definition but still a useful start). A typical standup\nstarts on time a team member talks about what they did, what they are going to do and impediments next one follows suit until everybody completes. This is just the basic outline. The process entails a lot of other nuances which are equally important. Let me pick one of them.\nIn one of the teams I was part of, standup happened as members reporting their previous day\u0026rsquo;s work to the leader(s) in the team. And of course that sucked! The team members felt a lot of pressure. The standup process itself says a strong NO to this. We being believers, noticed this and asked each person to face the team to provide the update and not the lead. And something changed - it felt more like sharing than reporting. There were many more nuances which we watched out for, acted and made changes to the way we were doing things. And it took time. Eventually the standup became a process which everybody looked forward to come into, so that they know where their team is and how they can help or contribute.\nIn closing Good processes (whether team or individual) needs feedback and time. If you give up too early and don\u0026rsquo;t really get involved it is bound to fail.\nAnd more important than that please remember a process is about predictability and consistency. Speed is a potential side effect which you may get to enjoy.\nPlease write in with your feedback and thoughts on processes in your own life or work. I would love to hear and learn more.\n","date":"2019-10-27T00:00:00Z","permalink":"/why-process.html","title":"Why Process!"},{"content":"Act 1 \u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash; The curtain opens \u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash; - Jill µ service is already sitting in the bar. The setting is typical of all bars. It is crowded with a lot of µ services having a good time with drinks and conversations. It is a chatty place. Jack µ service enters, looking haggard. - {: class=\u0026ldquo;figure\u0026rdquo; }\nJack µ: What a day! Shall I sit here? \u0026hellip; I am going to sit here. Please don\u0026rsquo;t mind.\nJill µ: Go ahead. No problems.\nJack µ: Thank you. I am Jack. Who are you?\nJill µ: I am Jill. Pleased to meet you in person!\nJack µ: Meet you in person? What does that mean? Does that mean that we know each other?\nJill µ: You talk to me all the time professionally, by calling my URI - jill.ourcompany.io. Ring any bells?\nJack µ: Oh yeah. I know you. I send requests to that url, I mean your url all the time. Yeah, I remember.\nJill µ: Told you.\n- Jill is smiling. Then Jack\u0026rsquo;s demeanor changes. Looks up agitated \u0026amp; angry - Jack µ: You gave me so much PAIN last week. Why did you do that?\n- Jill looks at Jack shocked for a moment, but calms herself down - Jill µ: What did I do?\nJack µ: Oh! You don\u0026rsquo;t remember last wednesday. Oh boy! I remember it all.\n- A look of understanding comes on Jill\u0026rsquo;s face - Jill µ: Ah! I do remember. It was a bad day. My development guys were all looking at my problem\u0026hellip;\n- Jack lifts his hand and interrupts Jill - Jack µ: No, no, no! It was a BAD day for me. I got sc***ed because of you. It is all because of you.\nJill µ: Hold on. Let us take it slow. Here, have a drink.\nJack µ: Don\u0026rsquo;t patronize me. You did this to me.\nJill µ: What really happened? You need to give me details so that I can understand. Calm down and have this.\n- Jill picks up the CPU credits from the counter and hands it to Jack and he takes a swig. Jack looks a bit satiated - Jack µ: Okay. This is what happened. I called you to get the answers I need from you to do my job as usual. I waited for an answer but it never came. And I kept waiting. Then more people asked for the information and I called you again. And you just did not respond. I got all stuck up - all blocked threads; all my servers froze up. I couldn\u0026rsquo;t serve any of my customers. Everyone was shouting \u0026amp; pinging me again \u0026amp; again but, I just couldn\u0026rsquo;t do anything. I lost face because of you.\nJill µ: Ok. Let us talk through this. We are both µ services. We take care of different aspects of the business domain - my developers call it bounded contexts. We work together to ensure that our customer needs are met. Your customers are my customers too. For a given usecase, many times, we have to talk to each other and get things done. And we do that all the time and mostly it is successful.\nJack µ: Yeah, I know that. I am not d**b. But on that day, you\u0026hellip;.\n- Jill interrupts Jack - Jill µ: Hold on Jack. Let me finish. We both want the same thing \u0026amp; you need to understand that. But given the nature of the world we live in, it is possible that one of us doesn\u0026rsquo;t work as well at times. Things go wrong with the Infra guys sometimes. Or sometimes our developers make a mistake. And sometimes the Network guy acts up - rare - but that does happen. We are a distributed system. We have to live with the problems that come with it.\n{: class=\u0026ldquo;figure\u0026rdquo; }\nJack µ: Yeah, yeah. I understand all that. But I really don\u0026rsquo;t want go down when you go down. I don\u0026rsquo;t like this CASCADING of failures . There are many things that I can do to help my customers even when you are down. But since you bring me down with you, I can\u0026rsquo;t serve anyone. I don\u0026rsquo;t like it.\nJill µ: I understand that Jack. I appreciate you wanting to be available for our customers. Please believe me. But as I said, things go wrong with us at times. Last week, I heard your DB guy was acting up and you couldn\u0026rsquo;t help your customers. Pitcher µ was complaining about it to me.\nJack µ: Yeah, that did happen. I know it happens to all of us. But I don\u0026rsquo;t want to feel helpless like this.\nJill µ: Let us dig deeper Jack. How do you call me to get your answers?\nJack µ: I call you through your REST endpoint. I make a call with the right parameters and you return back a JSON response almost immediately. That is the way I like it. But that time everything went wrong.\n{: class=\u0026ldquo;figure\u0026rdquo; }\nJill µ: I got what you are doing now. By the way, do you use TIMEOUTS on your side? I mean on your calls to me as a client.\nJack µ: What timeouts? I don\u0026rsquo;t follow you.\nJill µ: Ok. Timeout is the concept of time boxing an operation so that, if things don\u0026rsquo;t work out within that time, you give up and move on to something else. This is employed in many places. Not just in service to service requests, but when getting any resource that is used by µ services like us. We could use timeouts for acquiring a lock, connecting to a database or file system. In all such actions, timeout is good idea.\nJack µ: I don\u0026rsquo;t follow that fully. Can you explain it a bit more?\nJill µ: Sure. Let me take an example of what I do. Whenever I try to connect to a database, I try it for a period of 6 seconds. If something is wrong - I mean the DB could be having some issues or the network could be acting up, I give up on that task temporarily and throw an error for everybody to see and move on to other things. I might try it again, but I don\u0026rsquo;t keep hoping and waiting forever for things to happen in the first call. Am I making sense?\nJack µ: Kind off\u0026hellip;. But\u0026hellip; But if you give up, then you can\u0026rsquo;t serve the customer needs. I mean you don\u0026rsquo;t have the data to serve the request. Then, what is the point?\nJill µ: You are right. For that request, I can\u0026rsquo;t serve the customer for sure. But I also don\u0026rsquo;t get bogged down by a slow or failed resource or dependency. I can drop that request and serve other requests. This way, I don\u0026rsquo;t have a set of blocked threads and won\u0026rsquo;t become completely unresponsive. Isn\u0026rsquo;t that better?\nJack µ: Yeah. It sort of makes sense at a high level. Not sure, how it applies to me though.\nJill µ: You said you call my REST endpoint. That is a http call and you must be using some kind of http client. Almost all good http client libraries whether it is in Python, Ruby, Java or any other language, will provide a way to configure timeouts. So go ahead and configure them with some sane values and you are done.\nJack µ: Wow! That is interesting. So what kind of timeouts are involved in http calls?\nJill µ: Typically there are two timeouts that are configured. One is the connection timeout - the time taken for establishing the tcp connection. The other is a read timeout - which is time waiting for data to be received during a read. All these libraries provide the ability to configure both these values. Once you configure them to appropriate values as applicable to you, you are done.\nJack µ: That sounds pretty neat. So you are saying that once I configure myself with these timeouts for my interactions with you, I will be hale, healthy and happy!\nJill µ: Sure. Doing this will be a great step towards your own stability and avoiding Cascading Failures.\nJack µ: Okay! This is good. I am finishing this drink and going to talk to my Dev folks right after. I am going to be the stablest µ service in the world. Cheers!!\nJill µ: Cheers!! Have fun buddy! Have a timeout!\nMusic grows louder and Jack and Jill go up to the dance floor. \u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash; The curtain falls \u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash;\u0026mdash; For more on building resilient microservices, see Caching in Microservices for performance and scale patterns, and The Right size of a µService? for the architectural thinking behind bounded contexts and service sizing.\n","date":"2019-10-13T00:00:00Z","permalink":"/2-%C2%B5-services-chat-timeout.html","title":"µservices gossip: Take a timeout!"},{"content":"The back story As part of day to day development work, I have been trying to apply functional concepts wherever it makes sense. I have long been a OO developer and hence some of the effects stay with you. Especially design patterns. In my opinion, design patterns - primarily GOF patterns, though referenced in the context of OO design and languages, have some good ideas that can apply elsewhere too. With languages that support functional features, I believe some of these patterns can be applied at a method/function level instead of carrying around the cruft of classes for just doing behavior (OO enthusiasts bear with me - Classes are great in the right places, but in others they are just there because a language forces you to use them).\nI am also a fan of Python decorators. Decorators are a very cool and powerful feature of python. It is syntactic sugar to create higher order functions - a very important functional paradigm feature. We can combine multiple functions to get work done - composability. You can read a lot about decorators here - a highly recommended read. I will referring to it throughout this post.\nSo given my background and my current love (functional programming and decorators), I have had a chance to get inspired by GOF pattens and use decorators to create some clean code as part of my work. Here I am going to share that attempt with you.\nOk, let us get in When you look at the general use and applicability of python decorators they feel like a ready-made way to replace the traditional Decorator pattern - and for the code lovers you can look here. This thought is not knew and you will see it mentioned in other places too. Theoretically, this is not exactly correct (my opinion). A class level decorator is a structural pattern which allows me to decorate multiple behaviors of the object or component. But in practical terms, I have seen that this does not pan out and method level decorators (using python decorators) are more prevalent.\nAs I played more with python decorators, I realized that there is one more of my favorite patterns that I could implement using decorators. That is the Chain or Responsibility pattern (CoR) - code sample. CoR is a behavioral pattern and behaviors are generally managed at method level. Hence decorators feel like a great fit for CoR.\nEnough talk! It is really difficult to explain my thinking with english words. So let us get down to writing some python words/code. I need an example to illustrate what this is.\nThe example Here is a contrived example (of course) - a calculator. And since I love TDD and py.test let us start with a test which can drive our code.\n:::python import pytest import app.natural_number_calc as calc @pytest.mark.parametrize(\u0026quot;operator, arg1, arg2, output\u0026quot;, [ ('+',3,2,5), ('+',4,2,6), ('-',22,12,10), ('-',24,4,20), ('*',12,7,84), ('*',11,11,121), ('/',84,6,14), ('/',11,11,1), ('^',11,2,121), ('^',4,3,64), ]) def test_calculator(operator, arg1, arg2, output): assert output == calc.do(operator, arg1, arg2) def test_calculator_operator_not_supported(): with pytest.raises(ValueError) as ve: calc.do('%', 5, 10) assert 'Calc Error - Operator not supported' in str(ve.value) @pytest.mark.parametrize(\u0026quot;operator, arg1, arg2\u0026quot;, [ ('+',3,0), ('+',4,-2), ('-',22,0), ('-',-24,4), ('*',12,0), ('*',11,-4), ('/',84,0), ('/',12,-2), ('^',11,-2), ('^',-4,2), ]) def test_calculator_non_natural_numbers_not_supported(operator, arg1, arg2): with pytest.raises(ValueError) as ve: calc.do(operator, arg1, arg2) assert 'Calc Error - Natural numbers only supported' in str(ve.value) The test suite covers everything which I want to implement with my calculator. So we have a start.\nThat is some c***! For satisfying the test suite, here is some plain vanilla code.\n:::python def do(operator, arg1, arg2): if operator == '+': return _add(arg1, arg2) elif operator == '-': return _subtract(arg1, arg2) elif operator == '*': return _multiply(arg1, arg2) elif operator == '/': return _divide(arg1, arg2) elif operator == '^': return _power(arg1, arg2) else: raise ValueError('Calc Error - Operator not supported') def _power(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return arg1 ** arg2 def _divide(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return arg1 / arg2 def _multiply(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return arg1 * arg2 def _subtract(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return arg1 - arg2 def _add(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return arg1 + arg2 Yeah, I know. This is pathetic code\u0026hellip; so many ifs and elifs and all. That is on purpose so that we can improve it with some decorator and pattern goodness. And it is code that works and hence our test passes! We are on green mode \u0026amp; we can start refactoring.\nLet us start decorating If you look at the above code we see an obvious copy paste case. The check for natural numbers is repeated on every operation code and we can easily decorate each operation code using the Decorator pattern or in our case python decorators. Let us first look at the decorator code.\n:::python def only_natural(func): def wrapper(arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return func(arg1, arg2) return wrapper If you know your decorators, this is a simple decorator in action. It takes the function that needs to be wrapped. It defines an inner wrapper function which take two arguments which checks the arguments are natural numbers. If they are then the wrapped function is called else raise an error. Let us now use this decorator on our calculator module.\n:::python def do(operator, arg1, arg2): if operator == '+': return _add(arg1, arg2) elif operator == '-': return _subtract(arg1, arg2) elif operator == '*': return _multiply(arg1, arg2) elif operator == '/': return divide(arg1, arg2) elif operator == '^': return _power(arg1, arg2) else: raise ValueError('Calc Error - Operator not supported') @only_natural # decorator applied def _power(arg1, arg2): return arg1 ** arg2 #1 @only_natural def divide(arg1, arg2): return arg1 / arg2 #2 @only_natural def _multiply(arg1, arg2): return arg1 * arg2 #3 @only_natural def _subtract(arg1, arg2): return arg1 - arg2 #4 @only_natural def _add(arg1, arg2): return arg1 + arg2 #5 You can see that our calculator is surely improved (note the numbers) using the decorator pattern created with decorators. But the do method is still a eyesore. With just 5 operations, we have a huge if/elif/else clause and this will only grow further if we want to support more operations (I understand this is a toy example but you get the picture).\nEnter CoR So how can we improve this. Let us dig in. It is clear that for each operation, there is a corresponding method to handle it. The handling determination happens one after the other. It almost feels like a set of actions to do\u0026hellip; a chain of things to do\u0026hellip; a Chain of Responsibilities to complete (come on, that is not such a bad lead up!). Let us give it a shot once.\nBefore we get to the code let us understand a bit. A classic COR goes roughly like this. A request which needs to be processed is given to the first link in the chain of processors. That processor either processes it if it can or passes it on to the next processor. A given processor knows what it can process and also knows who is the next one in the chain. That is pretty much the essence of it. The class based style is already referred earlier, so let us try to do this with decorators which can work at method level.\nFirst shot:\n:::python def cor(next): def wrapper(current): def inner(*args): output = current(*args) return output if output else next(*args) if next else None return inner return wrapper This is a more involved decorator than the first one. Because we need to take an argument, we need this double nested structure. The outer most cor function is the visible annotation part of the decorator and it takes the function object that needs to be called next in the chain as argument. The cor function defines a wrapper function which is the one that accepts the actual function that is being decorated - the current. The wrapper in turn has the inner function where the actual work happens. It calls the current function and gets its response. If that response is valid (a simple truthy response), then it means that request has been processed and the chain can be broken to return the result. If the response is not valid, it means that the current function is not the one to handle the request. Hence the control has to pass on to the next processor or function (which is available to inner because it is a closure - another functional feature of python. You can read more about decorators that take arguments here.\nFor this to nest along with the already existing decorator for natural numbers, we need to do some changes to that decorator.\n:::python def only_natural_with_operator(func): def wrapper(operator, arg1, arg2): if arg1 \u0026lt; 1 or arg2 \u0026lt; 1: raise ValueError('Calc Error - Natural numbers only supported') return func(operator, arg1, arg2) return wrapper The above one is just a simple tweak, so let us move on. Let us look at the calculator to figure out how its usage gets manifested.\nWhat the CoR? :::python def do(operator, arg1, arg2): value = _add(operator, arg1, arg2) if value: return value else: raise ValueError('Calc Error - Operator not supported') @only_natural_with_operator def _power(operator, arg1, arg2): if operator == '^': return arg1 ** arg2 else: return None @only_natural_with_operator @cor(next=_power) def _divide(operator, arg1, arg2): if operator == '/': return arg1 / arg2 else: return None @only_natural_with_operator @cor(next=_divide) def _multiply(operator, arg1, arg2): if operator == '*': return arg1 * arg2 else: return None @only_natural_with_operator @cor(next=_multiply) def _subtract(operator, arg1, arg2): if operator == '-': return arg1 - arg2 else: return None @only_natural_with_operator @cor(next=_subtract) def _add(operator, arg1, arg2): if operator == '+': return arg1 + arg2 else: return None Hmm\u0026hellip; Pretty underwhelming to put it nicely. But before we get into it, let me first explain what this is doing.\nThe do method just calls the first method in the chain, the _add method. It expects that the processing gets completed to return a valid result. If it gets back an invalid result (None), then it understands that this calculation cannot be processed and throws an Error. The do method has improved for sure.\nThe _add method declares the next operator/function to call as decorator parameter - (@cor(next=_subtract)). In the body it checks if it can process the request - is it the right operator? . If it is then great, else it returns None denoting that it is not interested. This happens in each operator/function till we reach _power which has no next. So the chain stops here. We can of course extend the chain from this point onwards and for that we don\u0026rsquo;t have to touch the do or the _add (or other) methods. All the methods are separated. This cor decorator could be used to create a chain of any set of functions as long as they follow the basic contract of returning a truthy value if they did the processing or a falsy value if they want to pass it on (provided if they have defined a next).\nCoR 2.0? Now back to that bad feeling we get on seeing the resultant code. In the process of introducing CoR to save the do method, the operation functions have lost their charm. They are crowded now and that is not what we want. And when we look closely, we see that each operation function does one common thing: it checks if the operation is what it can handle, before it actually does the real work. The error handling in the do function looks similar in some way too. All these seem to be common behavior which can be applied to these functions using a wrapper/decorator - is it not? Let us get our decorator pattern back now. The improved cor (2.0) decorator looks like this.\n:::python def calc_cor(my_operator, next=None): def wrapper(current): def inner(*args): if args[0] == my_operator: return current(*args) elif next: return next(*args) else: raise ValueError('Calc Error - Operator not supported') return inner return wrapper This is no longer the very generic cor decorator we started with but we sort of expected that. This is a decorated-calculator-specific-CoR - calc_cor. This decorator takes two arguments. The first one is the operator supported by the current function and the second one is the next function. It also expects the the current function (which is being decorated) to always takes the operator symbol as the first argument - the implicit contract. Since the operator is passed, the check of applicability can be done in the decorator itself. Also it does the error handling. This is the decorated part of the new CoR. Now let us see how this changes our calculator code.\n:::python def do(operator, arg1, arg2): return _add(operator, arg1, arg2) @only_natural_with_operator @calc_cor(my_operator='^') def _power(operator, arg1, arg2): return arg1 ** arg2 @only_natural_with_operator @calc_cor(my_operator='/', next=_power) def _divide(operator, arg1, arg2): return arg1 / arg2 @only_natural_with_operator @calc_cor(my_operator='*', next=_divide) def _multiply(operator, arg1, arg2): return arg1 * arg2 @only_natural_with_operator @calc_cor(my_operator='-', next=_multiply) def _subtract(operator, arg1, arg2): return arg1 - arg2 @only_natural_with_operator @calc_cor(my_operator='+', next=_subtract) def _add(operator, arg1, arg2): return arg1 + arg2 That looks way better than what we had before. The do method just calls the first link in the chain. Each chain link just does its processing. Everything else is just declared as decorator arguments and we are done. This combination of COR and Decorator pattern using decorators seems to have produced the best results. Wouldn\u0026rsquo;t you agree?\nCentralized CoR -3.0!?! I showed this result to Sathia, a friend and colleague of mine (that was different production code but the concept is the same). He pointed out something. With this design somebody trying to add a new operator has to figure out where in the chain she needs to add it. Rather she has to figure out where the current chain ends and add the new one there. In the above example that is simple. In real world code this may or may not be easy. He wanted to see if there is a way for each operator function to just register itself and then the chain would execute them. Of course in all these cases we are talking with the underlying premise that the operator processing order does not matter.\nSo some more thinking is needed. Can we make the CoR satisfy this? For this, we probably have to give away the decentralized nature of the current CoR. We need some kind of centralization. We need some way to register operation functions to a common place and then pull the chain to execute them all. Here goes another shot.\n:::python CHAIN = [] def link_to_chain(predicate): def wrapper(operator): CHAIN.append((predicate,operator)) return operator return wrapper def pull_chain(*args): for predicate,operator in CHAIN: if predicate(*args): return operator(*args) raise ValueError('Calc Error - Operator not supported') The first function link_to_chain is a decorator function which registers (or links) the operator and its predicate into a registry or chain CHAIN. The predicate is nothing but a function or lambda which provides applicability check. In this case the decorator is not really doing any decoration (no pre or post processing). It is more a way to plug things in.\nThe pull_chain function executes the CoR. It runs through the chain of handlers, uses the registered predicate to find the right one, executes them and breaks out of the chain. If there is none found then it raises.\nWith this idea now the calculator looks like this\n:::python def do(operator, arg1, arg2): return pull_chain(operator, arg1, arg2) @link_to_chain(lambda *args: args[0]=='^') @only_natural_with_operator def _power(operator, arg1, arg2): return arg1 ** arg2 @link_to_chain(lambda *args: args[0]=='*') @only_natural_with_operator def _multiply(operator, arg1, arg2): return arg1 * arg2 @link_to_chain(lambda *args: args[0]=='/') @only_natural_with_operator def _divide(operator, arg1, arg2): return arg1 / arg2 @link_to_chain(lambda *args: args[0]=='+') @only_natural_with_operator def _add(operator, arg1, arg2): return arg1 + arg2 @link_to_chain(lambda *args: args[0]=='-') @only_natural_with_operator def _subtract(operator, arg1, arg2): return arg1 - arg2 Not bad at all! Actually looks pretty good to me. Individual functions link to the chain and the do method pulls the chain. The single responsibility of the functions shine through. Given that the chain is centralized, the individual functions don\u0026rsquo;t even care about who is next. All they do is register into the chain along with their predicate. This is probably the cleanest solution we can get as of now. Time to stop and take a break!\nClosing thoughts Python is great language with support for useful functional features. Decorators are a sweet way of doing functional programming in python. The great thing I realized in this attempt is, when we try to do functional programming, your earlier learnings of GOF design patterns don\u0026rsquo;t go waste. The ideas still make sense. All we need to do was to tweak them a bit to make them applicable in a functional context. And lo behold we have much better code than where we started \u0026hellip;the if/elif/else blob in the beginning\u0026hellip; Let us keep learning and try to extract out the essence of the things we learn. Then we might actually be able use it in more than one places and in more than one ways.\nHappy development to all in the festive season! Please chime in with your thoughts and comments. Your criticisms and improvements are most welcome since I learn a lot from them. See you soon.\np.s: You can get all this code here\n","date":"2019-09-29T00:00:00Z","permalink":"/gof-inspired-decorators.html","title":"GOF inspired python decorators"},{"content":" TL;DR\nCaching in microservices can help with improving performance and scaling if used wisely. Opt for service level domain aggregate caches and use mashed up object caching on client services only when you are trying to speed-up/avoid local processing on remote data. Don\u0026rsquo;t use blackboard caches and remember cache cannot be a source of truth or a permanent data store. Origin Note\nThis article is based on a talk I gave at an event hosted by Everest Engineering. The article serves both as a independent reference on the topic for anybody and a refresher for people who attended the talk. Why caching in Microservices Microservices offer us a lot of advantages but they are not a silver bullet. Every architecture tries to satisfy the “ities” . This architecture style is no different. It is very promising but it is not without its trade-offs.\nEveryone has heard of caching. It is prevalent in our world of computers and software at multiple levels. From the CPU level L1/L2 cache, to in-memory caches in our monoliths, all of us would have seen caching in some place or the other. Why is it used? There are two desirable characteristics for any user feature:\nRespond to the user very fast - performance. Respond to a lot of users - scale. And caching can help with both.\nBut do microservices need them? Microservices already offer a lot of good qualities to our systems - like independent scaling, independent data storage for better performance etc. . So should we care about caching. Also caching is not the easiest thing. You might have read about the saying in Martin Fowler's bliki - [Two Hard Things](https://martinfowler.com/bliki/TwoHardThings.html): There are only two hard things in Computer Science: cache invalidation and naming things To answer this let us dig deeper to identify challenges which microservices introduces.\nUse case - Viewing/Editing an online document The use case is pretty common. So let us look at potential architecture for making this work. For showing a single document to the end user there are 5 - 6 services involved if we adopt microservices architecture. The individual components are:\nDocument service - This one serves the original document. Comments service - This one provides the various comments created on top of the document by different users. Authentication service - This is a system service which ensures that the call to the document service is from an authenticated user. This could be API gateway but I am representing it as a service so that it is clear that it is another layer/system involved in the interaction. Authorisation service - It checks if the user can see/edit the document - Action level authorisation. Tenant service - This ensures that the document requested belongs to the same tenant as the user - Data level authorisation User Document service - The Orchestrator. This talks to the underlying services and mashes up the final information and sends to the user. Given the above architecture, let us think about performance. Generally a single request made by the user is expected to respond within 300-500 ms. The idea is that if the first byte comes through fast then, there is some time for the browser to visually display the content along with any client side processing it has to do within 2-3 secs.\nIn the above microservices architecture instead of one service (monolith) returning within that time, all these 5 services should work together to respond within the same time. For simplicity, if we are thinking of splitting it up equally we are talking about 50-80 ms per service. That can be pretty tight. If the page is not ready for end user consumption in 2 - 3 seconds, the user will move to a different document editor provider.\nMicroservices offer a lot of good. But in this context where we need great performance, the need to talk to multiple services to respond to one use case can mean a very slow and painful experience for the end user. Not good. We need to do something. What can we do which will help us improve performance and scale? Caching!! Applying caching to microservices allows us to hit our required goals. That does not mean that we apply caching to anything \u0026amp; everything. There are things to consider, things to manage.\nNow that we have established why caching is useful, let us get into more detail about caching. Let us start with what you would want to cache.\nWhat to cache A general cache acts like a map or hash or dict. Pick your term based on your language of choice. Any object is added to the cache by identifying it with a key. A cache generally does not care what value it caches. You can then retrieve the value using the key. So we could cache any kind of object in a cache. But what should we cache?\nOut of scope\nBefore we go deeper, I am not covering the entire topic of http caching. While http caching is useful in the context of microservices they are not really specific to them. It is applicable more generally. Domain objects/aggregates In the world of services (I will interchangeably use service and microservice because I believe microservice is just a SOA service done right), one of the primary things you should consider caching are domain aggregates or objects. Any given microservice generally deals with one primary domain aggregate or object (may be two if it makes sense). In the example we talked about earlier, we had an comment service whose primary domain object is comment. Similarly document could be the one for document service. Caching the primary domain aggregate/object means that all relevant information required by the client can be easily served up quicky without looking at multiple places - especially the database. The actual response could be a subset of the data, but caching the aggregate allows us to adapt \u0026amp; support many use cases. We know databases and associated disk reads can be the cause of big performance delays. By caching domain aggregates we make it much easier for the service to serve its clients. There are still things to consider here. We will discuss about it down the line.\nConfigurations Another thing we look at caching is configurations of a service. This one is fairly common even in the monolith world. Configurations generally don’t change much and are used in different parts of the app - hence they are a great candidate for caching.\nMashed up objects with processing/calculations The above two cases are straight-forward. Next thing to consider for caching is mashed up objects. This is typically employed by an orchestration service acting as client to other services, and it involves merging in responses from these services, doing some calculations or processing on top of them and caching the result. Again referring to the use case above, the user document service might take the document(s) from the document service and merge the applicable comments from comments service and cache these rich documents on its side. This means that you not only avoid round trips to other services but also don’t need to do the additional processing to match, merge and position them. This means better performance and also lesser load (hence better scale) for all the services involved. There are trade-offs involved here too and we will get to them.\nAs a general advice, I would say that you should cache everything BUT only if you can.\nWhere to cache Now that we know what to cache, let us talk about where to cache.\nIn service memory Within a service, we could just use an in process / in memory cache and improve performance with great ease. This works, but is applicable for a very limited set of use cases. One example is static configuration information. This is not very large in size can be stored in a in-memory, in-process cache. Given that any service worth its salt will be setup as a cluster in a production setup, we have a replicated cache in each of the service nodes. This cache will be the fastest of all since it is not just in memory, it is in same process as the service.\nThe above approach allows us to get started, but falls apart soon. When we want to cache domain aggregates/objects, a clustered service will find it very difficult to keep changes in sync across the memories of multiple service nodes. Also, once you go down the path of caching and get the taste of performance gains, you will plan to cache a more in memory. This means that the cache is competing for memory with the actual service procesing requests. This can lead to reduction of service scale. It is time to move out of service memory.\nOut of service memory - Standalone The first obvious choice here is to have a standalone caching solution which can be reached by different service nodes for both reading and writing data. This is obviously going to be slower than the in-process cache but it will still be faster than going to the database and doing disk reads. Also given that it is separated from individual service nodes it removes the overhead created by cache storage on the individual nodes. Typical solutions used here are Redis, Memcached etc.\nOut of service memory - Distributed When we want scale these even further, we get into distributed caching and in-memory data grids. These solutions allow for multiple nodes holding a large amount of data in memory for faster response and higher scale. It is not uncommon to have a 100 node cluster of in-memory data grid machines which are hosting terabytes of data in memory by employing partitioning of data across different nodes.\nEach of these individual solutions provide a lot of different features but that is not our focus.\nWhat we have covered now is a broad base of locations where data could be cached. Each location of storage has pros and cons and are suited depending on our needs.\nWhen to cache We now know what to cache and where to cache it. Now let us discuss when we would cache any data.\nOn Demand One approach to populate the cache with data is when it is required. When a particular piece of data is requested and the cache does not have the same, then the data is picked up from the source, the cache seeded with the same and then returned back to the requester. This is the On Demand mode of populating a cache. This mode can work in most scenarios but has a couple of drawbacks. The first request which populates the cache will be very slow and leads to a bad experience to that end user(s). The other one that if there are multiple service nodes which request for the same entry then it could cause database contention.\nPre-loading The other approach to when to cache is to pre-load data upfront. As part of the service initialisation process, the cache was seeded with required data. This means that there is a huge load on the data store during start up and hence a potential delay in start up. But once the loading is complete, the cache is primed and end user experience is great - no more delays even for the first user. And if you cache most of the relevant data, we might even survive a db outage! One problem with this is that, we don’t know what to cache if we are not planning to cache everything.\nHow to cache - Patterns Let us get into details of how caching can be implemented within microservices. There are some well known patterns for reading and writing to cache. These have their pros and cons as well. Also they are not mutually exclusive in any way. They generally work together to solve problems. Let us go through them one by one.\nCache aside The first one is the Cache aside pattern. This is the most common pattern and used extensively. The idea of the pattern is to treat cache as a different store similar to the database. A service would read and write to the database and the cache as an aside. The control of what and when data are written into or read from the cache lies with the service itself. This pattern is great for read heavy workloads. Also we could write the service in such a way that during a failure in cache setup - when we use standalone/grid mode - the service can still keep serving from db. Of course this can’t be sustained for long given the cache setup is to support scale, but the option is there. The approach for when writes happen depends on us. Writing to database is the first thing the service will do - almost always. What happens to the cached entry is subject to developers choice - the patterns leaves this open to us. One thing to do is to just remove or invalidate the entry from the cache. There are others options available.\nI prefer this approach because as a business service writer I have lot more control with this approach. Hence I have used it a lot as well.\nSometimes we really don’t want so much control. Rather we want convenience and ease of use. The following patterns afford this one way or other and the unifying aspect of these patterns is that the caching library or system acts as the facade and controls how data is written/read to/from the underlying source data store. Read through The first one among them is the Read-Through pattern. Here the cache, when requested for a entry and not finding it, will initiate a call to the underlying store to read the data. It will then cache it and return the data to requester. The key thing to note here is, the cache is the one orchestrating the action. This is different from how cache aside pattern works where the control is with the service code. Also Read through pattern follows lazy or on-demand loading and hence has the same caveats. We must also remember that in this pattern the data structure cached must match with the structure stored in the underlying store.\nEven in Cache aside, we could follow a similar technique of lazy loading when writes happen (i.e writes just invalidates the corresponding entry in cache if it exists) if the applicable caveats work for you.\nWrite Through The Write Through pattern is about writing data. This is similar to Read-Through - the cache system sits in between the service code and database. With this approach when changes are made to the cached entity, the service writes into the cache and that in turn writes into the database. Both writes need to be completed before completion of request. This adds a bit of an overhead to the write operation but when combined with Read Through pattern it gives a lot of benefits. The write through pattern ensures that entries in the cache are not out-dated or stale. So we have consistent data available at very high speeds for reads. This is great for a cache.\nEven with the Cache Aside pattern, we generally employ a similar approach to read through and write through. The difference is of course that the service controls the entire interaction rather the cache system.\nWrite-Around Write-Around Cache is a slightly different from the older one. Here the write happens only to the database and the cache is updated only during a read through. There are some advantages - writes are faster but at the same time they are durable (since db is written). But reads could miss cache or even return stale data. This approach is great for write heavy workloads where reads are much less - e.g. is real time logs.\nWrite-Back or Write-Behind Write-Back or Write-Behind Cache is another variation. Here the service writes to the cache and returns. The cache will write to the DB behind the scenes with some potential delay. Of course writes are super-fast but there are chances of missed writes too. Combined with read through, you get a good cache times for most mixed workloads - you always have the recently updated and accessed data. Also one can argue that it is resilient to db failures - (but how long? - keep that in mind). Another thing possible is that multiple writes to the same object could be coalesced into one write to the db.\nAs I said earlier these are general patterns which have trade-offs. And they are always combined. In my own opinion, treating a cache as a data source is rarely a good idea. Unless you have throwaway data or what you holding is always derived reconstructable data. If not stick to the more durable write patterns always. How Long to Cache - Invalidation We are now embarking on the one of toughest problems in computer science! (referred already). In my experience this is a true statement.\nAny cache we create is an alternate store of data and cache is not the source. That means it is bound to go out of sync with the source. This is called as going stale. Unlike stale food, stale data from cache is not always bad. That said we can’t keep having stale data and serve our clients with the same. How long we can use stale data depends on your business scenario.\nNews sites with stories could show some stale data - slightly older news - may be few hours. But a stock ticker like app which enables users to trade cannot real work with stale data! So it depends.\nLet us figure out how to get out of this stale state.\nExpiry One of the ways to deal with staleness is expiry. Depending on the data you are trying to cache, you generally know how long the data can remain fresh and live. If so, we can set the data to expire. This is generally called Time To Live or ttl. Most caching frameworks will drop the data once it passes ttl - either actively or passively. A request for this expired data will result in a cache miss. The next step depends on the caching patterns you use. Many caching frameworks allow us to set this expiry at the bucket level (all new stories) as well as individual item (a particular new story) level - we can use any as required.\nService based While expiration is a reasonable way of handling invalidation, we could handle it more actively. When we use caching within a service boundary, a service has control over the data which it is caching and hence can actively manage the invalidation of stale data. For example when more comments are added to a document, the change happens through the service and it can actively manage the cache invalidation. This is one of the reasons I prefer the service based approach.\nEvents based Another way invalidation can be achieved is through events. This technique is especially applicable when orchestration service clients cache mashed up data. When the object owner service finds that data has changed, it sends out an event to an event bus or MOM. This is consumed by the orchestration service to take appropriate action.\nTwo more concepts on Caching Measurements Anything we do, we should measure. There is a saying in Tamil\nஆற்றில் போட்டாலும் அளந்து போடு\nEven when you are just going to throw something into the river you should measure and throw it.\nOne of the critical measurements for any caching setup is the cache hit ratio. Every one understands what a cache hit is - when a cache access succeeds. And a cache miss when you miss. So cache hit ratio is:\nCache Hit Ratio = Cache Hit / (Cache Hit + Cache Miss) For caching to be considered effective, the data cached must have a good cache hit ratio. If you have a low cache hit ratio then you are surely doing something wrong. Either you are using the wrong cache patterns or you are caching the wrong data. Any changes you want to do related to caching (change methods/techniques or something else) must keep the cache hit ratio in mind. Any change reducing the cache hit ratio is a bad idea.\nEviction We talked about expiry a lot. There is another concept which people consider closely related to it - Eviction. Actually eviction is very different from Expiry. It has more connection to the cache hit ratio and what to cache question. Both expiry and eviction deal with removal of entries, but their causes and purposes are completely different.\nCache eviction comes into play because memory is a finite resource - for the most part that is. While I would love to cache the entire database it is just not economical to do it. So once the amount we cache exceeds a number limit or memory limit, any addition of entry means some other entry needs to be removed out of memory. This process is called eviction. Eviction is generally done based on some algorithmic strategy. Different caching frameworks provide many different algorithms. The most common ones are LRU, LFU, FIFO.\nLRU is the most common is generally considered a reasonable default. It is considered a close proxy to the most optimal caching algorithm. The specific reason is due to Locality of reference. This is easily explained in the context of caching at the CPU level where the recently used data or instruction is repeatedly requested by the CPU. This is called Temporal Locality. The same phenomenon applies to the real world usage of cached data too. We can understand this intuitively. For example most times when data is created it is immediately accessed. Also when real users surf through data like products they tend to return to see the same products again and again. Another example is generally items like dresses or vehicles come into trend in time cycles (or may be because there is a big sale going on). Temporal locality makes sense. In my experience of using caches, I have never needed to change the eviction algorithm to something else. Nor have I heard of any real life usage of any other algorithm - that is anecdotal for sure but I am pretty convinced.\nChanging a caching algorithm to something else is mostly a configuration change. The more important thing is, when we make such a change, we need to measure cache hit ratios and average response times and see how they are affected.\nConclusion - Summary of Opinions Preferred Approach - Service Caching\nI prefer to use service managed caches as an approach to caching. Given that service owns the data, as a service developer I have a much clearer understanding of how and when data changes and hence I can make decisions more easily. With this approach clients are unaware of what is happening and hence they are not affected by any changes to mode/mechanism of caching. I can keep tweaking the implementation as long as I satisfy the performance SLA. I can keep improving performance or scale without having clients to have to change anything. A service can internally use in process caching or stand alone caching to begin with and then move to an IMDG as it needs more scale. All good right!\nBut you sometimes need - Orchestrator/Client side caching\nNot really. Service level caching does not solve all scenarios. Clients sometimes want even better response times than what service level caching can provide. Network latency could be one reason. I generally don’t really think it is a great argument since once you want to scale the client you would need an out of process cache and then the network latency is back. But that is not the only reason. There are situations where client services mash up data from multiple services and do some processing on top and use it. In such cases it might be required for that service to cache the outcome of the processing to quickly serve clients. I have done the same in one of previous situations because it was needed to meet the SLA for the service - to keep real users happy. Though this approach is sometimes required, we must understand that it is a complex thing to manage. We need to build in checks which will ensure that this cache data still ties back to original data source services - potentially an event based mechasim.\n** Never ever Shared Caches**\nOne of ways which I have seen caching being used is like a blackboard where some service can write something and another service can read the same. This is possible to do but I am not in favour of it. This feels very much like multiple services using the same underlying database - a global namespace. Any change cannot be done in an isolated manner and every service can touch or be touched by all changes happening on the shared cache. So beware of it. I am not saying that this cannot be done. It feels more dirty and complicated and hence can turn ugly if we are not very careful.\n** And not really a replacement to DB**\nAnd last piece of advice or opinion. Never treat your cache as your database even if it super reliable with great clustering features. Some IMDG vendors say that it is possible. In my experience that is not what they are good at and hence they don’t work well as good persistent stores.\nI am done. Share your thoughts or questions through comments below.\nFor related microservices reading: The Right size of a µService? explores the architectural forces that determine how big or small a service should be, and µservices gossip: Take a timeout! covers another key resilience pattern — timeouts — through a fun fictional conversation.\n","date":"2019-09-15T00:00:00Z","permalink":"/caching-in-microservices.html","title":"Caching in Microservices"},{"content":"Nginx is one of the projects which I always felt a pull towards, owing to it architecture. It is \u0026ldquo;event driven\u0026rdquo;!. For some time, I have heard this but I always wanted to get more deeper into it. So I did some digging on how nginx works. I read many articles (will be referred below) and pieced it together to the best of my understanding. Here is my attempt to explain how I think it works!\nOf course take this with generous helping of salt:\nI don\u0026rsquo;t have much knowledge on linux internals and syscalls - so whatever I describe is surely going to have faults/mistakes. I look forward to get help from others to correct it. Another reason is that I did not go through the nginx source code. I don\u0026rsquo;t have expertise in C and I am too scared to peep into nginx codebase for the fear of getting completely lost. Now that is out of the way let us get started. If you want the basics of getting nginx running first, see Setting up a nginx virtual host on Ubuntu.\nBackground - Process Roles Okay. Before we get started let us get some background on the nginx processes.\nNginx follows an event driven architecture and has different types of processes doing specific kinds of tasks. Let me first describe these process type and their roles. Once that is out of the way, I can get to more details on how the nginx startup and processes requests.\nThe four different kinds of processes are:\nMaster The master process is what starts up and manages the lifecycle of all nginx processes.\nWorker This is the work horse of nginx. This process is the one which does all processing for client requests. Reverse proxying, load balancing, compression, ssl termination etc. are all done by this process. Generally there could more than one of these processes running at any given time.\nCache related processes Cache loader process This process checks the on-disk cache items and populates nginx in-memory db with cache metadata. It prepares nginx to work with files already cached and exits after updating in-memory db Cache manager process This process manages cache expiration and invalidation. It stays in memory. That should be enough background. Let us deep dive into how nginx starts and processes requests. For this discussion the processes under focus are only the master and the worker processes.\nSee it yourselves If you want to see these processes in action. Do the following (assuming you have done the installation): Open a terminal/shell and execute\n:::shell watch -n 1 \u0026quot;sudo ps -eFww --forest | grep 'nginx\\|PID'\u0026quot; In another terminal execute\n:::shell sudo nginx You can drop the sudo if your nginx does not have reserved ports configured for listening.\nOnce you start nginx, you should see the processes in the first terminal window. Keep watching it for sometime (you might notice something).\nNginx startup You start nginx by calling nginx. Let us look at what each of the main processes do at this point\nThe Master (A true leader/delegator) The first process to start is the master process. It first reads through, validates and compiles the configuration. Once the configuration is validated and compiled, it looks at the configuration to figure out what all listen sockets have to be created for serving client requests.\nThe server connection establishment process starts at this point for the required listen sockets. As a server (role played in client server communication), the master first tries to create sockets and bind to the ports defined in the configuration. One thing to note is that if the defined ports belong to the reserved set, the nginx needs to be started as a privileged user (root/sudo). Once the socket is created and binded it will also set the socket to listen mode with a default backlog of 511 (read more about listen backlog from references).\nThe next step the nginx master does is to start the worker processes. This is typically done by forking (clone) them out as a child process (this is my assumption/understanding). This also means that listen sockets descriptors are copied over to the child processes and are hence accessible to the workers. The compiled configuration is also passed onto the them. The number of worker processes to be created is based on configuration. The typical default is auto which leads to the creation as many workers as there are cores in the machine (or VM).\nThe Worker (I am awake!) Each worker creates a epoll data structure with the kernel (using epoll_create). It then registers the listen socket descriptor to it using epoll_ctl and asks the kernel to let it know if there are any events (read or write) on the listen socket(s). All the different workers have access to the listen socket and they concurrently share the requests coming to them. Eventually if the worker has no other work to do it would block using epoll_wait.\nEach of the workers also create non-blocking connection sockets to upstream servers so that they can act as proxies to them. This also is event based and hence based on epoll.\nNginx processing requests Now that nginx has started, it is time to process requests.\nThe Master (time to sleep) At this point the master pretty much does nothing. It does not have any work to do during the time of processing requests.\nThe Worker (A superstar) When a new client connection request comes to the listen socket, the linux kernel will pick the latest added worker process among epoll those waiting in the listen queue and send an event.\nThis worker process would then do a non-blocking accept call which will create a connection socket between the client and server. This connection is now going to be served by this worker process. The worker does the same thing with the connection socket as it did with the listen socket. It registers interest on IO events happening on that socket through epoll_ctl and waits for events with epoll_wait if it has no other work to do.\nOver a period of time you will find that a worker process ends up serving many connections at the same time. Each of these connections are registered within their (worker\u0026rsquo;s) own epoll data structure. At the end of epoll_wait, the worker might get multiple sockets which are ready for processing. It then processes each of those requests. Processing of incoming request might include acting as a reverse proxy (write out the request to upstream server), do ssl termination etc. On the other hand processing of the response could be compressing the response read from the up stream server (again this is event based using epoll), and write out the response to the client again in non-blocking fashion. The worker is the one which exhibits all the wonderful features of nginx.\nThe worker processes do not use epoll based asynchronous IO for files. For files it does blocking IO in most cases. If AIO is well supported in a platform it might use the same. But generally file IO slowness can lead to blocking behavior in the worker (and hence nginx).\nSee the worker in action Do you want to see the workers in action? Go ahead and watch the connections using the following command:\n:::shell watch -n 1 \u0026quot;sudo netstat -npt | grep :80\u0026quot; With that watch running go ahead and hit your nginx server using ab or something similar. You should see the connections swelling up. Of course I have assumed here that the port nginx is listening to is 80. Change it according to your setup.\nWhat is all this fuss about! Nginx does all this to provide high scalability.\nThe worker\u0026rsquo;s power A nginx worker can process 1000s of connections at the same time because of its non-blocking event based nature. Because of this nature, the cost per new connection in nginx is a matter of space for a new file descriptor and data structures needed to manage that socket\u0026rsquo;s information. This is unlike other servers which have a process driven architecture (apache) which needs to allocate much more memory due to creation of process (stack and heap).\nAlso the creation of limited number of worker processes in nginx means they can remain pinned to the cpu cores and avoid excessive context switching.\nBut then it is not all roses Earlier I mentioned that the linux kernel keeps picking up the latest added process to distribute connection requests coming into the listen sockets, it happens that one of the workers get the lion share of the work load and hence the multi-core usage becomes skewed - more on one process. You will find more information in one of the articles in the references section.\nThe master strikes back. From the above it looks like the worker is the only star and master is just sleeping. But the sleeping giant plays an important role in keeping nginx running when reloading configuration changes or even doing a nginx binary upgrade. You can find out more about this in the articles in references.\nConclusion As I said earlier, what I have tried here is to give an overview of how nginx goes about serving its clients at a slightly more detail level. I have used the following references as a way to understand most of this. And of course I might have got some of the connecting pieces wrong. If anybody can find these gaps please chime in. Thanks for being here!\nReferences Inside NGINX: How We Designed for Performance \u0026amp; Scale - Gives a good idea on Nginx architecture. Also covers how the master is able to handle config changes or binary upgrades without downtime. Nginx Tutorial #1: Basic Concepts - Just basic idea on running nginx and some basic configuration nginx - A deep dive on nginx architecture by one of nginx architects Tuning NGINX for Performance - Gives you ideas for improving nginx performance Know your TCP system call sequences - A general article covering system calls related to TCP connection creation and management. Covers listen backlog too. Why does one NGINX worker take all the load? - This article talks about how it happens that one nginx worker ends up getting a lot more load than others and what you can potentially do about it. The method to epoll’s madness - A good article on how epoll works. Does Nginx block on file IO? - A discussion thread on how nginx file reading works. Sysdig - This is what I used for determining those sys calls that were happening on each of the processes under different conditions. ","date":"2018-03-31T00:00:00Z","permalink":"/nginx-working-deepdive.html","title":"Nginx Serves Us like this - Maybe"},{"content":"Ok. I did say that I will bring the next installment quickly (you can find the previous one here) But my life and me got in the way. But, better late than never.\nPodcasts Set 2 - The Software Developer\u0026rsquo;s Topper List This set of podcasts are focused on software development, open source software and technology related. I listen to a good number of such shows and in this installment I am going to share my top three picks. Hopefully I will follow up with more!\nSoftware Engineering Radio Software Engineering Radio, as the name suggests, is focused on Software engineering. I would say it is a must listen for professional developers. The topics covered vary from software engineering related topics - agile, continuous delivery, architecture related and open source frameworks. The discussion is very technical in nature (some of the most technical discussions I have heard on a podcast) but it still tries to give the listener a good overview of the subject. The discussions are reasonably long (around 45 - 60 minutes), so there is time to explore the topic to some extent. The guests are mostly leaders in the field and/or head honchos of the open source projects that is being discussed. The hosts are a team of developers themselves (some of them very renowned in their own right) and help the steer the discussion so that it is developer focused.\nSome of the recent topics I have listened to are Apache Storm, Continuous Delivery, Logging infrastructure, CQRS, Kafka etc. Recently these shows have become more frequent as well (hope it stays that way). If you are a developer and want to try podcast listening, this one is something you would want to start with.\nThe Cloudcast The Cloudcast started as a cloud technologies podcast. At that time, lots of coverage used to be on Cloud platform vendors and products out there. But close to an year back, they have started focusing a lot on open source projects on cloud and distributed computing and devops related topics. These podcasts are generally short and to the point. The hosts try not get into a lot of depth but try to get the guests to provide high level but useful information and more importantly trends. Recently they have added byte sized versions of the podcast which provide very short introductions of dev and devops topics. You might find those specific ones either useful or trivial.\nI primarily find the podcast discussions providing me a lot of breadth of knowledge in the space. The hosts are really good too. Brian is very sharp and to the point. Aaron on the other hand brings more fun and cheer. Overall a very good podcast to listen to for the topics they cover.\nFloss Weekly Floss Weekly is a podcast focused on free and open source software. This is one of the oldest shows in the podcasting planet. The nature of projects could vary a lot in this podcast. I have discovered a desktop software for controlling multiple computers using a single keyboard and mouse to a platform which made Kenyan elections better through this podcast. It is this variety which draws me to it. The primary criteria of projects participating in it is about them being open source.\nThe hosts don\u0026rsquo;t get as technical as the other two shows (except for Randal at times), but the show provides a well rounded overview of the project. There is considerable discussion on open source licensing and governance which I don\u0026rsquo;t find in other shows. And that is something I like to get exposed to. So if you are into open source in general and like variety, this is a good podcast to listen to.\nDone! This is a short one. The top three are out, but there is more to come. I will get them out sooner than later.\n","date":"2015-05-04T00:00:00Z","permalink":"/thou-shall-listen-to-podcasts-part-2.html","title":"Thou shall listen to Podcasts - Part II"},{"content":"I listen to a lot of podcasts. I really can\u0026rsquo;t remember how it started but getting my smart phone (about 4 years back) is what triggered it. I have listened to a lot of them and found them useful, entertaining, informative and fun. Some of these podcasters even feel like long time friends. Ok, that might be pushing it, but at times I do feel a sort of allegiance and loyalty to them.\nWhy Podcasts? Objectively, I feel podcasts can act as a good source of information/knowledge which can consumed in a passive manner. I listen to podcasts mostly when I am commuting or exercising (walking!). There are podcasts for almost every topic you can think of. I am primarily focused on technology, software development and startup related podcasts but I know there are a lot more available. While there are podcasts directories which you can use to locate podcasts, I find my podcasts from podcatchers, itunes and from other podcasts (and of course do googling for getting the rss feed link). Most of the podcasts I listen to are produced in the US (wish I could find more from India!!!). That said, they provide a lot of value from my perspective.\nShare the goodness Since I find it so useful, I thought it would be good to share them with others. I initially thought of just creating a list of all of them and throw it out there. But somehow I felt that was too vanilla. Then I thought of creating a top 10 list but that felt cheesy initially. When I thought more about it and I felt it might be useful for figuring out my own preferences and likings and my ability to judge things. So I attempted to make an objective score for some of the really good podcasts (as per my taste) which I listen to. Only to realize that it is damn difficult to make it objective. So I gave up on that. Finally decided to create a set of subjective groups of podcasts I listen to and share them with you all.\nPodcasts Set 1 - Distinctive and Fresh I am starting this series with a set of podcasts which I feel have a very distinctive nature. The content they provide (most times) is perceptive and opens your mind to a lot of different thoughts and ideas. Listening to them makes you think, smile and sometimes be amazed. Let us get on with it.\nSpark Spark, in Nora\u0026rsquo;s words, is a podcast about tech trends and fresh ideas. And I couldn\u0026rsquo;t describe it any better. Nora is the anchor of the show. The podcast is set as a conversation with the listener. Nora makes the listener a part of the journey in which she meets remarkable people and has very deliberate and pleasant conversation with them. These people look at tech in different ways - either to solve problems or just to understand different things. The podcast brings innovative stories on tech trends and how technology affects people and culture. It brings up simple life hacks and cool new ideas. And it is really produced well (it is a radio show by CBC). The show is done regularly. The music is done well and it connects the various parts of the show nicely. There is a scent of art and creation in the podcast which appeals to creative spirit in us developers (at least I would like to think that :)). It leaves you with an enriched and fresh feeling most of the times.\nHanselminutes Hanselminutes is a podcast produced by Scott Hanselman. This podcast historically was a .NET developer podcast. But for quite a long time (at least from the time I have been listening), it has not had that focus at all. There are some shows related to .NET for sure. At the same time there are shows on Python, Javascript, Dart, Java etc. as well. Actually forget the programming languages. This guy produces shows on UX, game development, startups, relationships, developer culture, diabetes technologies, iphones etc. Almost anything under the sun - the difference is that he looks at it from an eye of a developer and problem solver. Also, he always will try to NOT make any assumptions on what the listener might know about the topic. He will get the guest to explain the topic without the listener getting lost on jargon speak. The discussion is never long, but whatever is talked would make sense to you and that nugget is something you can carry with you. The way he goes about the discussion is engaging and simple. He does not try to be funny or anything. Just genuine good conversation. The wide variety of topics which he covers makes it very appealing to me. And he is very very regular. So you can expect some interesting conversation every week. Though I have never met him personally, the show sort of makes me feel that I know him somewhat. And he is an open source supporter too!!!\nCognicast Cognicast is a podcast produced by Cognitect and is hosted by Craig Andera. This is relatively new podcast and leans towards Clojure related topics (since Cognitect is Clojure focused - Rich Hickey is the CTO for crying out loud!). Now I am not a Clojure guy at all but I like the functional leanings of the topics. That said, this podcast is also modeled in the lines of hanselminutes. Apart from technical topics, it covers other kinds of topics as well. Craig keeps the conversation nice and cordial. One of the great things he does is that he allows the guest to flow with what they want to talk and get the maximum out of them. He might nudge them a little here and there but allows them to take the limelight almost completely. Very nice and humble all the time. Some of the discussions I have heard have truly blown my mind. That is why even when there are many clojure heavy discussions on the show, I still listen to them since I get at least something out of it. Another novel part of the show is that allows you to sample lots of different music. The show is young but I find it enjoyable, thought provoking and fresh. I hope Craig keeps going that way.\nUpdate on 3-May-2015: The music sampling part of the show got stopped from this year (2015) onwards.\nThat is the first batch out. The next installment is ready — head over to Part II for more podcast recommendations.\n","date":"2015-01-31T00:00:00Z","permalink":"/thou-shall-listen-to-podcasts-part-1.html","title":"Thou shall listen to Podcasts - Part I"},{"content":"I have been spending some of my free time on working on a personal project. As part of that, I needed to figure out how can we show visualizations of my data - yep charting. To give you some background, I am playing with angular js for this application and using a python based backend. Since I wanted to have a dynamic visualization - with animations and interactions thrown around, I decided to use a client side charting library that takes in the data and does the visualization entirely on the browser. Another thing I wanted to do was to see if I could use the same code or parts of it for delivering visualizations to the mobile.\nD3 Enters Given its immense popularity and its ability to work with svg based visualization (which I felt would work better for supporting multiple devices - of course that may not be true), I gravitated to D3. I got to the D3 site and I found so many cool looking visualizations that I was just blown away (I bet you will have the same feeling). Of course almost none of them made much sense to me. I wanted to use some simple visualizations like bar charts, line charts etc. and they were of course available on D3.\nBut I am building an Angular app. Also I was lazy. I wanted to figure out if there is a pain less way to get these charts integrated into my angular app. The immediate thought was to figure out if there are any angular directives.\nAngular Directives and NVD3 to the rescue So I googled it. And lo and behold there was an entire page talking about it. After some digging around I settled on two of them - angular-nvd3 and angularjs-nvd3-directives. Both of these directive libraries leverage nvd3 underneath which itself was built on d3 (Wow! A layer above a layer above the actual thing). While both of them seemed promising to me, I somehow settled on the second one. I remember my reasons at that time were that I liked the declarative nature of the directive (I am not sure if I like that still) and that it was around for longer time (which I still think is sensible).\nThat was a simple bar chart (look at the various bar colors!!!) and I followed that with a simple line chart\nSo my immediate needs were taken care and everything was perfect. I cooked up some bar charts, line chart and even some pie charts. I tweaked some colors and axis layout through the directive provided support. All was going well. Of course, in all the tweaking I was doing (colors, date formats), I sometimes needed to get some insight into d3.js itself. But that was very minimal.\nThings change, We want more I had taken a short detour into the world of statistics earlier. So I always liked the concepts of median and percentiles. So I wanted to figure out if there is a way to depict that in a visualization. My friend then introduced me to the box plot. I won\u0026rsquo;t go into the details of box plot here. There is good reference material on that on the internet.\nSo my mind was set on the box plot and I wanted to figure out how I can create a visualization for it. The angularjs-nvd3-directives did not have any support for them. Neither did nvd3. So I looked directly at d3 and there was an example and the associated plug-in code available for it.\nMy idea of living on top of the abstraction (actually an abstraction over abstraction) no longer worked. I had no choice.\nGetting my feet wet into D3 I initially thought I would try to create a nvd3 based box plot but I realized that it is going to take a lot of time figuring out nvd3 when I did not even know much about d3.\nSo I tried to figure out some basic concepts of d3 so that I understand the plug-in code. First and foremost I understood the concept of selection and mapping the selection with data. Also got an understanding of scales. This helped me understand the plug-in code. But that was not enough. I needed to figure out how I can integrate d3 with my angular app. Again there was example readily available. A simple directive would do the trick and I created a box plot using the same.\nTweaking the box plot I started getting interested in the box plot code itself. First thing I realized was that the box plot code in its current form (inside the plug-in) took a lot of horizontal space as you increase the number of plots. This may not work very well when you don\u0026rsquo;t have a lot horizontal space (read mobile device). So I figured I needed to tweak the box plot to support a change in orientation.\nThe second thing I wanted to do was to figure out a way to show labels close to my plots to indicate what they are plotting.\nAnother thing I noticed was that the outliers plotted by the box plot could skew up your graph quite a lot if you have really high outlier values. So I felt it would be good to have a way to turn it off. That is another thing I wanted to tweak.\nAnd that is what I did. You can find my code in plunker.\nThe Road forward The plnkr code is still not the cleanest. I have done some ugly hacks to make it look reasonable. It is available publicly. If anybody wants to tweak it and make it better (and teach me in the process), that would be fantastic. Also, I have still not been able to make my changed box plot work with my angular directive reliably. That is something I would surely like to fix. If I do I will share that code.\nOn the library side, I want to figure out if I can find a better abstraction over d3 which is simple to use. d3 is good but it is very literal and low level in its nature (which is by design from what I understand and hence gives it a lot of power to do new things!). I don\u0026rsquo;t know whether nvd3 is that abstraction. May be it is and I will find out more about it. There seem to be other alternatives as well. Also for the mobile, I am not sure whether the d3 way would be the best fit - I somehow do not feel so (anybody can correct me!!!).\nLibraries aside, I feel visualization is a field to really get a good handle on. To use a cliche - A picture is 1000 times better than words (or was it a picture is better than 1000 words\u0026hellip; either way) - good visualization can be very powerful. I think a more deeper study on visualization will be very useful to me. Hopefully I can go down that path and do something worthwhile!\n","date":"2014-12-21T00:00:00Z","permalink":"/my-journey-starts-at-the-box.html","title":"Journey starts at the Box"},{"content":"For a long time, I have been focused on Java as my primary development language (and platform) for both my work and any of my small personal projects. But I have been playing with Python for more than 6 months now. The reason I picked Python, is a discussion for another day. Currently I want to focus on couple of things which I found to be weird with Python.\nBefore I get into that, let me make myself clear. My relationship with Python is very young and my perspective comes from a long time Java exposure and a limited exposure to other languages (read Javascript and very very little bit of Haskell). Also, within this short time with Python, I find the language as a breath of fresh air. I find it to be much more concise than what I am used to (think Java). It is really powerful. I am getting a taste of it\u0026rsquo;s dynamic nature as well. These qualities of Python are well known to all and I will probably write about my impressions on specific features sometime down the line. But today I wanted to focus on couple of specific language features I found to be slightly weird in their working.\nAugmented Assignment The term might sound a bit fancy (that is what I felt when I read it), but the construct is pretty simple and probably known to all programmers (of almost any language).\n:::python a = 0 a += 1 You must have spotted the augmented assignment operator! Yep, it is += . Of course there are other similar ones like -= , *= etc. The form a += 1 is generally a shortcut of a = a + 1 . In Python also it works the same way. At least that is what I thought.\nLet us try using the augmented assignment operator with list concatenation:\n:::python \u0026gt;\u0026gt;\u0026gt; A = [1,2,3,4] \u0026gt;\u0026gt;\u0026gt; B = [5,6,7] \u0026gt;\u0026gt;\u0026gt; A = A + B \u0026gt;\u0026gt;\u0026gt; A [1, 2, 3, 4, 5, 6, 7] \u0026gt;\u0026gt;\u0026gt; A = [1,2,3,4] \u0026gt;\u0026gt;\u0026gt; B = [5,6,7] \u0026gt;\u0026gt;\u0026gt; A += B \u0026gt;\u0026gt;\u0026gt; A [1, 2, 3, 4, 5, 6, 7] \u0026gt;\u0026gt;\u0026gt; That works as expected. So I should be able to reliably use the augmented assignment operator instead of the longer form. Let us try something else now.\n:::python \u0026gt;\u0026gt;\u0026gt; A = [1,2,3,4] \u0026gt;\u0026gt;\u0026gt; B = [5,6,7] \u0026gt;\u0026gt;\u0026gt; C = A # Why am I doing this? Wait for it. \u0026gt;\u0026gt;\u0026gt; A = A + B \u0026gt;\u0026gt;\u0026gt; A [1, 2, 3, 4, 5, 6, 7] \u0026gt;\u0026gt;\u0026gt; C [1, 2, 3, 4] This makes sense to me. The concatenation operator + creates a new object and assigns to A. And \u0026lsquo;C\u0026rsquo; keeps pointing to the older object. This is all good and working as expected. Let us change the above using the augmented assignment operator instead.\n:::python \u0026gt;\u0026gt;\u0026gt; A = [1,2,3,4] \u0026gt;\u0026gt;\u0026gt; B = [5,6,7] \u0026gt;\u0026gt;\u0026gt; C = A \u0026gt;\u0026gt;\u0026gt; A += B # Here I have used the augmented assignment version \u0026gt;\u0026gt;\u0026gt; A [1, 2, 3, 4, 5, 6, 7] \u0026gt;\u0026gt;\u0026gt; C [1, 2, 3, 4, 5, 6, 7] ????####!!!!. What happened here? Something happened. How did it change? What did I change? The only change I made from the previous listing is that I used augmented assignment. But that changed how things work. Concatenation no longer creates a new object. It mutates the assigned object in place!!!!\nThat is weird to me! I figured that it is Python trying to optimize since the list is a mutable object in Python. But somehow it feels unclean, because it seems to break a promise. To a long term Python programmer, this may not be weird at all. But to me, it felt out of character to how generally Python works - predictable and explicit. It might just be my own (mis)interpretation, but it feels weird.\nBoolean Operations I am referring to the and and or operators. In Python they mean exactly what they say. The and refers to \u0026amp;\u0026amp; (conjunction) in other languages like Java and or refers to || (disjunction) in other languages. In most other languages, using these operators leads to boolean results. By not in Python! These operators return one of the objects which is an outcome of the corresponding expression. One of the underlying principles behind this is Python\u0026rsquo;s concept of truth values. Let me illustrate this with some examples:\n:::python \u0026gt;\u0026gt;\u0026gt; \u0026quot;\u0026quot; and 23 '' \u0026gt;\u0026gt;\u0026gt; \u0026quot;add\u0026quot; and \u0026quot;subtract\u0026quot; 'subtract' \u0026gt;\u0026gt;\u0026gt; \u0026quot;\u0026quot; or 23 23 \u0026gt;\u0026gt;\u0026gt; \u0026quot;add\u0026quot; or \u0026quot;subtract\u0026quot; 'add' In all these examples, you see that and and or are not returning any booleans. They work based on truth value concepts of Python and return the objects involved as per the truth value rules. Let us see its usage below:\n:::python \u0026gt;\u0026gt;\u0026gt; def calc_simple_interest(principal, rate, tenure): ... p = principal if principal else 0 ... r = rate if rate else 10 ... t = tenure if tenure else 5 ... print(\u0026quot;Returning interest for %d at %d percent for %d years\u0026quot; % (p,r,t)) ... return p * (r/100) * t ... \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,5,3) Returning interest for 1000 at 5 percent for 3 years 150.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,0,0) Returning interest for 1000 at 10 percent for 5 years 500.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,8,0) Returning interest for 1000 at 8 percent for 5 years 400.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,8,None) Returning interest for 1000 at 8 percent for 5 years 400.0 The above example is a convoluted and contrived way to handle default values (since Python has function argument defaults). But to somebody reading through that code, it still makes reasonable sense. Now let me change it.\n:::python \u0026gt;\u0026gt;\u0026gt; def calc_simple_interest(principal, rate, tenure): ... p = principal or 0 ... r = rate or 10 ... t = tenure or 5 ... print(\u0026quot;Returning interest for %d at %d percent for %d years\u0026quot; % (p,r,t)) ... return p * (r/100) * t ... \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,5,3) Returning interest for 1000 at 5 percent for 3 years 150.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,0,0) Returning interest for 1000 at 10 percent for 5 years 500.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,8,0) Returning interest for 1000 at 8 percent for 5 years 400.0 \u0026gt;\u0026gt;\u0026gt; calc_simple_interest(1000,8,None) Returning interest for 1000 at 8 percent for 5 years 400.0 \u0026gt;\u0026gt;\u0026gt; Now that is Python\u0026rsquo;s or operator working its way to give us the exact same behavior as the \u0026rsquo;ternary if\u0026rsquo; used before.\nThe way the logical operators work in Python felt weird to me. But I did not feel very unclean about it like the last one. It just was different.\nIn Closing These are two cases where I felt Python to be slightly weird in its ways. There might be others and may be I will find them down the line (and I will share them if I do).\nThough I have highlighted what I felt weird about Python, it does not mean that I don\u0026rsquo;t like the language. On the contrary, I actually like it quite a lot. But just like anything/anybody who you like/love a lot has some small imperfections, so does Python. In fact, it is those imperfections which make them unique and differentiated to us. That is what this does to Python too.\n","date":"2014-11-16T00:00:00Z","permalink":"/python-can-be-weird.html","title":"Python can be weird!"},{"content":"For close to 2 years (the time since I got the domain), I had married myself to Google sites for my own blog and site. It was not a happy marriage. While it might have worked for others, the inherent inability to change anything or use any of the good tools out there, for my content creation did not give me any comfort. I tried hard to use what is provided and finally gave up. I decided that, may be having my own site is really not worth it.\nGithub Pages For sometime, I have been hearing about Github pages, but never thought too much about it. Then I got chatting with one of my friends and he talked about using Github pages with Octopress as the content management system for his blog. This really piqued my interest and I decided that I would give it a go.\nSo I went through the documentation of github pages and figured out how to create a user site and put a place holder page in it.\nIt was not great but it was a start. I used bootstrap for the css and used some basic elements on the page.\nI also made my domain point to it. It took a day (may be two) for the dns records to get updated and viola! my new site was up. I had finally broken the shackles and escaped from the tyranny of Google sites. My new journey had begun.\nPelican Now my friend had talked about using octopress for his blog. I felt that using a static file based content management system was surely a good idea but I wanted to use a python based one instead of a ruby one. A quick search lead me to Pelican.\nPelican seemed to fit my bill. I could use markdown (which was another thing I meant to learn) to get my content. Pelican documentation looked pretty good and it was easy to get started. There was a good amount of configurability in Pelican. Also there was support for themes and plugins (which is python based and that looks interesting to me). The available collection of ready made themes seemed reasonable and I picked the bootstrap 3 based one called pelican-bootstrap3 from Daan. This post is written on this base setup. I am still to add any plugins to the site but that can wait.\nI wanted to get started. And now I have!\n","date":"2014-11-04T00:00:00Z","permalink":"/move-to-github-pages-and-pelican.html","title":"Bye! Google Sites, Hello! Github pages"},{"content":"I had heard of nginx as a very good web server from the perspective of performance. So I decided to try it out for one of my learning endeavors.\nInstallation Installation of nginx on my Ubuntu was a breeze. Nginx is available as part of the Ubuntu distribution from Canonical. So I could just search the Ubuntu Software Center and install it on my machine. Once installed, starting and stopping the nginx server is simple. Just open the terminal, and use the following commands\nsudo nginx (starts the server) sudo nginx -s quit (stops the server) sudo nginx -h (provides basic usage help) One thing to notice is that you have to execute these commands with superuser privileges (sudo).\nSetting up the virtual host Being able to run the nginx server is all good. But for me to use it, I needed a virtual host where I can put my development site\u0026rsquo;s content.\nUsing the readily available and trusted resource, I reached a link which talked about this. After reading the same and some experimentation, I was able to set the virtual host. Below is a brief description of the steps which I followed:\nFolder Structure Once nginx is set up, you find the following folder where definitions of the virtual hosts are kept:\n/etc/nginx/ The folder structure is as depicted below:\nThe important folders for our discussion are sites-available and sites-enabled. For all sites which are to be hosted by nginx inside the current machine, an entry needs to be made inside the sites-available folder. A file needs to be created which holds the configuration and the name of file is the domain name. For example, I can create a file - ex.nacnez.com which represents the domain name using which the virtual host can be accessed. The contents of the configuration file are as follows (remember this is just the basic stuff - more configuration is possible but for setting up the virtual host this is good enough):\nserver { listen 80; server_name example.nacnez.com; access_log /home/your/docroot/basepath/ex.nacnez.com/log/access.log; error_log /home/your/docroot/basepath/ex.nacnez.com/log/error.log; location / { root /home/your/docroot/basepath/ex.nacnez.com/public/; index index.html; } } Here /home/your/docroot/basepath means the base path under which you want to store your site and its document root folders.\nSetting up the actual document root The contents of your site is generally placed under its document root folder.\nIf you look at the configuration above you can understand where the document root of your site is placed. Under the public folder is where your index file (index.html as per the above configuration and which could contain any HTML content) and other website artifacts go. Anybody accessing your web server through the above domain (of course there is more work to be done for that) is taken to this folder. The log folder is used to store logs like access and error logs. There are a couple of other folders (private and backup) but they are not used for simple setups (and I don\u0026rsquo;t even know how they are going to be used - may be something for a future post).\nEnabling the virtual host Though the configuration file has been created inside the sites-available folder, the nginx server still does not serve the pages of this site yet. For enabling this, one needs to create a soft link to the config file inside the sites-enabled folder.\nsudo ln -s /etc/nginx/sites-available/ex.nacnez.com /etc/nginx/sites-enabled/ex.nacnez.com This enables the site on nginx. Once you restart nginx ideally this site should be available.\nSetting up the hosts file The last important step is to ensure that the hostname is configured in the DNS server to point to your machine. Since I was using it just for my local development, I went ahead and configured my /etc/hosts file.\n127.0.0.1 ex.nacnez.com Once this is done, we are all set. If you crank up the browser and type in the domain name you must get the content of your index page.\nThis was my first encounter with nginx. This was enough for me for my current use of nginx. Hopefully I will get pushed to learn more on nginx and that should be fun. I did get pushed — see Nginx Serves Us like this - Maybe for a deeper dive into how nginx actually works inside: its master/worker architecture, epoll, and event-driven request processing.\n","date":"2012-07-03T00:00:00Z","permalink":"/nginx-ubuntu.html","title":"Setting up a nginx virtual host on Ubuntu"}]