Very often, when we are given some ad-hoc task which is of our interest, we tend to directly jump into coding it out of excitement. We skip the design part of the application and just want to shoot the target as fast as possible. I was asked to write a plugin and I did the same mistake. Knowing what impact this plugin would make, I started coding the project to make the lives easier for at least 5000 users.
The problem at hand looked fairly simple to me, which could be solved by calling a set of API endpoints through manual construction of HTTP requests, based on the configurations created by a user. The problem was that, it took roughly 15 minutes for the developers to manually perform HDFS operations and to submit distributed computable services to the cluster of machines. And for experimenting out different configurations for these distributed services means hours of unproductive time. To solve this problem, I was asked to write a plugin for IDE that would provide these capabilities in a few clicks. There were several such operations that were expected from this plugin. I wrote the code, tested various cases and happily published it. For each of these operations, it required roughly 2 clicks for the user to perform it. I had coded it in a way that would open a form corresponding to the user action in the extended menu added by the plugin. After adding almost 7 such functionalities, I realized, it was quite irritating for me, to have 7 different forms for related functionalities over HDFS.
Lesson-1: Always consider the user experience, before you start designing anything.
I considered myself in a position of a potential user and created a window based UI, that would provide a UX that will not have too many popup forms and also reduced the clicks to 1 for some operations. The code review happened, people started using it and I was happy with the appreciations I got, showing my Colgate white teeth, until I was asked to add some more functionalities. All my smiles were gone and I was cursing that it was not in the scope of the project. How can something be added in between? The reason was, it would have required a lot of changes to be done, to include the new operations and this opened the loopholes in my bad software architecture, which in first place was not designed properly, rather was implemented just based on current set of requirements.
Lesson-2: Always design the software considering the maintainability and reusability in future.
I did the required changes. This time I used well defined diagrams to present the pieces of software and how they interact with each other. For implementation, I referenced Gang of Four: Design Patterns and used few of them including Builder, Singleton, State and Adapter patterns. This would obviously mean use of principles of software design like Composition over inheritance, separate constants from changing parts, etc. This time I was sure that everything went well and created a beautiful user manual with steps explained to perform the functionalities. There was still a surprise gift left for me, which I received a RITM which is nothing but a service ticket in terms of Service Now tool. One of the users raised that IDE gets hanged often and freezes while using this plugin window. This was something which was not directly evident from the way in which the plugin was designed. I reviewed the design with multiple people and did profiling of the plugin, still no luck. I checked this issue with multiple users and it turned out that, for some users it worked well, for some it didn’t. Amidst all this, one fine day, when I was using the plugin for my purpose, I noticed that even my IDE was freezing when I clicked the button for the actual operation and it didn’t even allow me to select anything else till then. I had made a big mistake, which no one has caught. Guess what? The latency of a request is the time for which the IDE freezes.
Lesson-3: To handle such latencies in an interactive software, make use of asynchronous tasks via. multithreading.
Implementing this part was little trickier as I knew basic multithreading in Java, but I had never designed any application which makes use of it. This was the first experience for me and required to study multithreading and modality in IDEA. I also read about the IntelliJ SDK for plugin development and how to fit my plugin code with it. When implementing this, it was not very heavy on code, but some minor changes. Finally…finally…finally…after multiple iterations, I was able to solve this problem in a better way.
Lesson-4: Keep Learning! Cheers! :)