Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Refresh affect trackers after filing trackers #472

Merged
merged 5 commits into from
Jan 28, 2025

Conversation

superbuggy
Copy link
Collaborator

@superbuggy superbuggy commented Nov 1, 2024

OSIDB-3483 Fix affect tracker refreshing after filing trackers

Checklist:

  • Commits consolidated
  • Changelog updated
  • Test cases added/updated
  • Jira ticket updated

Summary:

[Replace with a brief summary of the changes introduced by this PR.]

Changes:

[Replace with a detailed description of the changes made in this PR, including any new features, enhancements, bug fixes, or refactorings.]

Considerations:

[Replace with any additional considerations, notes, or instructions for reviewers.]

Closes OSIDB-3483

@superbuggy superbuggy requested review from C-Valen and a team November 1, 2024 16:21
@superbuggy superbuggy self-assigned this Nov 4, 2024
@superbuggy superbuggy marked this pull request as draft December 10, 2024 15:03
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from e8c74c2 to 357dad7 Compare December 11, 2024 14:43
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from 357dad7 to 8cca421 Compare January 13, 2025 19:10
@superbuggy superbuggy marked this pull request as ready for review January 14, 2025 15:27
@superbuggy superbuggy marked this pull request as draft January 15, 2025 15:47
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from f7c0752 to d5e4165 Compare January 16, 2025 17:40
@superbuggy superbuggy marked this pull request as ready for review January 16, 2025 17:47
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from d5e4165 to 5bc3463 Compare January 16, 2025 17:55
Copy link
Member

@MrMarble MrMarble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should enforce the as Ref<ZodFlawType>; everywhere.
The only place where initializeFlaw is called is on fetchFlaw, maybe instead of using the global flaw, use a local variable and only if the flaw is fetched correctly, update the global one, that way we can remove the optional null on useFlaw and leave it like ref<ZodFlawType>(blankFlaw()); so we can remove all the type casting.

src/components/FlawAffects/FlawAffects.vue Outdated Show resolved Hide resolved
src/composables/useFlaw.ts Show resolved Hide resolved
src/composables/useFetchFlaw.ts Outdated Show resolved Hide resolved
Copy link
Member

@C-Valen C-Valen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting a type error when trying to file a bunch of trackers:

image

