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

Allow Mix.install/2 to run several times in the same instance #12293

Open
josevalim opened this issue Dec 8, 2022 · 4 comments
Open

Allow Mix.install/2 to run several times in the same instance #12293

josevalim opened this issue Dec 8, 2022 · 4 comments

Comments

@josevalim
Copy link
Member

josevalim commented Dec 8, 2022

The process should be roughly like:

  1. Create a new directory for the new installation
  2. Run mix deps.get
  3. Compare the versions and see which entries were added or removed
  4. Run a fixpoint computation until we find all application that depends on something that was added or removed
  5. Stop all apps, unload all modules, and remove all code paths for previous dependencies + consolidated protocols
  6. Copy the _build and deps entries for the ones that did not change
  7. Continue as usual

/cc @wojtekmach

@josevalim josevalim added this to the v1.15 milestone Dec 8, 2022
@josevalim josevalim modified the milestones: v1.15, v1.16 May 10, 2023
@josevalim josevalim removed this from the v1.16 milestone Oct 14, 2023
@thbar
Copy link
Contributor

thbar commented Jan 2, 2024

Coming from:

Something increasingly useful I'm doing for prototyping of feature is: use the trick described in https://github.com/livebook-dev/livebook/blob/main/lib/livebook/notebook/learn/intro_to_livebook.livemd#elixir-integration-and-use-cases to re-use the main app config & dependencies inside an otherwise standalone "exs" script, but add a couple extra dependencies in the same Mix.install/2 call for prototyping purposes.

This is very useful to give birth to complicated features that will require all the app context, but delay the inclusion of dependencies until the last required moment, something that is cleaner in terms of maintenance IMO.

Having incremental compilation here would be especially useful, because we otherwise recompile the "whole app" each time we add one dependency on the script calling Mix.install/2 directly.

Is the current issue about that, or something bigger? Thank you!

@lukaszsamson
Copy link
Contributor

This is something that would be beneficial for language servers as well. ElixirLS already has custom (and most certainly buggy) implementation of steps 2-5

@josevalim
Copy link
Member Author

josevalim commented Jan 2, 2024

@thbar this issue is about that, yeah. :)

@lukaszsamson I am not sure how applicable this is outside of Mix.install. The issue with Mix.install is that it compiles everything from scratch on each new dependency and the main goal of this task is to minimize that.

For an actual project, which Elixir LS is running on, you are not compiling everything from scratch, so the benefits are minimal. Plus, in all measurements I have performed, stopping all applications, removing all modules, and pruning all code paths was always slower (and bug proner) than restarting the app. For Elixir LS, I would consider isolating the app runtime from the language server itself, so you have more flexibility of when to restart the runtime.

It may be that we use a similar solution for Mix.install/2. Instead of allowing it to run multiple times, we can simply allow a previous install directory to be used as a reference (and then still restart the runtime).

@josevalim
Copy link
Member Author

#13378 implements a simpler version of this that will allow us to test how easy deps are to migrate.

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

No branches or pull requests

3 participants