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

Make WebIO statically compilable (relocatable): don't run include()s in __init__ #378

Merged
merged 3 commits into from
Jan 8, 2020

Conversation

NHDaly
Copy link
Contributor

@NHDaly NHDaly commented Dec 31, 2019

If you statically compile an application that uses WebIO, it will attempt to run this Module init at runtime, but of course those source files will no longer be present once the application has been downloaded to a user's computer.

Please see these sections from the PackageCompilerX for an overview of relocatability:

(I made this code change months ago but never sent it for review, so i don't remember what the errors were. But rereading the diff, it seems reasonable. I'll rebase and update it now..)

…s in __init__

For example, now this still works correctly:
```julia
julia> which(Base.isopen, (WebIO.WSConnection,))
isopen(p::WebIO.WSConnection) in WebIO at /Users/nathan.daly/.julia/dev/WebIO/src/providers/generic_http.jl:13
```
@NHDaly
Copy link
Contributor Author

NHDaly commented Dec 31, 2019

@travigd Can i request a review from you? 😁


Updated to use include_string instead of eval so that the filenames are still preserved, exactly as if it was a normal include:

julia> which(Base.isopen, (WebIO.WSConnection,))
isopen(p::WebIO.WSConnection) in WebIO at /Users/nathan.daly/.julia/dev/WebIO/src/providers/generic_http.jl:13

@codecov
Copy link

codecov bot commented Dec 31, 2019

Codecov Report

Merging #378 into master will increase coverage by 0.18%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #378      +/-   ##
==========================================
+ Coverage    62.1%   62.29%   +0.18%     
==========================================
  Files          16       16              
  Lines         599      602       +3     
==========================================
+ Hits          372      375       +3     
  Misses        227      227
Impacted Files Coverage Δ
src/WebIO.jl 80.95% <100%> (+3.17%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e261042...915c36c. Read the comment docs.

@twavv
Copy link
Member

twavv commented Jan 1, 2020

Does this work with frontends? The JavaScript is still just static files that we include on the JS side for the most part.

I'm not familiar enough with the package compilation to even know where to begin with answering that. 🤓

@NHDaly
Copy link
Contributor Author

NHDaly commented Jan 2, 2020

Does this work with frontends? The JavaScript is still just static files that we include on the JS side for the most part.

I don't fully understand the question, unfortunately. What do you mean "the frontends"?

Anyway, I think this shouldn't change anything for normal julia execution.. we're just preloading the strings from the files during precompilation, and evaling them at runtime, instead of reading the files at runtime. This is needed because for a "shipped" executable, those files are no longer present at runtime.

But other than that, there should be no change! :)

@twavv
Copy link
Member

twavv commented Jan 2, 2020

(preamble: I know nothing about the package compilation stuff so these might be rather basic questions and/or represent a faulty understanding of how things work)

My concern (or uncertainty, I guess) is around how the package compilation process will handle asset files.

For example, in Blink, we have some static JS and HTML and CSS files and they're references at runtime. For example, whenever a window is loaded, we require the WebIO JS bundle, which lives at ~/.julia/packages/WebIO/packages/webio/dist/webio.js (or something like that). We use the pretty standard (afaict) way of referencing them:

const packagepath = normpath(joinpath(@__DIR__, "..", "packages"))

My question is whether or not that is going to cause issues when we try to load it.

src/WebIO.jl Outdated Show resolved Hide resolved
@NHDaly
Copy link
Contributor Author

NHDaly commented Jan 2, 2020

Ah, thanks for explaining. Yes, that is definitely a problem as well! 😁

The ApplicationBuilder.jl package has some infrastructure set up to let you list "assets" like these, which get copied into the final .app bundle, and then you have to manually add some code in your project that says basically if _is_static_compiled_() @eval WebIO const packagepath = "assets/webio/packages" or wherever you had them moved to. It's super hacky and dumb, but this is how it is for now.

However, that doesn't work for things that are referenced in the __init__() function of a module, because the __init__() is run before your code gets a chance to override the path! So basically, the rule is that references to absolute paths from within __init__() functions are hostile to relocatability of Applications. (Thus, this PR)


That said, the ultimate best approach would probably be to make any assets like that into Artifacts through Julia's new Artifacts system, since those are totally path-agnostic and relocation-friendly, but I dunno if that would be overkill for something like what you're describing...

@twavv
Copy link
Member

twavv commented Jan 2, 2020

I have no opposition to making assets into artifacts (though ideally, I'd like to keep compatibility with Julia 1.0 - I'm not sure if that's an issue?).

I don't really want to do that work myself though. :^)

Copy link
Member

@twavv twavv left a comment

Choose a reason for hiding this comment

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

LGTM.

@NHDaly
Copy link
Contributor Author

NHDaly commented Jan 2, 2020

Yeah agreed. And i'd say there isn't really much reason to. For those who care about it, the hacks i described above are mostly good enough for now...

@shashi
Copy link
Member

shashi commented Jan 8, 2020

Nice PR! :-)

About frontend assets, @ranjanan once got an app to compile. The main idea is to keep the assets in some path and setup a const like @NHDaly showed, then AssetRegistry.register them in __init__, or just use them in Scopes so it's automatic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants