-
Notifications
You must be signed in to change notification settings - Fork 6
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
🐛 Refresh affect trackers after filing trackers #472
Conversation
e8c74c2
to
357dad7
Compare
357dad7
to
8cca421
Compare
f7c0752
to
d5e4165
Compare
d5e4165
to
5bc3463
Compare
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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(); |
There was a problem hiding this comment.
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.
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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you remove this?
// vi.mock('@/composables/useFlawAffectsModel', async importOriginal => ({ | ||
// ...await importOriginal(), | ||
// refreshAffects: vi.fn(), | ||
// })); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's cool!
src/composables/useFlaw.ts
Outdated
|
||
export function useFlaw() { | ||
return flaw; | ||
return { flaw, relatedFlaws, blankFlaw, resetFlaw }; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
if (index !== -1) { | |
if (relatedIndex !== -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2af8bdd
to
9d02fe7
Compare
9d02fe7
to
b408e9b
Compare
♻️ Unify flaw source of truth ♻️ Don't do circular dependencies ♻️ Never use null for default flaw value
81070ee
to
87c1783
Compare
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)); |
There was a problem hiding this 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 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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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.
There was a problem hiding this 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 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 withTracker 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.
There was a problem hiding this comment.
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
.
📝 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
🚨 Remove blank line
d86b8ec
to
204da29
Compare
OSIDB-3483 Fix affect tracker refreshing after filing trackers
Checklist:
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