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

Fix actions fetching logic and loading state, prevent duplicate toasts #31124

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

silverwind
Copy link
Member

@silverwind silverwind commented May 27, 2024

  1. Fix the bug where action steps would not expand sometimes. This was because when a fetch was running and the user clicked "expand" it would not propagate the expansion request to the backend, leaving the UI state invalid. Fixed this by adding a force flag.
  2. When a fetch failed, it would just throw the error and the browser would dump it into the console, invisible to the user. Show a toast in such a case.
  3. Add a dedicated loading state to steps to ensure they can not get stuck in that state when cursor remains at null, for example when a fetch error happened.

Also, because in the actions view, fetches can fail repeatedly because of the refreshing, I saw the need to introduce a deduplication for toasts, so if an attempt is made to raise a toast with the same message and level, it will suppress opening them.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label May 27, 2024
@pull-request-size pull-request-size bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label May 27, 2024
@silverwind silverwind added the backport/v1.22 This PR should be backported to Gitea 1.22 label May 27, 2024
@lunny
Copy link
Member

lunny commented May 28, 2024

Could we split these as two PRs for easier review?

@silverwind
Copy link
Member Author

Can't easily split this because if I remove only the toast changes, there would be the problem of repeated error toasts every second because of that refresh mechanism. The only thing that could be done is to have a reduced backport that only fixes issue 1 with the force flag.

@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels May 29, 2024
@silverwind
Copy link
Member Author

BTW one reason we need the toast deduplication: Go to admin dashboard and disconnect your network:

image

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Jun 23, 2024
@wxiaoguang wxiaoguang removed the backport/v1.22 This PR should be backported to Gitea 1.22 label Jun 23, 2024
Copy link
Contributor

@wxiaoguang wxiaoguang left a comment

Choose a reason for hiding this comment

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

Missed this review request.

No block from my side (I don't use Actions and I haven't spent time on reading code), just share some opinions:

  1. the loadData state management becomes more and more complex and fragile, at first glance I can't tell whether it is complete but I guess there could be some edge cases, for example: force=true will reset other this.loading=true
  2. maybe there should be some tests to cover some functions (even without e2e test, we could mock and test some code blocks)
  3. the change of showToast is quite hacky
    • preventDuplicates should not default to true, it is a breaking behavior.
    • it should hide the existing toast, but not skip the new toast.
  4. it shouldn't be backported since the change is not covered by tests, and it doesn't fix blocker problems for end users.

web_src/js/modules/toast.js Outdated Show resolved Hide resolved
@silverwind
Copy link
Member Author

silverwind commented Jun 25, 2024

maybe there should be some tests to cover some functions (even without e2e test, we could mock and test some code blocks)

Quite hard I assume unless Vue works in happy-dom, but I would doubt that. Maybe with some Vue-specific testing framework, but I have no experience with those.

preventDuplicates should not default to true, it is a breaking behavior.

It helps with other cases like systems stats flooding the page with error toasts when going offline.

it should hide the existing toast, but not skip the new toast.

This is actually a nice idea, I will try to implement.

it shouldn't be backported since the change is not covered by tests, and it doesn't fix blocker problems for end users.

It's quite annoying when you click an action step and nothing happens though. Happens to me like a third of the time.

@silverwind silverwind marked this pull request as draft June 25, 2024 00:30
@silverwind
Copy link
Member Author

Will also fix the boolean trap with loadData :)

@wxiaoguang
Copy link
Contributor

maybe there should be some tests to cover some functions (even without e2e test, we could mock and test some code blocks)

Quite hard I assume unless Vue works in happy-dom, but I would doubt that. Maybe with some Vue-specific testing framework, but I have no experience with those.

Maybe something like "Improve <SvgIcon> to make it output svg node and optimize performance (#23570)"

@silverwind
Copy link
Member Author

Right, this createApp + mount pattern I had a helper function in another PR, so likely tests could use it in place of this h function.

BTW, I think I will extract the toast changes to another PR. I have a few improvements in mind.

@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 25, 2024
@silverwind
Copy link
Member Author

preventDuplicates should not default to true, it is a breaking behavior.

Ended up following your suggestion and defaulting to false, so it requires opt-in at the caller and I did so on all known callers that do fetch in a loop. Maybe later we could make it default for all error level toasts.

@silverwind silverwind marked this pull request as ready for review June 25, 2024 19:46
@wxiaoguang
Copy link
Contributor

Thought again about this and I think it's not ideal to have a toast constantly re-show. It's bad UX as user can not easily select text in the toast.

