greasyfork-org / greasyfork

An online repository of user scripts.
https://greasyfork.org
GNU General Public License v3.0
1.43k stars 431 forks source link

[Bug] Update button leads to re-install of old version #1124

Closed adamlui closed 9 months ago

adamlui commented 1 year ago

For my latest update of https://github.com/adamlui/userscripts/blob/master/chatgpt/chatgpt-widescreen-mode/chatgpt-widescreen-mode.user.js from 2023.03.15.1 to 2023.03.17, GF (https://greasyfork.org/en/scripts/461473-chatgpt-widescreen-mode) appropriately reflected the change by updating the button, however clicking it leads to Tampermonkey trying to re-install old version.

When removing the script from TM and trying again, the same behavior persists:

https://user-images.githubusercontent.com/10906554/225956853-4195608d-ab35-47e7-9537-ced0de1b9ab3.mp4

adamlui commented 1 year ago

I just visited the GF page from my phone and the code tab shows the updated code (2023.03.17), however tapping install also still links to the old user.js (2023.15.1)

Screenshot_2023-03-17-09-20-08-66_3aea4af51f236e4932235fdada7d1643

JasonBarnabe commented 1 year ago

https://greasyfork.org/scripts/461473-chatgpt-widescreen-mode/code/ChatGPT%20Widescreen%20Mode%20%F0%9F%96%A5%EF%B8%8F.user.js currently serves up // @version 2023.03.18 for me. Does it seem to be working for you now? If so, probably a caching issue.

adamlui commented 1 year ago

Indeed it works now. The original caching issue seemed to be GF-side, since two different devices (albeit on same network) were served the old install link. Since the GF source tab properly updated, maybe something is glitched in the logic that update install link

adamlui commented 1 year ago

It's happening again for this one: https://greasyfork.org/en/scripts/461473-chatgpt-widescreen-mode

Button GF: image

Install screen when clicking it: image

This time phone tapping led to most recent version (but as I type this desktop is still cached).

The reason this issue is concerning, imagine how many users w/ caches that are really long periods (e.g. 30 days) would miss out on TM auto-updating critical versions that patch vulnerabilities. Maybe you can force-clear caches when user clicks or something. I asked ChatGPT for some tips:

You can control the caching behavior of a file by setting the appropriate HTTP headers on the server-side. For example, you can set the "Cache-Control" header to "no-cache" or "max-age=0" to indicate that the file should not be cached by the browser. This way, when the file is requested, the browser will check with the server to see if the file has been modified since the last time it was requested, and if so, it will download the updated file.

Yes, you can force the browser to clear the cache of a specific .js file on your website by appending a version or timestamp parameter to the file URL. For example, you can modify the URL of your .js file like this: '' or ''. In the first example, the "?v=1.0" parameter indicates the version number of the file. Whenever you make changes to the file, you can increment the version number to force the browser to download the updated version. In the second example, the "?t=202203280900" parameter indicates a timestamp of when the file was last modified. You can update the timestamp whenever you modify the file to force the browser to download the updated version. By appending a unique parameter to the file URL, the browser will treat it as a new file and fetch it from the server instead of using the cached version.

And this is the method ChatGPT taught me that works for me when serving requests for my JS lib (called 'cache busting'):

var jsURL = 'https://code.chatgptjs.org/chatgpt-latest.js?cache=' + new Date().getTime()

This URL param forces browser to send a server request even if cached copy exists on client

JasonBarnabe commented 1 year ago

Greasy Fork caches this content server-side, otherwise it'd never be able to keep up with all the update requests it gets. Adding a cache busting parameter would circumvent caching, which would fix your issue but crash the site.

Greasy Fork will cache the user.js for 60 minutes. It will also clear the cache when the script is updated. I believe the problem is that Greasy Fork is actually multiple servers, and while the one that received the update will clear the cache, the others won't.

adamlui commented 1 year ago

Greasy Fork will cache the user.js for 60 minutes. It will also clear the cache when the script is updated

It's happening again, 45mins since update in both TM + VM in Firefox 112.0.2 (64-bit):

image image

JasonBarnabe commented 9 months ago

