Seven troubles – one answer: how we solved the problem of permanent fixes

Greetings, Habr! My name is Pavel Voropaev, I am a Software Engineer at Exness. Previously, he worked in various Russian companies as a full stack developer, Oracle database developer, Python developer and team lead. On the occasion of the end of my probationary period, I decided to write an article in which I would like to talk about how you can optimize the immersion process in the problem. I will talk about my previous experience and how my experience helped me out when I came to Exness. In the examples, I will describe the interaction of microservices using a sequence diagram.

image

Surely all of you at different stages of your career have faced such a problem: you saw the task, it seems that it is simple and the requirements are clear, and then it turns out that it was necessary to implement it differently. Time has been spent on implementation, and the deadline is already sneaking up, and the task is actually not ready. We have to rewrite on the fly, probably in violation of the deadline. Man-hours are wasted, and they cost money, and if this problem is not for one developer, but for the entire company, then a lump of overdue tasks grows, the cost of development grows, the business cannot implement the strategy, and the company suffers losses.

What is the problem?

This problem arises due to insufficient immersion in the task. There can be many reasons, here are some of them:

  • lack of up-to-date documentation;
  • misunderstanding of the business process;
  • elaboration of requirements is not fully;
  • the human factor (the source of knowledge and the performer speak about the same thing, but they understand it differently);
  • personal carelessness of performers and customers;
  • and others (each stepped on the rake in his own way).

As a result of insufficient immersion in the task, the developers do the wrong thing or not to the full, the testers do the wrong thing, the devops do the wrong thing, and the SRE monitors the wrong parameters.

How can this be fixed?

In previous places of work, I have seen the following work algorithm:

  • collection of information and formation of requirements;
  • the team is grooming and thinking over a common solution;
  • an executor is appointed who implements the task;
  • code review;
  • fixes;
  • testing;
  • more fixes;

  • more fixes;
  • long-awaited completion of the task.

Obviously, the most time is spent on the implementation of the task and fixing bugs, so why not minimize this effort?

In those teams where I worked, we decided to describe a technical solution, that is, what exactly we will do to complete the task. The description of the technical solution is made even before the start of development and then reviewed by the whole team. For clarity and improvement of perception, we decided to dilute the text with graphic schemes. The purpose of this action is to identify pitfalls, choose the right tools, correctly interact with other nodes in the system, and be able to immerse the whole team in the solution. The result we expected was a decrease in labor costs and errors in business processes (looking ahead, I will say that errors in business logic have practically disappeared, many technical errors have been avoided, fixes have been reduced, and the average time to complete a task has decreased quite well). It also turned out that it is much easier and faster to make edits to the textual description or diagram than to the already written code.

Then the work algorithm will be as follows:

  • collection of information and the formation of a requirement;
  • the team is grooming and thinking over a solution;
  • a responsible developer is appointed;
  • the developer describes the technical solution;
  • then this technical solution is reviewed by the team and others immersed in the subject area;
  • and only after the solution has been agreed upon, the developer writes the code;
  • code review;
  • testing.

Why is it so important to describe the technical solution before the implementation itself:

  • the logic of the solution is reviewed, errors are corrected at the design stage;
  • the developer dives deeper into the domain before implementation, which allows to think over the architecture in advance;
  • adjacent departments can immediately understand what the API will be and are ready to start parallel development;
  • clarifies the needs of colleagues depending on your implementation;
  • all the above points save time for all participants in the process (according to my observations as a developer, the diagram is drawn several times faster than the code is written and rewritten).

How did I apply this experience to Exness?

image Having come to Exness, I wanted to quickly get used to the team, study the infrastructure and start solving combat missions. In the first capacious task, I decided to use the accumulated experience and minimize the risk of incorrectly solving the problem. To describe the interaction of services, I decided to use sequence diagrams, block diagrams to describe the operation of algorithms and ER diagrams to describe the database schema.
In the process of drawing a diagram, I learned from colleagues what services might be needed to solve my problem, checked requests to them and data in the database, so I already understood what and how it works. It didn’t take a lot of time to develop the diagram, and while reviewing the diagram, I got useful feedback:

  • the front-end developer wanted to know in what cases, what data and statuses he would receive from the back-end;
  • QA needs to understand where the data in the service comes from in order to cover as many cases as possible.

