Update review list right after user posting/revoking#670
Update review list right after user posting/revoking#670yiningwang11 wants to merge 46 commits intoeclipse:masterfrom
Conversation
|
Thanks for your contribution @yiningwang11. It works as expected. I think it would be better to use the ETag header instead of fixed duration caching or no caching at all. It's a combination of creating an ETag of the JSON response: caching the response: openvsx/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java Lines 109 to 116 in 962947c and evicting the cache at the right time: |
|
Thank you for your suggestion. I'll continue look into it :) |
|
|
||
| return ResponseEntity.ok() | ||
| .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic()) | ||
| .cacheControl(CacheControl.noCache().cachePublic()) |
There was a problem hiding this comment.
I wonder if there is a better way of replacing the cache instead of disabling it altogether? cc @amvanbaren
Otherwise I'm good with the changes
There was a problem hiding this comment.
I wonder if there is a better way of replacing the cache instead of disabling it altogether?
Yes, a combination of server caching and generating an ETag for the response. If the request contains the If-None-Match header and the value matches the ETag value, then no content (204) is returned because the client already has the most up to date response. #670 (comment)
| protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { | ||
| // limit the filter to /api/{namespace}/{extension}, /api/{namespace}/details | ||
| // and /api/{namespace}/{extension}/{version} endpoints | ||
| // and /api/{namespace}/{extension}/{version}, and /api/-/search endpoints |
There was a problem hiding this comment.
@yiningwang11 Why generate an ETag for the /api/-/search endpoint?
There was a problem hiding this comment.
Hi, @amvanbaren thanks for the review!
I added this to generate an ETag for the response because I have disabled the cache for the search endpoint that returns the homepage. I thought with an ETag coming with the response header, even though the cache is disabled, no content would still be returned if the client has the up-to-date response.
There was a problem hiding this comment.
@yiningwang11 Ok, that's true. The downside is that the search is fully processed. Only at the end the ShallowEtagHeaderFilter compares the If-None-Match request header with the hash of the JSON body and discards the body if the two Etags match.
On the other hand #542 caches search results on the server side, so this approach will work. I'll test #542 and merge it in.
| public ExtensionJson getExtension(String namespace, String extensionName, String targetPlatform, String version) { | ||
| var extVersion = findExtensionVersion(namespace, extensionName, targetPlatform, version); | ||
| var json = toExtensionVersionJson(extVersion, targetPlatform, true, false); | ||
| var extension = repositories.findExtension(extensionName, namespace); |
There was a problem hiding this comment.
Please remove this statement, because you don't have to set averageRating here.
| var json = toExtensionVersionJson(extVersion, targetPlatform, true, false); | ||
| var extension = repositories.findExtension(extensionName, namespace); | ||
| json.downloads = getDownloads(extVersion.getExtension(), targetPlatform, extVersion.getVersion()); | ||
| json.averageRating = extension.getAverageRating(); |
There was a problem hiding this comment.
Please remove this statement, because averageRating is already set in ExtensionVersion.toExtensionJson.
There was a problem hiding this comment.
Hello @amvanbaren , thanks for your comment!
The reason that I set averageRating here is because I found out in ExtensionVersion.toExtensionJson, the averageRating is not updated immediately according to deleting/posting new reviews with new ratings of an extension. However, the extension.averageRating is being updated correctly in time. That's why I put an extra statement here to update the averageRating.
There was a problem hiding this comment.
Ok, I see what you mean. I went through the code to find out how this could happen. The VersionService caches the latest ExtensionVersion. When a review is posted or deleted your fork doesn't evict the latest version cache, which causes findExtensionVersion to return a cached instance of the lastest ExtensionVersion with an old Extension instance (averageRating not updated).
This has been fixed in master. Can you sync your master branch and rebase the updateReview branch? Then the extra database call shouldn't be necessary anymore.
You can sync the master branch by clicking Sync fork in the right corner of your Github repo:

After syncing your fork you can rebase by opening a terminal in your openvsx directory and following these steps:
git checkout master
git pull
git checkout updateReview
git rebase master
<FIX CONFLICTS & COMMIT>
git rebase --continue
git push -f origin updateReview
There was a problem hiding this comment.
Hello @amvanbaren , thanks for your suggestion!
I've followed these commands but seems like git push -f origin updateReview has caused one of the checks to be failing. It looks like one of the authors of the commits is not covered by the ECA. I'm not sure if that's gonna affect anything, or what should I do to fix this?
Thank you again for your help :)
There was a problem hiding this comment.
Hi @yiningwang11, it looks like you merged openvsx:master on top of your updateReview branch. yiningwang11:master is still 70 commits behind eclipse:master.

A rebase changes the base of the branch, but the changes you've made stay on top. This article explains it in further detail: https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase. The example under the Usage heading describes what we try to do here.
Are the top 5 commits for this feature or were there more commits?

There was a problem hiding this comment.
Hello @amvanbaren , thanks for your comment! I went over the article you recommended. Is this because I should have sync my yiningwang11:master branch and then rebase the updateReview feature branch, instead of merge the openvsx:master on top of my updateReview feature branch?
Is there anything I can do to make things right at the moment?
The top 5 commits in the screenshot you shared were for this feature, there aren't any more commits yet. (I'm still working on adding the @Cacheable annotation on LocalRegistryService.getReviews now)
Thank you :)
There was a problem hiding this comment.
Is this because I should have sync my yiningwang11:master branch and then rebase the updateReview feature branch, instead of merge the openvsx:master on top of my updateReview feature branch?
Yes, it is so that this feature is current with master. This ensures that you don't run into issues that already have been fixed in master and that there are no conflicts when this branch is merged into master.
Is there anything I can do to make things right at the moment?
Yes, you can use git rebase to drop the unwanted commits.
First, do git stash to store your current changes.
Then set VS Code as your default git editor. You can skip this step if you're familiar with vim.
git config core.editor "code --wait"
Next, do an interactive rebase on your updateReview branch. I see this PR has 46 commits. If you have more commits locally then increase the number in the below command, e.g. you've added 2 more commits, then the number becomes 48.
git rebase -i HEAD~46
You get a list of commits. You need to keep the first 5 commits and if you've added extra commits since this PR you want to keep those too. All the other commits in between you want to drop.