Comment on lines 46 to 43
async function useMockedModel(flaw: ZodFlawType) {
const _useFlaw = await vi.importActual<typeof import('@/composables/useFlaw')>('@/composables/useFlaw');
vi.mocked(useFlaw).mockReturnValue({ ..._useFlaw.useFlaw(), flaw: ref(flaw) });
const { flaw: flawRef } = useFlaw();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this component only uses the flaw and not the other properties, I think we could skip importing the original implementation, just adding the partial option to vi.mocked will get rid of the type error.

Suggested change
async function useMockedModel(flaw: ZodFlawType) {
const _useFlaw = await vi.importActual<typeof import('@/composables/useFlaw')>('@/composables/useFlaw');
vi.mocked(useFlaw).mockReturnValue({ ..._useFlaw.useFlaw(), flaw: ref(flaw) });
const { flaw: flawRef } = useFlaw();
function useMockedModel(flaw: ZodFlawType) {
vi.mocked(useFlaw, { partial: true }).mockReturnValue({ flaw: ref(flaw) });
const { flaw: flawRef } = useFlaw();

I've tried this locally and all the tests pass, this way we can remove the async functions

@@ -14,6 +14,7 @@ import type { ZodFlawType } from '@/types';
import { postAffects, deleteAffects } from '@/services/AffectService';
import { getFlaw } from '@/services/FlawService';

// const { blankFlaw } = useFlaw();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you remove this?

Comment on lines 35 to 38
// vi.mock('@/composables/useFlawAffectsModel', async importOriginal => ({
// ...await importOriginal(),
// refreshAffects: vi.fn(),
// }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this can be removed

watch(relatedFlaws, () => {
selectedRelatedFlaws.value.forEach((selectedFlaw) => {
const index = relatedFlaws.value.findIndex(({ uuid }) => uuid === selectedFlaw.uuid);
if (index !== -1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a suggestion, just a comment.
This expression can also be written as !!~index, the ~ bitwise operator will flip the numbers and only -1 will return 0, so we can coerce that to boolean with the !!.
It is a bit obscure but I like it for some reason 😆

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool!


export function useFlaw() {
return flaw;
return { flaw, relatedFlaws, blankFlaw, resetFlaw };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could leave blankFlaw outside of the useFlaw composable as it is returning a constant value that does not modifies flaw in any way

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this same thought

watch(relatedFlaws, () => {
selectedRelatedFlaws.value.forEach((selectedFlaw, index) => {
const relatedIndex = relatedFlaws.value.findIndex(({ uuid }) => uuid === selectedFlaw.uuid);
if (index !== -1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was left behind after the renaming, index comes from the loop so it will never be -1

Suggested change
if (index !== -1) {
if (relatedIndex !== -1) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once this is fixed I'll leave my approval, rest LGTM

@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from 2af8bdd to 9d02fe7 Compare January 22, 2025 15:34
C-Valen
C-Valen previously approved these changes Jan 22, 2025
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from 9d02fe7 to b408e9b Compare January 22, 2025 15:40
MrMarble
MrMarble previously approved these changes Jan 22, 2025
♻️ Unify flaw source of truth

♻️ Don't do circular dependencies

♻️ Never use null for default flaw value
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from 81070ee to 87c1783 Compare January 24, 2025 14:58
async function refreshRelatedFlaws() {
isLoadingTrackers.value = true;
// After filing new trackers, there is a delay before the new trackers are available on the flaws
await new Promise(resolve => setTimeout(resolve, 2000));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a random timeout is a solution, tracker creation is asynchronous, it depends not only on Jira API response time, but also if workers are idle and ready to take the creation task or busy with periodic work / requests from other users, this value might work locally, but it will surely fail in production.

Maybe we could implement a polling system, make a request every second or half a second to the /affects/<affect_uuid> endpoint to see if the tracker is already there, if it takes more than 10 requests (5 to 10 seconds depending on the delay) we show an alert with Tracker creation took too long so we don't keep the user waiting.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing I saw while testing this is that when we make the POST to trackers for creation, the response already has everything we need to show the tracker in the UI, can't we use this to update the trackers table? (status is empty but since we are creating it, I think we can assume it is NEW)
image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noted this as well, but it does not have the relational associations. Additionally, matching based on ps_update_stream will not yield correct associations in some situations.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a random timeout is a solution, tracker creation is asynchronous, it depends not only on Jira API response time, but also if workers are idle and ready to take the creation task or busy with periodic work / requests from other users, this value might work locally, but it will surely fail in production.

Maybe we could implement a polling system, make a request every second or half a second to the /affects/<affect_uuid> endpoint to see if the tracker is already there, if it takes more than 10 requests (5 to 10 seconds depending on the delay) we show an alert with Tracker creation took too long so we don't keep the user waiting.

What do you think?

I agree and had considered the same, but have concerns about implementation complexity and resource allocation for this particular PR.

While not ideal, I think this is candidate solution for a temporary fix, though I think providing a warning that a hard refresh may be required. I agree with the polling approach, and while not a massive extra lift, does expand the scope of the solution. I considered this strategy, but we are already experiencing scope creep here. I agree with you, but from an operational perspective, I am somewhat hesitant to implement a more robust solution at this time.

It is worth noting that the JIRA sync is non-blocking for the relational associations to take place and that the 2 seconds seems sufficient for the relational associations to propagate in my testing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, so pending the discussion between @MrMarble and I during our code review, I realized we can in fact use the data from the request-response cycle for trackers since each tracker is created one by one. This however does expand the scope of the PR, and we have fix planned documented in OSIDB-3961.

MrMarble
MrMarble previously approved these changes Jan 28, 2025
📝 Update changelog

🐛 Fix typo

✨ Atomically refresh trackers for affects after filing

🔥 Remove unused reference

🔥 Remove unused reference

🐛 Separate refresh logic to avoid weird bundled code in vitest

🚨 Handle linter warning

🔥 Remove unused code

🐛 Fix trackers refresh behavior

✅ Align test mocks with streamlined data flow

✅ Update tests for never-null flaws

🐛 Fix index mismatch

♻️ Simplify mock

🔥 Remove dead code

🐛 Exclude affect history from comparison

🐛 Correct index reference

🚨 Remove unused references

🚨 Remove unused references

🚨 Remove unused references

♻️ Remove blankFlaw from composable scope

🔧 Make related flaws query faster

🐛 Fix refreshing of related flaw trackers

Used incorrect source of truth for related flaws
📸 Update snapshots

📝 Document limitations in comments

📸 Update snapshots
@superbuggy superbuggy force-pushed the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch from d86b8ec to 204da29 Compare January 28, 2025 15:05
@superbuggy superbuggy merged commit d61ea68 into main Jan 28, 2025
5 checks passed
@superbuggy superbuggy deleted the feature/OSIDB-3483-fix-tracker-refresh-after-filing branch January 28, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants