Whether you're a software engineer looking to optimize your code or just eager to understand runtime analysis, this article will help you think about rules as they relate to code analysis.
In this article, I explore a maintenance rule called "Too Many Updates" and discuss its implications, causes, and mitigation strategies.
At AppMap, we define the "Too Many Updates" rule as a verification process that examines the number of SQL and RPC updates executed by a command function or method within your application. This rule sets a default threshold of five updates in our
default.yml file. Any function or method that exceeds this threshold triggers the "Too Many Updates" finding to appear in the runtime analysis results.
In technical terms, this finding corresponds to CWE-1048, which refers to an “invokable control element with a large number of outward calls” [sic]. For simplicity, we'll refer to it as "Too Many Updates" throughout this article.
To illustrate the concept, let's consider a real-world example using a Spring Pet Clinic application implemented with Java and the Spring framework. This application allows us to manage owners, pets, and visits for a veterinary clinic. Imagine we have created an owner, and a pet, a bird we have given the name of Jimmy, and added a recent visit to the veterinarian. Now, let's take a closer look at the code and explore the consequences of the "Too Many Updates" finding.
Before diving into the code, let's first understand how to customize the default threshold for the "Too Many Updates" rule. By creating an
appmap-scanner.yml file, and running the command, you can override the default settings.
$ npx @appland/scanner \
--appmap-dir tmp/appmap \
--config appmap-scanner.yml \
In the example provided, the warning limit is set to one for demonstration purposes.
- rule: authzBeforeAuthn
- rule: http500
- rule: illegalPackageDependency
- equal: actionpack
- rule: insecureCompare
- rule: missingAuthentication
- rule: missingContentType
- rule: nPlusOneQuery
- rule: secretInLog
- rule: slowFunctionCall
- match: Controller#create$
- rule: slowHttpServerRequest
- rule: slowQuery
- rule: tooManyJoins
- rule: tooManyUpdates
- rule: unbatchedMaterializedQuery
- rule: updateInGetRequest
However, in practical scenarios, it's recommended to set a more appropriate threshold based on your application's requirements. Now that we can control our threshold let's jump over and view our findings.
To analyze the findings, we'll use AppMap to navigate to the runtime analysis section. The findings table provides a comprehensive overview of all the identified issues.
You can also group the findings by project, date, or category to gain better visibility into your application's maintainability.
Examining Example 1
Open the findings report for the "Too Many Updates" finding to understand its causes and implications. In this example, the command performs 47 SQL or RPC updates, as indicated in the event summary.
When we examine the map, we can observe a sequence diagram representing the execution flow. The presence of this finding suggests potential poor coding practices or architectural flaws in the application.
It highlights the need to consolidate multiple calls into a more efficient and maintainable structure. In this particular application, this is the result of database migrations being performed during the setup phase for development.
Examining Example 2
Now, let's explore another example to compare and contrast the findings. In this case, the threshold is set to two, and we examine the sequence diagram for the corresponding map finding an action that performs to “updates” in the same function call.
This specific scenario involves adding a pet to an owner. We can observe that two updates are performed: one to
INSERT the pet's information…
INSERT INTO pets (id, birth_date, name, type_id)`
…and another to associate the pet with its owner.
UPDATE pets SET owner owner_id=? WHERE id=?
Unlike the previous example, this finding emphasizes a design choice rather than inherent flaws in the application's architecture. It prompts us to evaluate if these two calls can be consolidated into a single call for improved efficiency and simplicity.
To address the "Too Many Updates" finding, we have several mitigation strategies at our disposal.
The first and simplest approach is refactoring the code to consolidate multiple updates into a single call. Often we find that “Too Many Updates” isn’t the result of some large flaw in the design of our application, but rather the result of poor implementation of coding standards and common best practices.
By reviewing the code and analyzing the sequence diagrams, we can identify opportunities to optimize the number of updates performed. Additionally, if we do find a larger issue at play we can consider architectural changes. Such as reevaluating the structure of services and abstractions, to ensure a more streamlined approach.
Alternatively, if these issues uncover a security risk in our application, we can employ the use of rate limiting to ensure our application remains performant and secure. These mitigation strategies enhance maintainability, improve code readability, and reduce potential security risks.
Watch the video:
In this article, we explored the "Too Many Updates" maintenance rule and its impact on software engineering practices.
By understanding the causes, implications, and mitigation strategies, you can effectively optimize your code and ensure a more efficient and maintainable application.
Remember to review your findings, analyze sequence diagrams, and implement the appropriate refactoring techniques and architectural changes. By doing so, you'll enhance the overall quality and performance of your software.
⬇️ Download AppMap for VSCode and JetBrains: https://appmap.io/download
⭐ Star AppMap on GitHub: https://github.com/getappmap
🐦 Follow on Twitter: https://twitter.com/getappmap
💬 Join AppMap Slack: https://appmap.io/slack
ℹ️ Read the AppMap docs: https://appmap.io/docs
📺 Watch AppMap Tutorials: https://www.youtube.com/@appmap