When you're 100% sure (you can't undo this operation) which commits to keep and which to drop, close the editor. The rebase is applied and the commits from the merge with master should be gone.
Force push updateReview
git push -f origin updateReview
If you used git stash, you can use git stash apply to get your local working changes back.
| .map(e -> { | ||
| var entry = e.getValue().toSearchEntryJson(); | ||
| entry.url = createApiUrl(serverUrl, "api", entry.namespace, entry.name); | ||
| entry.averageRating = repositories.findExtension(entry.name, entry.namespace).getAverageRating(); |
There was a problem hiding this comment.
Please remove this statement, because averageRating is already set in ExtensionVersion.toSearchEntryJson.
There was a problem hiding this comment.
I added this statement due to the same reason. I found ExtensionVersion.toSearchEntryJson is not updating averageRating attribute according to deleting/posting reviews with new ratings.
| protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { | ||
| // limit the filter to /api/{namespace}/{extension}, /api/{namespace}/details | ||
| // and /api/{namespace}/{extension}/{version} endpoints | ||
| // and /api/{namespace}/{extension}/{version}, and /api/-/search endpoints |
There was a problem hiding this comment.
@yiningwang11 Ok, that's true. The downside is that the search is fully processed. Only at the end the ShallowEtagHeaderFilter compares the If-None-Match request header with the hash of the JSON body and discards the body if the two Etags match.
On the other hand #542 caches search results on the server side, so this approach will work. I'll test #542 and merge it in.
| try { | ||
| return ResponseEntity.ok() | ||
| .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic()) | ||
| .cacheControl(CacheControl.noCache().cachePublic()) |
There was a problem hiding this comment.
@yiningwang11 Can you also make LocalRegistryService.getReviews @Cacheable? Please make sure to evict entries from the cache when a review is added (LocalRegistryService.postReview) or deleted (LocalRegistryService.deleteReview) and when UserData changes in UserService.updateExistingUser
There was a problem hiding this comment.
@amvanbaren I'll take a look into this. Thank you!
| applyFilter = path[2].contains("search"); | ||
| } | ||
| if(applyFilter && path.length == 4) { | ||
| applyFilter = !(path[3].equals("review") || path[3].equals("reviews")); |
There was a problem hiding this comment.
Please keep applyFilter = !(path[3].equals("review");, because I think we don't want to use ETags when a review is added or deleted.
rebase branch "updateReview" onto branch "master"
* Access token dialog improvements * Set focus on the Copy button --------- Co-authored-by: amvanbaren <aart.vanbaren@eclipse-foundation.org>
* Search bar improvements * Remove 'Space' key in extension-list-header.tsx Change charCode 13 to key 'Enter' in namespace-input.tsx --------- Co-authored-by: amvanbaren <aart.vanbaren@eclipse-foundation.org>
Fixes eclipse#427 Change Namespace Evict caches Update search entries
Fixes eclipse#452 Added UpstreamProxyService Add url rewriting to UpstreamVSCodeService.java # Conflicts: # server/src/main/java/org/eclipse/openvsx/UpstreamRegistryService.java # server/src/main/java/org/eclipse/openvsx/adapter/UpstreamVSCodeService.java
Update extension publicId of already published extensions when a new extension has the same publicId
Use react-helmet to make <head> tags configurable through pageSettings for homepage, extension and namespace pages Simplify header tags Pass params instead of only name
bump webui version # Conflicts: # webui/package.json
Add possibility to delay running migrations, so that deployment can finish before migrations run
Added FixTargetPlatformMigration Remove extensionFile at end of a migration Don't run migrations in mirror mode
Improve social links UX
Use timestamp in namespace logo to bust browser cache
Currently copy-pasting some commands with smart quotes results in errors. Replace all the smart quotes with straight quotes for consistency. Signed-off-by: David Xia <david@davidxia.com>
server: move files to new namespace in background job webui: show confirmation dialog, instead of loading new namespace
Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.76.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](webpack/webpack@v5.75.0...v5.76.0) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com>
Merge namespace members Return error if namespaces contain duplicate extensions
668438a to
082d053
Compare
|
@yiningwang11 I've opened PR #761. It contains your changes and clears the cache when a review is posted or deleted. |


fixes #613
The review list is not updated because it always gets loaded from the disk cache. Making the 'getReviews' always get data from the registry instead of from the cache fixes this issue.