Skip to content

Commit

Permalink
Issue #151: Restructure ADR
Browse files Browse the repository at this point in the history
  • Loading branch information
Amar-Bolkan committed Nov 8, 2022
1 parent d78a3a4 commit 11bbe44
Showing 1 changed file with 39 additions and 61 deletions.
100 changes: 39 additions & 61 deletions docs/adr/adr_0005.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,42 +28,51 @@ To calculate the score for a specific team the following entities are queried fr
- team: `/api/teams`
- all available badges: `api/badges`

In the dashboard view this leads to all `Teamskills` (possibly #Teams * #Skills) being loaded into the frontend.
Depending on the number of Teamskills the scores can be incorrect. This happens due to pagination and the client not checking if all records were queried.
This problem has been, until now, avoided by simply increasing the size of each page.
In the dashboard view this leads to all Teamskills (possibly #Teams * #Skills) being loaded into the frontend.

This however is not a long term solution, especially in terms of scalability as the
maximum number of teamSkills can increase quit rapidly.
Therefore, the addition of one single team or skill might push the total amount of records above the currently set maximum for each page.
This leads to several problems. The most severe one is that correct behavior of the systems is depending on the
current amount of data. This calls for more viable solution to be implemented.
#### Problem

Depending on the number of Teamskills the scores can be incorrect. This happens due to `Pagination` and the client `only querying the first page`.
The solution up to this point has been to simply increase the page size. This however is not a long term solution, especially in terms of scalability as the
maximum number of Teamskills can increase quit rapidly.

## Decision
There appear to be two general approaches one of which would be fixing the problem in the frontend and the other to move the entire calculation into the backend.

### Solution 1: Check if all pages have been queried

Instead of increasing the maximum amount of entities per page, the client could check if all pages have been queried.
This would ensure that all Teamskills have been retrieved from the backend and in turn should lead to all Teamscores being calculated correctly.

### Pros

- low implementation effort, query for Teamskills only needs to be put into a loop
- no new files need to be added / no custom code needs to be changed or extended


### Cons

### Solution 1: Moving the calculation into the backend
- keeps the computational load on the client
- `Teamscores` can't easily be queried by third party software
- might negatively impact scalability of the system, due to increasing amounts of data needing to be queried

#### Non-persistent approach
Move team score calculations to the backend and create an Api, which
the client can query. The calculation of the score is done on demand and is not persisted.

Proposed API:
### Solution 2: Moving the calculation into the backend

`/api/team-score/:teamId` : Accepts GET requests and returns the current score for the queried team.
Create a new Service, which queries a backend Api that calculates the score for a team on demand.

#### Pros

- the new API would allow for third party systems to query `Teamscores`, which would for example enable easy monitoring through something like Prometheus
- client performance should increase because calculation is now done server side
- this change might make the score calculation more scalable for each score only a subset of `Teamskills` is queried.
- calculating the score on demand avoids having to check after every CRUD operation if the previously calculated score is still correct.

#### Cons
- the client for retrieving the score needs to be adapted to the changes
- more java classes need to be added to the backend, these might need to be changed when updating to new versions of the `Jhipster Generator`
- changes need to be made in client code
- custom classes need to be added to the backend. Those might need to be maintained, when updating to new Jhipster versions

Files to be added to the backend:
<!-- ## Notes (can be deleted once solution is implemented) ##
Files to be added to the backend:
- `CustomTeamscoreResource`
- `CustomTeamScoreService`
Expand All @@ -72,27 +81,13 @@ Files to be changed in the frontend:
- `src/main/webapp/app/custom/teams/teams-status/teams-status.component.ts`
Files to be deleted:
- `src/main/webapp/app/custom/helper/team-score-calculation.ts`

#### Persistent Approach

Not persisting `Teamscore` calculations means that the same calculation might be done over and over again.
This is quite redundant and might lead to unnecessary load for the server. Instead the score for each team can be
persisted inside the database. This might be done by adding a score field to the team entity.

#### Pros
- `src/main/webapp/app/custom/helper/team-score-calculation.ts`
- should be more resource efficient (no redundant calculations of `Teamscores` )
- third party systems could still easily query scores for each team
- separate Api, which retrieves the `Teamscore` could later be added
- client performance should increase (calculations now done in the backend)
-->

#### Cons

- persisted `Teamscores` now need to be maintained (server needs to react when events occur which might influence the `Teamscore`, for example a skill expires or isn't relevant anymore)
- generated code might need to be extended or changed
<!-- ## Notes (can be deleted once solution is implemented) ##
<!--
Relevant files for score calculation:
- CompletionCheck `src/main/webapp/app/custom/helper/completion-check.ts`
- RelevanceCheck `src/main/webapp/app/custom/helper/relevance-check.ts`
Expand All @@ -103,34 +98,17 @@ mirror these classes in the backend
Variable used in TeamScore calculation: team (containing all achieved skills), all available skills, and all available badges
-->

### Solution 2: Query all entities

Another solution would be to keep sending queries until all entities have been returned by the backend.

### Pros

- low implementation effort, query for `Teamskills` only needs to be put into a loop
- doesn't add new custom files to the backend, which would need to be maintained separately from the generated ones


### Cons
## Decision

- keeps the computational load on the client
- `Teamscores` can't easily be queried by third party software
- might negatively impact scalability of the system, due to increasing amounts of data needing to be queried
We decide to implement Solution 2. The score calculations won't be persisted in the database.

## Consequences

### Solution 1:

This change would shift the computational load onto the server and provide a clear and easy way for the client to
query scores for each individual team. In turn new classes are added to the backend and the client code also needs to be adapted to use this new Api.
It would also lead to code duplication as `RelevanceCheck` and `CompletionCheck` are also used in different parts of the frontend.

- Moving the `Teamscore` calculation to the backend will shift the computational load to the server
- Making `Teamscores` queryable through a separate API enables third party systems to monitor `Teamscores` over time
- New files need to be added to the backend and client code needs to be adapted

### Solution 2:
### Persisting Results

This would simply be a small adaption in the client code. Where the single query is replaced
by a loop that checks if all pages have been queried.
In case of large datasets this solution could lead to higher network traffic and be a strain on the
clients resources.
Calculating `Teamscores` only on demand means that the same calculation might be done over and over again.
This could in the future lead to a performance bottleneck and might be further discussed in separate ADR.

0 comments on commit 11bbe44

Please sign in to comment.