-
-
Notifications
You must be signed in to change notification settings - Fork 293
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
Artifacts to proxy&cache CDNs #241
Comments
All these assets are cached by a service worker, so the second load should even work offline! So the uncompressed files and HTTP1 overhead for the larger number of files isn't really a problem. Improvements to the first load time are welcome of course, but they might be overshadowed by Julia compiling Pluto's methods. There is still the use case of deploying Pluto notebooks online - this would be useful there. |
But I am very interested in the artifacts system - do you think we can use it to make our project independent of the CDNs? Ideally you could run an old version of Pluto 20 years from now, when (JS hype has moved on to something else and) some of these CDNs might have gone offline. Because Pluto is scientific software - these CDNs are commercial. |
Ah, that makes sense, yes. I was working on a tethered phone, so it took many seconds to fetch those resources the first time. A pathological case for sure.
Yes, definitely! I'd be happy to help you walk through it; the short version is that you would run a script to bundle together your content and upload it as a tarball. Then in |
It would be great to use artifacts for this for the reasons mentioned but there might be some other surprise benefits as well. For example, making Pluto work better in places like China which like to block some CDNs (including google fonts, at least in the past.) |
Thanks everyone! I am definitely interested, but I still have some questions:
|
Yes. It's possible to build a "hybrid system" that downloads the assets via Artifacts on 1.3 and through some other mechanism on 1.0-1.2, but IMO it's not worth the effort and maintenance burden.
Hard to say, but the volume of users asking for help with binary issues on Julia 1.3 has dropped off significantly, so my guess is that the majority of users are 1.3+ at this point.
How often does the bundle change? I was under the impression that this was a "generate once, forget about it for a few months" kind of thing. If it changes rapidly, then perhaps we'll need a different solution; a Travis job to rebuild it after every commit and automatically update the |
That's true, only about 1-2 times per month. What would a manual solution look like? A second repository that just contains releases, that I upload myself? |
Precisely; the way I usually do it is to have a script somewhere that, when run, bundles everything together then uploads it to a GitHub release somewhere. It could be I tend to use function upload_to_github_releases(repo, tag, path; gh_auth=Wizard.github_auth(;allow_anonymous=false),
attempts::Int = 3, verbose::Bool = false)
for attempt in 1:attempts
try
ghr() do ghr_path
run(`$ghr_path -u $(dirname(repo)) -r $(basename(repo)) -t $(gh_auth.token) $(tag) $(path)`)
end
return
catch
if verbose
@info("`ghr` upload step failed, beginning attempt #$(attempt)...")
end
end
end
error("Unable to upload $(path) to GitHub repo $(repo) on tag $(tag)")
end And heres's how an artifact is created, archived (e.g. turned into a tarball) and bound to an # Create artifact (which is a folder in `~/.julia/artifacts`)
treehash = create_artifact() do dir
# write your files into <dir> here
end
# Archive artifact into tarball and upload it to GHR
local tarball_hash
filename = "WebAssets-1.0.0.tar.gz"
mktempdir() do dir
tarball_hash = archive_artifact(hash, joinpath(dir, filename))
BinaryBuilder.upload_to_github_releases(repo, tag, dir)
end
# Bind artifact to Artifacts.toml that needs to go into your package:
bind_artifact!(
"./Artifacts.toml",
# This is the name of the artifact; you'll get the path of the locally-installed files via `artifact"WebAssets"` in your package
"WebAssets",
treehash,
download_info = Tuple[
("https://github.com/$(repo)/releases/download/$(tag)/$(filename)", tarball_hash),
],
) |
Thanks so much! Your examples are very helpful. I am motivated to incorporate this to ensure that old versions of Pluto can stay online for "ever". (In response to @c42f: thank you for bringing this up, I hadn't thought about access in China. I did find that the EDIT: Google Fonts are now also served over jsdelivr. |
My laptop is giving errors when trying to load these files from the cdn. I have no idea what this means. Please see this screenshot: https://i.imgur.com/k3u64Qc.png |
@ArrowRaider have a look here: #607 (comment) And you are right that browser extension problems are solved by a proxy. |
I'm going to fork things and try and make this work. I work on offline computers all day long and would really like to be able to use Pluto! This is what I've got going so far.. I'm just working through the repo searching for urls. The one thing I'm not certain about is the best way to serve the static files once they're downloaded into the artifacts dir.
|
I think you might want to create a single artifact from all those files (instead of N artifacts for N files) and lay out the files within that artifact in such a way that Pluto has an easy time pointing at them (e.g. putting the |
Also, I'm not sure why you're removing the file from the artifact with that I also think your calculation of |
I would say, serve all notebooks by URL-encoding their URL. e.g. serve
under
so that the artifact has a flat folder structure and the backend is as uncomplicated as possible. Use the serviceworker to redirect requests to their proxied version. Also note that we want to minimize the maintenance burden for future frontend development. We change the asset dependencies very often, and ideally the artifact system is fully automated. (One idea is to use puppeteer to extract the network log of a Pluto session -- that also gives you indirect dependencies.) |
I found that we can use a pre-release hook to trigger a github action before the release is created: https://github.com/JuliaRegistries/TagBot#pre-release-hooks This will happen after our patch is merged into the general registry, but before the release it tagged in this repository. Users only get the "update is available!" message after we tag the release. However, if we are using the Artifacts system, then we would need to generate the artifact before we register our patch into the general registry, because we need to mention it in our Artifacts.toml file, right? |
Almost implemented in #1125 , except right now all assets are in the Pluto repository, which I don't like. Can someone use artifacts to store the assets? |
I can confirm that it is not blocked in China (Beijing) right now. But unfortunately, it is blocked under the corp network recently 😢 |
We are still tweaking offline support before we release it, current TODOs: |
It would be nice for startup time (especially on a slow connection) to bundle all web assets locally; if this is a relatively slowly-moving target, this can be done easily by using Artifacts; simply write a script that collects all files into a single location inside of
create_artifact()
, archive the artifact into a tarball, upload that tarball somewhere, bind the location of the artifact to a name in your package, and you'll be able to serve the files from a tarball that gets downloaded at the same time as your package.As a reference, these are the assets that my browser requests after a force-refresh on Pluto
v0.11.1
:The text was updated successfully, but these errors were encountered: