Skip to content

Commit 4978972

Browse files
authored
docs: add project versions docs to architecture.md (#52)
1 parent be65605 commit 4978972

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

pages/architecture.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
Expert is designed to keep your application isolated from Expert's code. Because of this, Expert is structured as an umbrella app, with the following sub-apps:
66

7-
* `forge`: Contains all code common to the other applications.
8-
* `engine`: The application that's injected into a project's code, which
9-
gives expert an API to do things in the context of your app.
10-
* `expert` The language server itself.
7+
- `forge`: Contains all code common to the other applications.
8+
- `engine`: The application that's injected into a project's code, which
9+
gives expert an API to do things in the context of your app.
10+
- `expert` The language server itself.
1111

1212
By separating expert into sub-applications, each is built as a separate archive, and we can pick and choose which of these applications (and their dependencies) are injected into the project's VM, thus reducing how much contamination the project sees. If Expert was a standard application, adding dependencies to Expert would cause those dependencies to appear in the project's VM, which might cause build issues, version conflicts in mix or other inconsistencies.
1313

@@ -26,3 +26,17 @@ The only messages the Expert server process handles directly are those related t
2626
- Performing initialization and shutdown.
2727

2828
All other messages are delegated to a _Provider Handler_. A _Provider Handler_ is a module that defines a function of arity 2 that takes the request to handle and a `%Expert.Configuration{}`. These functions can reply to the request, ignore it, or do some other action.
29+
30+
## Project Versions
31+
32+
Expert releases are built on a specific version of Elixir and Erlang/OTP(specified at `.github/workflows/release.yml`). However, the project that Expert is being used in may be on a different version of Elixir and Erlang/OTP. This can lead to incompatibilities - one particular example is that the `quote` special form may call internal functions in elixir that are not present in the version of Elixir that Expert is built on and viceversa, leading to crashes.
33+
34+
For this reason, Expert compiles the `engine` application on the version of Elixir and Erlang/OTP that the project is using. At a high level the process is as follows:
35+
36+
1. Find the project's elixir executable, and spawn a vm with it that compiles the `engine` application.
37+
2. Namespace the compiled `engine` app, return the path to the compiled `engine` to the `expert` manager node, and exit.
38+
3. Gather the paths to the compiled `engine` app files, spawn a new vm with the project's elixir executable, and load the `engine` app into that vm.
39+
40+
We use two separate vms(one for compilation, one for actually running the `engine` app) to ensure that the engine node is not polluted by any engine code that might have been loaded during compilation. We currently use `Mix.install` to compile the `engine` app, which loads the `engine` code into the compilation vm. Spawning a new vm for the engine node ensures that the engine node is clean.
41+
42+
The compiled `engine` application will be stored in the user's "user data" directory - `~/.local/share/Expert/` on linux, `~/Library/Application Support/Expert/` on macOS, and `%appdata%/Expert` on Windows.

0 commit comments

Comments
 (0)