You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: pages/architecture.md
+18-4Lines changed: 18 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,10 +4,10 @@
4
4
5
5
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:
6
6
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.
11
11
12
12
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.
13
13
@@ -26,3 +26,17 @@ The only messages the Expert server process handles directly are those related t
26
26
- Performing initialization and shutdown.
27
27
28
28
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