In the diagram, I have detailed the exceptions and how they come out, and the data sources used. This made it possible to visually show colleagues how the functionality works and what to expect from it, respectively, colleagues could start implementing their parts without waiting for my implementation. The front-end developer knew how the service would respond and could start writing integrations, the QA had information on how the service responds to different situations and how to reproduce these situations. As a result, the development and immersion in the task turned out to be quite fast, and the drawn diagram supplemented the documentation of the service being developed.

Example

The example described below is a composite of various situations.

A new developer received a task with the wording “Write a new microservice to reject late orders. Notify clients about status changes.“.

After clarifying the technical details, you can understand the problem like this:

  • build a microservice, make one POST in it – an API method named reject_old_requests;
  • in this API method, you need to get data from the database, specify filters by user, status and date in the request;
  • for each request, change the status in the service that manages requests;
  • then send a request to the notification service to notify users about the change in the status of the application.

A sequence diagram for this task might look like this:

and what mistakes you could run into:

  • under the new microservice, the analyst could mean the usual API method in the microservice for working with requests, but it is difficult to recognize such a scenario (in my practice there was a case when the analyst understood the usual API method as a microservice, as far as I know the analyst did not adapt to the correct terminology);
  • perhaps the application has sub-applications or related applications, the existence of which the new developer may not know, and the analyst may forget to report and hope that the developer himself will get the information;
  • Perhaps there will be a lot of applications, and their rejection in production will take a long time. In this case, it would be better to lay down and make it possible to reject in the background;
  • good practice is to get data from the service, not directly from its database. After all, the service that manages requests may have additional fetching logic.

As a result, it turns out that such a solution will have to be rewritten from scratch, since the presence of such errors can make the implementation unviable.

If you write a technical solution before development and use a sequence diagram for clarity, then during its review, more immersed colleagues in the subject area will be able to see errors and point out them. And probably the developer himself will be able to see some problems and fix them before the review.

I assure you, just speaking the solution to a problem does not mean solving the problem correctly, one will not express it correctly, and the other will not understand correctly, and the task will not be implemented correctly. The sequence diagram is not a silver bullet, but in many cases it will help clarify some details.

What the diagram would look like after the corrections:

What is the use of charts?

Not every person is able to transfer a thought well to paper, so it is better sometimes to dilute the text with a graphic description. A clearer description of the problem will be useful not only for developers, but also for testers, as they face the same immersion problem as developers. Testers need not only to check positive outcomes, but to make sure that the system responds correctly and predictably in any situation; to emulate such cases, one needs to understand well what has changed in the system. For the team as a whole, it may be more convenient to store the documentation in the form of diagrams or various schemes, since they are laconic, with large changes they take less time to edit than a textual description. In a major refactoring, charts are indispensable because they allow you to quickly understand who and how is working with a particular node in the system. For team leaders, the thing will be useful in that you can reduce your time and the time of younger colleagues for immersion, and accordingly, more accurately plan tasks. When transferring cases from one developer to another, time costs are reduced, respectively, the situation with the bus factor improves.

What conclusions can be drawn?

Sequence diagrams are a very powerful and useful tool that saves you and your colleagues’ time. A visual description makes it easier to understand and allows you to focus on the solution itself without going deep into the technical implementation. But in no case say that such a visual description is a salvation from all problems, but it will help to solve a significant part of them.

Diagrams will definitely help with:

  • the quality and speed of immersion in the project / task;
  • improve the situation with the bus factor;
  • reduce labor costs for maintaining technical documentation;
  • simplify the transfer of cases between colleagues;
  • reduce labor costs for implementation, testing and code review, since the logic of the solution of the problem is reviewed even before the start of implementation – you will avoid a lot of errors.

Personally, in my practice, diagrams have been and remain an indispensable tool.

I also wish you to find tools that will optimize your work. Thanks for reading to the end.

PS Write in the comments, do you use this practice, what tools do you use?

Similar Posts

Leave a Reply