I will try to propose a solution to see whether it is better. There are some details in my mind.

@wxiaoguang
Copy link
Contributor

-> Make toast support preventDuplicates #31501

@silverwind
Copy link
Member Author

I'll merge this now for the bugfix part. We can iterate on the toast in #31501.

@silverwind silverwind added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Jun 26, 2024
@silverwind silverwind enabled auto-merge (squash) June 26, 2024 10:31
@silverwind silverwind added the backport/v1.22 This PR should be backported to Gitea 1.22 label Jun 26, 2024
@wxiaoguang wxiaoguang removed the backport/v1.22 This PR should be backported to Gitea 1.22 label Jun 26, 2024
@wxiaoguang
Copy link
Contributor

I have objection for backporting, unless TOC agrees to backport.

@wxiaoguang wxiaoguang disabled auto-merge June 26, 2024 10:34
@wxiaoguang
Copy link
Contributor

And one more thing, could you revert the toast related code?

@silverwind
Copy link
Member Author

I can remove the toast code in favor of #31501 if you port all my changes from here (htmx and actions view preventDuplicates) into it.

I don't really care about the backport so much as I'm not using Actions, but other users might and I think it's a important bugfix for them.

@wxiaoguang
Copy link
Contributor

I don't really care about the backport so much as I'm not using Actions, but other users might and I think it's a important bugfix for them.

The problem is that the code really changed a lot and I am not sure there would be regressions, for example:

the loadData state management becomes more and more complex and fragile, at first glance I can't tell whether it is complete but I guess there could be some edge cases, for example: force=true will reset other this.loading=true

I think as a bug fix it is really good to end users and the work is awesome, while I also think we should make 1.22 branch as stable as possible to avoid introducing new regressions (especially for a large PR like this)

So, maybe if this change is stable enough in 1.23, then we could backport it to the next 1.22 release (eg 1.22.2 or 1.22.3)

if (!this.currentJobStepsStates[i]) {
// initial states for job steps
this.currentJobStepsStates[i] = {cursor: null, expanded: false};
if (job) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here and above: why it needs new two if here? They are from [job, artifacts] = await Promise.all, and the response shouldn't be null.

Copy link
Contributor

Choose a reason for hiding this comment

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

If the await Promise.all fails, none of these 2 variables could have value.

So it should return early in the catch block above, but not use extra if blocks here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the root problem is that the state management in this loadData/loadJob is quite messy (because after the initial version, then people only add code to "patch" it).

As a bug fix, I think this PR could work. While if we'd like to make the code right, I guess we need to rewrite the code and re-design the state management logic. For example, maybe this.loading doesn't make sense now, we need to track every request's state separately.

(Just some new thoughts)

Copy link
Member Author

@silverwind silverwind Jun 26, 2024

Choose a reason for hiding this comment

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

The ifs are meant to perform a partial state update if one of the two requests fails (which would be caught and show a toast).

Copy link
Member Author

Choose a reason for hiding this comment

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

But I see you are right, Promise.all can not deliver partial results, it either resolves both or rejects with the first encountered error, so my interpretion of the return value was wrong and the ifs are not needed.

@wxiaoguang
Copy link
Contributor

I can remove the toast code in favor of #31501 if you port all my changes from here (htmx and actions view preventDuplicates) into it.

I think #31501 could satisfy your requirement, it uses preventDuplicates=true and provides necessary visual feedback, so the htmx and actions view should work well without any change.

@silverwind
Copy link
Member Author

Ah, I see you went with the "default enabled" variant, so yes in this case we don't need to special-case these callers. I will remove all toast-related code from this commit.

@silverwind silverwind marked this pull request as draft June 26, 2024 13:58
@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jun 26, 2024

OK, I am sure the state management is not right now. See the duplicate lines:

image

image

That's my first worry in #31124 (review)

@pull-request-size pull-request-size bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 26, 2024
@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jun 26, 2024

@silverwind you edited my comment ...... (reverted)

To answer:

Got some steps how to reproduce that?

I think the reason is still related to the "force" behavior: to produce, make the backend sleep 500-1500ms to respond to make the edge cases could easily be triggered, then toggle the steps multiple times, then since you use force to reset the loading, then there are multiple requests in flight, then they get duplicate results.

@silverwind
Copy link
Member Author

Sorry, meant to reply. I will rework this later.

@wxiaoguang wxiaoguang removed the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Jun 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. modifies/js size/M Denotes a PR that changes 30-99 lines, ignoring generated files. type/bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants