From 7bdb643dd972f516e96d5d486f0eebb2bc5438cc Mon Sep 17 00:00:00 2001 From: Yunlong Gan Date: Tue, 5 Mar 2024 14:44:05 +0800 Subject: [PATCH 1/4] ADM-837:[docs]feat: add half completed spike doc --- ...rics-buttoo-polling-api-backend-change.mdx | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx diff --git a/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx new file mode 100644 index 0000000000..5b2dd24884 --- /dev/null +++ b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx @@ -0,0 +1,43 @@ +--- +title: Tech solution of all metrics export button problems for ADM-822 +description: Tech solution of all metrics export button problems for ADM-822 +--- + +## Background +The front-end uses the allMetricsCompleted field of the back-end polling interface to determine whether the board and dora metric have been generated to determine whether the export metric button can be clicked. The backend's field judgment logic is determined based on the boardMetricsCompleted and doraMetricsCompleted fields, and the null value in both is ignored and compared. However, the following situations may lead to incorrect judgment, resulting in incorrect button display. +See ADM-822 to get more information. + +### Wrong case 1 +The user selected board and dora. When generating indicators in the last step, if an error occurs and the board or dora request is not sent, you need to retry one or both of them. If only one of the requests (such as board) is successfully executed, That will cause boardMetricsCompleted=true, doraMetricsCompleted=null, ignoring the null value comparison, causing allMetricsCompleted to be true. At this time, the export metric button can be clicked, but the expectation is that the button cannot be clicked. + +### original fix in backend +The backend modification is to change the way of allMetricsCompleted field judgment and change the null value to false by default before comparison. But the following problems will occur(wrong case 2). + +### Wrong case 2 +The user only selects board or dora. Finally, the indicator is generated, but the export metric button cannot be clicked. The reason is that the front end still determines whether it is clickable based on the allMetricsCompleted field. For example, if only board is selected, it will result in boardMetricsCompleted=true, doraMetricsCompleted=null, allMetricsCompleted=false + +### Temporary fix +Frontend: The front end does not use allMetricsCompleted to determine the button status. Instead, it depends on whether borad or dora is currently selected. Look at boardMetricsComplete and doraMetricsCompleted to determine the button status. +Backend: code revert + +### Frontend legacy issues +The original problem of ADM-822 reappears + +### Backend legacy issues +The logic of the allMetricsCompleted field in the backend remains the same, and there is still the problem of wrong case 1 +There is logic to generate all metric csv in the polling interface, which will be triggered when allMetricsCompleted=true, which will cause incomplete csv to be repeatedly generated in the polling interface in wrong case 1, affecting performance. +The allMetricsCompleted field in the backend is currently no longer used by the frontend. Consider how to handle this field. + +### Why can’t it be purely back-end repaired? +The backend cannot distinguish between the above wrong case 1 and wrong case 2. The backend cannot sense whether the user has selected board and dora, or only one of board and dora. + + +## Expect +1. When the user selects either board or dora and succeeds, the export metrics button can be displayed as clickable +2. When the user selects both board and dora, the export metrics button can be displayed as expected by ADM-822 + + +## Solutions + + + From 415dc76b024caf2a5947a7586c30b57a559d2e73 Mon Sep 17 00:00:00 2001 From: Shiqi Yuan Date: Tue, 5 Mar 2024 16:26:34 +0800 Subject: [PATCH 2/4] ADM-837: [docs] completed spike solution for export-allMetrics button polling api. --- ...rics-buttoo-polling-api-backend-change.mdx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx index 5b2dd24884..b9667e80bd 100644 --- a/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx +++ b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx @@ -39,5 +39,24 @@ The backend cannot distinguish between the above wrong case 1 and wrong case 2. ## Solutions +# For backend + +# Modify generateReport Api +1.Previous api is POST /reports/{metricType}, but now need to modify as POST /reports and add new Parameter List metricTypes in requestBody. +2.Then write the metricTypes on file. +3.According to the metricTypes to generate boardCsv or DoraCsv then we start another thread to check if boardCsv and DoraCsv are generated. if check pass, then we can generate metricCsv. + +# Modify polling Api(POST /reports/{reportId}) +1.to use metricTypesFile to check if allMetricsCompleted index is true by use the combination of boardMetricsCompleted index and doraMetricsCompleted index or just one of these two index. +2.remove generate metricCsv file in this api logic. + +# Add a new scheduled task +1. Delete expire metricTypes file regularly. + +# For Frontend + +1.revert to previous version's logic, still use allMetricsCompleted index to decide whether the button can click or not. +2.modify the url and requestBody of generateReport Api。 + From c71cebe5343e94d9bb0cffd0af4e08cd4e736caf Mon Sep 17 00:00:00 2001 From: Shiqi Yuan Date: Mon, 11 Mar 2024 14:08:49 +0800 Subject: [PATCH 3/4] ADM-837: [docs] completed spike design for export-allMetrics button polling api. --- .../en/designs/optimize-generate-report.mdx | 219 ++++++++++++++++++ ...ics-button-polling-api-backend-change.mdx} | 24 +- docs/src/i18n/en/nav.ts | 10 + 3 files changed, 241 insertions(+), 12 deletions(-) create mode 100644 docs/src/content/docs/en/designs/optimize-generate-report.mdx rename docs/src/content/docs/en/spikes/{tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx => tech-spikes-export-all-metrics-button-polling-api-backend-change.mdx} (77%) diff --git a/docs/src/content/docs/en/designs/optimize-generate-report.mdx b/docs/src/content/docs/en/designs/optimize-generate-report.mdx new file mode 100644 index 0000000000..f4e1608153 --- /dev/null +++ b/docs/src/content/docs/en/designs/optimize-generate-report.mdx @@ -0,0 +1,219 @@ +--- +title: Optimize generate report +description: solve issue about when one of the export button can not click but export metric button can click +--- + +# Context +Considering to fix the issue about when one of the export button can not click but export metric button can click, and change logic about polling api in backend. we have to optimize generate report flow. + +# Design +## C2 - Generate report - AS-IS + +### Sequence Diagram + +```plantuml +@startuml report +skin rose +title C2 - Heartbeat - Generate Report - Transition +participant Frontend +participant Backend +participant Jira +participant Buildkite +participant Github + +Frontend -> Backend: generate metrics for board related +activate Backend +Backend --> Frontend: response 202 with callback +deactivate Backend + +group async process board related metrics + Backend -> Jira: get Jira raw data + activate Backend + activate Jira + Jira --> Backend: Jira raw + deactivate Jira + Backend -> Backend: calculate metrics for velocity, cycle time and classification + Backend -> Backend: generate board report csv + deactivate Backend + note left + response.boardMetricsCompleted is true + board metrics are ready for display + board csv is ready for download + end note +end + +Frontend -> Backend: generate metrics for pipeline,Source control(if required) related +activate Backend +Backend --> Frontend: response 202 with callback +deactivate Backend + +group async process pipeline and sourcecontrol related metrics + Backend -> Buildkite: get Buildkite raw data + activate Backend + activate Buildkite + Buildkite --> Backend: Buildkite raw data + deactivate Buildkite + Backend -> Backend: calculate metrics for deployment frequency, \nchange failure rate and mean time to recovery + note left + pipeline metrics are ready for display + end note + opt if lead time for change required + Backend -> Github: get Github raw data + activate Github + Github --> Backend: Github raw data + deactivate Github + Backend -> Backend: calculate metrics for lead time for change + note left + LTFC is ready for display + end note + end + Backend -> Backend: generate pipeline report csv with github data if required + note left + response.doraMetricsCompleted is true + pipeline report is ready for download + end note + deactivate Backend +end + +loop until (response code is 201 and body.allMetricsReady==true) or (response code is 5xx) + Frontend -> Backend: Polling the report + activate Backend + alt report is not ready + Backend --> Frontend: response 200 + else report is ready + Backend --> Frontend: response 201 with report + else fail to process + Backend --> Frontend: response 5xx + end + deactivate Backend +end +@enduml +``` + +## C2 - Generate report - TO-BE +### Sequence Diagram + + +```plantuml +@startuml report +skin rose +title C2 - Heartbeat - Generate Report - Transition +participant Frontend +participant Backend +participant Jira +participant Buildkite +participant Github + +Frontend -> Backend: generate metrics for board or dora or both of them +activate Backend +Backend --> Frontend: response 202 with callback +deactivate Backend + + +loop until (metricTypes list final element) + Backend -> Backend: write metricType on one file + activate Backend + + + alt metricsType is Board + Backend --> Backend: initialize boardMetricsCompleted index as false + group async process board related metrics + Backend -> Jira: get Jira raw data + activate Backend + activate Jira + Jira --> Backend: Jira raw + deactivate Jira + Backend -> Backend: calculate metrics for velocity, cycle time and classification + Backend -> Backend: generate board report csv + deactivate Backend + note left + update response.boardMetricsCompleted as true + board metrics are ready for display + board csv is ready for download + end note + end + + + else metricsType is Dora + Backend --> Backend: initialize doraMetricsCompleted as false + group async process pipeline and sourcecontrol related metrics + Backend -> Buildkite: get Buildkite raw data + activate Backend + activate Buildkite + Buildkite --> Backend: Buildkite raw data + deactivate Buildkite + Backend -> Backend: calculate metrics for deployment frequency, \nchange failure rate and mean time to recovery + note left + pipeline metrics are ready for display + end note + opt if lead time for change required + Backend -> Github: get Github raw data + activate Github + Github --> Backend: Github raw data + deactivate Github + Backend -> Backend: calculate metrics for lead time for change + note left + LTFC is ready for display + end note + end + Backend -> Backend: generate pipeline report csv with github data if required + note left + update response.doraMetricsCompleted as true + pipeline report is ready for download + end note + deactivate Backend + end + end + deactivate Backend +end + + +group async check if metricCsv can be generated + loop until (allMetricsCompleted==true) + Backend -> Backend: calculate the size of metricTypes list + alt the size of metricTypes list equal to one and metricTypes list contains board element + Backend --> Backend: allMetricsCompleted index is decided by the value of boardMetricsCompleted index + else the size of metricTypes list equal to one and metricTypes list contains dora element + Backend --> Backend: allMetricsCompleted index is decided by the value of doraMetricsCompleted index + else the size of metricTypes list equal to two and metricTypes list contains both board element and dora element + Backend --> Backend: allMetricsCompleted index is decided by the combination of value for doraMetricsCompleted index and boardMetricsCompleted index + end + alt allMetricsCompleted is true + Backend --> Backend: Metric csv generated, metric report is ready for download + else allMetricsCompleted is false + Backend --> Backend: Metric csv can not be generated, metric report is not ready for download + end + deactivate Backend + end + deactivate Backend + end + + +loop until (response code is 201 and body.allMetricsCompleted==true) or (response code is 5xx) + Frontend -> Backend: Polling the report + activate Backend + alt report is not ready + Backend --> Frontend: response 200 + else report is ready + Backend --> Frontend: response 201 with report + else fail to process + Backend --> Frontend: response 5xx + end + deactivate Backend +end +@enduml +``` + +### API Design +the request body of generate report api is the same as as-is, but will add one parameter in the request body. +``` +URI: POST /reports +Request payload: +{ + ... + "metricsType": [ + "string" + ] +} +``` + diff --git a/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-button-polling-api-backend-change.mdx similarity index 77% rename from docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx rename to docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-button-polling-api-backend-change.mdx index b9667e80bd..79255d461f 100644 --- a/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-buttoo-polling-api-backend-change.mdx +++ b/docs/src/content/docs/en/spikes/tech-spikes-export-all-metrics-button-polling-api-backend-change.mdx @@ -39,24 +39,24 @@ The backend cannot distinguish between the above wrong case 1 and wrong case 2. ## Solutions -# For backend +### For backend -# Modify generateReport Api -1.Previous api is POST /reports/{metricType}, but now need to modify as POST /reports and add new Parameter List metricTypes in requestBody. -2.Then write the metricTypes on file. -3.According to the metricTypes to generate boardCsv or DoraCsv then we start another thread to check if boardCsv and DoraCsv are generated. if check pass, then we can generate metricCsv. +#### Modify generateReport Api +1. Previous api is POST /reports/```{metricType}```, but now need to modify as POST /reports and add new Parameter metricTypesList in requestBody. +2. Then write the metricTypes on file. +3. According to the metricTypes to generate boardCsv or DoraCsv then we start another thread to check if boardCsv and DoraCsv are generated. if check pass, then we can generate metricCsv. -# Modify polling Api(POST /reports/{reportId}) -1.to use metricTypesFile to check if allMetricsCompleted index is true by use the combination of boardMetricsCompleted index and doraMetricsCompleted index or just one of these two index. -2.remove generate metricCsv file in this api logic. +#### Modify polling Api(POST /reports/```{reportId}```) +1. to use metricTypesFile to check if allMetricsCompleted index is true by use the combination of boardMetricsCompleted index and doraMetricsCompleted index or just one of these two index. +2. remove generate metricCsv file in this api logic. -# Add a new scheduled task +#### Add a new scheduled task 1. Delete expire metricTypes file regularly. -# For Frontend +### For Frontend -1.revert to previous version's logic, still use allMetricsCompleted index to decide whether the button can click or not. -2.modify the url and requestBody of generateReport Api。 +1. revert to previous version's logic, still use allMetricsCompleted index to decide whether the button can click or not. +2. modify the url and requestBody of generateReport Api。 diff --git a/docs/src/i18n/en/nav.ts b/docs/src/i18n/en/nav.ts index fc89758efd..811ba430e0 100644 --- a/docs/src/i18n/en/nav.ts +++ b/docs/src/i18n/en/nav.ts @@ -77,6 +77,11 @@ export default [ slug: 'designs/refinement-on-generate-report', key: 'designs/refinement-on-generate-report', }, + { + text: 'Optimize generate report', + slug: 'designs/optimize-generate-report', + key: 'designs/optimize-generate-report', + }, { text: 'Sequence diagrams', slug: 'designs/sequence-diagrams', @@ -161,6 +166,11 @@ export default [ slug: 'spikes/tech-spikes-calculate-rework-of-board-card', key: 'spikes/tech-spikes-calculate-rework-of-board-card', }, + { + text: 'Solution to optimize generate report', + slug: 'spikes/tech-spikes-export-all-metrics-button-polling-api-backend-change', + key: 'spikes/tech-spikes-export-all-metrics-button-polling-api-backend-change', + }, { text: 'Biz', header: true, type: 'biz', key: 'Biz' }, { text: 'Biz context', slug: 'biz/business-context', key: 'biz/business-context' }, From 2fd7fc4daeb2ece26c6e7986c89d029d9689bc5a Mon Sep 17 00:00:00 2001 From: Shiqi Yuan Date: Tue, 12 Mar 2024 14:22:20 +0800 Subject: [PATCH 4/4] ADM-837: [docs] add note to notice allMetricCompleted as true --- .../en/designs/optimize-generate-report.mdx | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/docs/src/content/docs/en/designs/optimize-generate-report.mdx b/docs/src/content/docs/en/designs/optimize-generate-report.mdx index f4e1608153..fc5f8f49f8 100644 --- a/docs/src/content/docs/en/designs/optimize-generate-report.mdx +++ b/docs/src/content/docs/en/designs/optimize-generate-report.mdx @@ -110,15 +110,15 @@ Backend --> Frontend: response 202 with callback deactivate Backend +Backend --> Backend: initialize reportStatus according to metricTypes list element +activate Backend + +group async check if metricCsv can be generated loop until (metricTypes list final element) - Backend -> Backend: write metricType on one file - activate Backend - alt metricsType is Board - Backend --> Backend: initialize boardMetricsCompleted index as false group async process board related metrics - Backend -> Jira: get Jira raw data + Backend -> Jira: get Jira raw data,put this thread into thread list activate Backend activate Jira Jira --> Backend: Jira raw @@ -135,14 +135,13 @@ loop until (metricTypes list final element) else metricsType is Dora - Backend --> Backend: initialize doraMetricsCompleted as false group async process pipeline and sourcecontrol related metrics - Backend -> Buildkite: get Buildkite raw data + Backend -> Buildkite: get Buildkite raw data, put this thread into thread list activate Backend activate Buildkite Buildkite --> Backend: Buildkite raw data deactivate Buildkite - Backend -> Backend: calculate metrics for deployment frequency, \nchange failure rate and mean time to recovery + Backend -> Backend: calculate metrics for deployment frequency, change failure rate and mean time to recovery note left pipeline metrics are ready for display end note @@ -164,30 +163,15 @@ loop until (metricTypes list final element) deactivate Backend end end - deactivate Backend + + Backend --> Backend: wait for threadList element all execute completed + Backend --> Backend: generate metricCsv + note left + update allMetricsCompleted as true and write it on the file + end note +end + deactivate Backend end - - -group async check if metricCsv can be generated - loop until (allMetricsCompleted==true) - Backend -> Backend: calculate the size of metricTypes list - alt the size of metricTypes list equal to one and metricTypes list contains board element - Backend --> Backend: allMetricsCompleted index is decided by the value of boardMetricsCompleted index - else the size of metricTypes list equal to one and metricTypes list contains dora element - Backend --> Backend: allMetricsCompleted index is decided by the value of doraMetricsCompleted index - else the size of metricTypes list equal to two and metricTypes list contains both board element and dora element - Backend --> Backend: allMetricsCompleted index is decided by the combination of value for doraMetricsCompleted index and boardMetricsCompleted index - end - alt allMetricsCompleted is true - Backend --> Backend: Metric csv generated, metric report is ready for download - else allMetricsCompleted is false - Backend --> Backend: Metric csv can not be generated, metric report is not ready for download - end - deactivate Backend - end - deactivate Backend - end - loop until (response code is 201 and body.allMetricsCompleted==true) or (response code is 5xx) Frontend -> Backend: Polling the report @@ -211,7 +195,7 @@ URI: POST /reports Request payload: { ... - "metricsType": [ + "metricTypes": [ "string" ] }