-
Notifications
You must be signed in to change notification settings - Fork 142
Fix mount points conflict causing empty project DLL in research environment #541
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
Fix mount points conflict causing empty project DLL in research environment #541
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thank you! This looks good, minor comment about the test below
tests/commands/test_research.py
Outdated
| temp_csproj_mounts = [ | ||
| m for m in kwargs["mounts"] | ||
| if m["Target"].startswith(f"/LeanCLI") and m["Target"].endswith(".csproj") | ||
| ] | ||
| # the following line does not run due to unknown reasons | ||
| # ./lean/components/docker/lean_runner.py:829: run_options["mounts"].append(Mount(target=f"/LeanCLI/{csproj_path.relative_to(compile_root).as_posix()}", | ||
| # assert len(temp_csproj_mounts) > 0, "No temporary csproj file mounts detected" | ||
| # assert all(m["Source"] != str(original_csproj) for m in temp_csproj_mounts), "Temporary csproj did not correctly overwrite user file" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/LeanCLI is mounted as a volume, not as a bind mount, you will find it kwargs["volumes"][{project name}] as a dictionary {'bind': '/LeanCLI', 'mode': 'rw'}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jhonabreul , thanks for your feedback!
I know /LeanCLI directory is mounted as volume, but /LeanCLI/<project_name>.csproj would be mounted using mounts, which was shown at run_options["mounts"].append(Mount(target=f"/LeanCLI/{csproj_path.relative_to(compile_root).as_posix()}", in above quoted line 315,
# ./lean/components/docker/lean_runner.py:829: run_options["mounts"].append(Mount(target=f"/LeanCLI/{csproj_path.relative_to(compile_root).as_posix()}",
That's why I am trying to access the *.csproj file from kwargs["mounts"].
What I commented from line 314 to 317 was trying to show, the code for mounting the /LeanCLI/<project_name>.csproj would not be run during mock test which would actually run if we launch the real image (that's how I figured out the solution). I also noticed _ensure_csproj_is_valid is never been called during mock tests even I run for all tests, and then I will add a new comment there for clarification to avoid any confusion.
…rch to keep consistent with docs
79a739c to
086310c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
I updated your unit test so that your commented assertions run.
Also the addition of Assembly.LoadFrom() was removed since I tested it and the notebook still needs the #r instruction to load the assembly. It won't work for Python notebooks either, so it would be better to find a more generic solution in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @efJerryYang! 🚀
Problem Description
When running
lean research, the/LeanCLIdirectory inside the Docker container was missing all.cssource files, leaving only an generated.csprojby the tool. This causeddotnet buildto emit the warningCS2008: No source files specified, resulting in an invalid project DLL (the content can be checked byilspycmd) placed in/Lean/Launcher/bin/Debug/that prevented referencing namespaced C# code of the project from Jupyter notebook.Root Cause
The Lean CLI attempted to mount the project directory to two paths in the container:
/LeanCLIfor C# compilation. This is needed for the correct compilation./Lean/Launcher/bin/Debug/Notebooksfor Jupyter Lab working directory. This is also needed for accessing the host project directory content directly.However, the
volumespython dict uses host paths as keys. Subsequent mounts overwrote earlier ones, leaving only the last mount (to/Lean/Launcher/bin/Debug/Notebooks) active.Additionally, the
_ensure_csproj_is_validmethod (called insideget_basic_docker_config) would generate temporary.csprojfiles and mounted them to/LeanCLI, which means we already have files mounted in/LeanCLIdirectory. Another relevant mount point that cause shadowing is theconfig.jsonfor theNotebooks/directory, therefore we'd better have the mounting forNotebooks/prior to any other mounting in theNotebooks/directory to ensure the shadowing working as expected.Expected Behavior
We need to have
/LeanCLIto be compatible with backtest/live, and allow it to compile the project DLL correctly. This compilation is still needed for research because in C# jupyter kernel, we can only load script files, those C# source files containingnamespaceare not allowed to be used directly in notebook cells and therefore can only be referenced by loading the corresponding project DLL. User can then run#r ../<project_name>.dllafter the#load "../QuantConnect.csx".Or even better, add a command to
commandsthen we canecho "Assembly.LoadFrom($project_name);" >> /Lean/Launcher/bin/Debug/QuantConnect.csxto load the DLL automatically. But I am not sure if this would break anything, so for simplicity didn't do that in this PR.Chosen Solution
Replaced
volumeswith explicitmountsfor the project directory and move the mounting logic prior to all otherNotebooksrelated mounting.