Greasy Fork is now using a CDN for these requests (e.g. https://update.greasyfork.org/scripts/1.user.js), which eliminates the need for the 60 minute cache I mentioned previously.

There is some caching going on at the CDN (because that's what it's for), but when you update a script, we tell the cache to invalidate the paths for that script. When I tested this, it took under a minute for the CDN to get the updated version.

People who previously installed a script from greasyfork.org rather than update.greasyfork.org may still see odd behaviour like this, but I'll put in a redirect or something to make that work once I am confident the CDN is working as expected.

adamlui commented 9 months ago

Ok sounds promising, do I need to change my download/update url metas (which currently link to .meta.js and .user.js of old gf install button link) in my GitHub repos for those who install by clicking raw but I still wanted to receive updates thru gf?

JasonBarnabe commented 9 months ago

I'm still working out the kinks of the new system, so it is subject to change. You'll probably want to eventually, but I suggest waiting for now.

adamlui commented 9 months ago

Oops I already changed them all over an hour ago, I really liked how clean the URLs were and couldn't resist

adamlui commented 9 months ago

An idea for even more improved semantics is

https://update.greasyfork.org/scripts/473439.meta.js https://install.greasyfork.org/scripts/473439.user.js

or

https://update.greasyfork.org/scripts/473439.js https://install.greasyfork.org/scripts/473439.js

JasonBarnabe commented 9 months ago

Per discussion in https://greasyfork.org/en/discussions/greasyfork/211213-what-are-the-current-requirements-for-script-urls, the filename is important for debugging/logging purposes, so now the format is:

adamlui commented 9 months ago

It looked cleaner when it was https://update.greasyfork.org/scripts/1.user.js but if filename is important, usually sites do URLs like /id-semantic-name instead of /id/semantic-name because /id/[something-else] sounds like [something-else] could be one of many things related to the script, but in this case it is either a [script-name.user.js] or [version-num/script-name.user.js] so the [something-else] is not very parallel

adamlui commented 9 months ago

Also I see you are eliminating customizability of name, but that was quite neat so I could shorten links where names had extra descriptors I didn't need in the URL (or sometimes to only go by ID if ultra cleanliness was the objective)

Also if script name meta ever changes, past links no longer work (for example if some new feature was added author wants to emphasize in title)

adamlui commented 9 months ago

For example GitHub current and past ver raw URLs are

https://github.com/KudoAI/duckduckgpt/raw/main/greasemonkey/duckduckgpt.user.js https://github.com/KudoAI/duckduckgpt/raw/c5146872a096d42cff33d9fb0c9d30f644023997/greasemonkey/duckduckgpt.user.js

So the [something-else] is very parallel, has same number of subpaths, is very logical to deduce structure of potential other URLs

For GF URLs it could emulate this parallelism by

https://(code|raw).greasyfork.org/scripts/1/current/GreasemonkeyTampermonkeyViolentmonkey%20test%20style.user.js https://(code|raw).greasyfork.org/scripts/1/ver/GreasemonkeyTampermonkeyViolentmonkey%20test%20style.user.js

(I suggest replacing 'update' subdomain since install clicks aren't updates, but code/raw makes sense for both install or update clicks)

JasonBarnabe commented 9 months ago

I'm not interested in discussing the beauty of URLs, but if there are actual problems with the format in use now, please let me know.

Also if script name meta ever changes, past links no longer work (for example if some new feature was added author wants to emphasize in title)

Renaming the script is not a problem. The "filename" is ignored by the site; you can put whatever you want, ex: https://update.greasyfork.org/scripts/1/This%20is%20not%20the%20name%20of%20the%20script.user.js.

adamlui commented 9 months ago

I'm not interested in discussing the beauty of URLs

"Beauty" is not the primary benefit of parallelism, as mentioned, "is very logical to deduce structure of potential other URLs" if parallel. For example, a script stops working after update, user can deduce structure to roll back until last working version (by clearly deducing 'current' is replacable with the working ver) so this is usabiilty not beauty benefit (they can't do this with current structure)

Renaming the script is not a problem. The "filename" is ignored by the site; you can put whatever you want, ex: https://update.greasyfork.org/scripts/1/This%20is%20not%20the%20name%20of%20the%20script.user.js.

I said meta name updates (which I've done before and URLs didn't break) not filename, and this changes GF's default install/update url filename which is no longer customizable, so authors who include GF URLs in-code have to make updates now

adamlui commented 9 months ago

OK, I will restore having the script name in the URL for this reason. I'm not going to make it customizable, though; I can't see any reason why you'd want it different than the script name.

This is the statement that led me to believe I can no longer type [update-url-leading-up-to-filename]/[whatever-i-want-as-long-as-it-included-id].user.js, is my understanding wrong? What do you mean you will not "make it customizable"?

JasonBarnabe commented 9 months ago

"Customizable" meaning you (as an author) can enter your preferred filename somewhere on Greasy Fork's UI and then Greasy Fork will use that filename as the default install URL for its green button. I'm not doing that, and the site has never supported that.

As stated above, the filename is irrelevant to the site. Both https://update.greasyfork.org/scripts/1/Original%20name.user.js and https://update.greasyfork.org/scripts/1/New%20name.user.js serve up the same content. Old URLs do not break if the script is renamed.

adamlui commented 9 months ago

Ok I don't know why you thought anyone would want to suddenly have a new UI method to input a custom filename to use as default URL for green button, that didn't seem to be a natural urge and why I read your statement that way. Back to the first issue, do yo use see now parallelism is not for beauty but utility, and why GitHub and other sites follows this concept?

adamlui commented 9 months ago

Actually beauty is a benefit too, but utility is the primary reason it is adhered to. It is not actually a "problem" as you insinuated will be the only reason you will change the structure, I'm just pointing out the benefits and very little cost to implement (just adding /current)

adamlui commented 9 months ago

It's your site though, I am a mere user, who am I to suggest ways to make it better, you can do what you want, it's not a problem

adamlui commented 9 months ago

i.e. I will use whatever URL you dictate with no problem since I make like 100+ commits a day. it's the others who don't update often that potentially face breaking changes (but if necessary change is made, it's best to make it solid from the start)

JasonBarnabe commented 9 months ago

Old URLs will not break.

adamlui commented 9 months ago

Redirects from https://greasyfork.org/scripts/459849/code/duckduckgpt.user.js will still up the Update Checks graph stats then? Also will it be forever redirecting? Also I'm curious to know what your concern is with making new structure parallel

adamlui commented 9 months ago

Actually I just clicked it it stopped working

adamlui commented 9 months ago

I tested from Mobile too just now Screenshot_20231112-173836

JasonBarnabe commented 9 months ago

This was an oversight - the format of the new URLs was conflicting with the format of the old. I've fixed it.

adamlui commented 9 months ago

Ok

JasonBarnabe commented 9 months ago

The new system seems to be working but will likely lead to excessive CDN costs due to the number of requests that it would process. I may need to switch back to the old system, but will likely keep the new URL format as that has other benefits.

adamlui commented 9 months ago

Ok

JasonBarnabe commented 9 months ago

With 2b871b3cee96f4e41e2163a82814e66a4931ebd5, this should be fixed on update.greasyfork.org. After a script is updated, it will take 1 minute maximum to clear the cache and start serving out the new version.