Uh oh!
There was an error while loading. Please reload this page.
Allow runtimeconfig StartupHooks and Environment StartupHooks to both be present - #61461
Conversation
ghost
commented
Nov 11, 2021
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsWhen building/running an app via our Bazel build implementation we rely on a startup hook for assembly loading. We specify this in the runtimeconfig.json as a configProperty STARTUP_HOOKS. When another startup hook is bootstrapped via the environment variable DOTNET_STARTUP_HOOKS this results in the following error: In our case this environment variable is added by the IDE to handle net6.0 HotReloading. Technically it is allowed to specify multiple startup hooks with a delimiter. This pull request resolves above error by merging startup hooks when they are specified in both locations. Since I rarely visit C++ a detailed review is very welcome. I could not find any existing tests for this code path to extend/replicate but have tested that it resolves my issue. I have also taken the opportunity to fix some log_duplicate_property_errors that mistakenly list the StartUpHooks property key.
|
vitek-karas
left a comment
There was a problem hiding this comment.
Looks good on the product side. We should add a test. The tests for startup hooks are here: https://github.com/dotnet/runtime/blob/main/src/installer/tests/HostActivation.Tests/StartupHooks.cs
(The host tests are a bit tricky to run - please take a look here: https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/host/testing.md)
Thanks a lot for this!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
vitek-karas
commented
Nov 11, 2021
Question unrelated to the PR: |
tomdegoede
commented
Nov 11, 2021
Our build tool (Bazel) doesn't copy dependencies to the output directory but instead lists their paths in a App.runfiles_manifest. To properly resolve the dll's at runtime we add a startup hook that registers Resolve handlers on AssemblyLoadContext.Default. In many scenarios we could register this via the environment variable, but in some cases (such as running tests from the IDE) this would be quite a hassle. The App.runtimeconfig.json of the target binary is always considered and thus fixes assembly loading in all cases. It also allows us to run I'll look into the feedback. Thanks for the quick reply! |
…_HOOKS" to both be present
tomdegoede
commented
Nov 15, 2021
@vitek-karas I have added tests and reused the predefined PATH_SEPARATOR. |
vitek-karas
left a comment
There was a problem hiding this comment.
Looks great - thanks a lot!
vitek-karas
commented
Nov 17, 2021
Hmm - thinking about the order. I wonder if it would be better to run the env. variable hooks first. In other places (for example roll forward) the env. variable takes precedence over runtime config. Typically the order of startup hooks should not matter as they should not make assumptions about other possible startup hooks. But in reality that's not always the case, as typically the thing starting the process also "owns" the startup hook and sets up the env. variable accordingly. I lean toward having the startup hooks from the env. variable run BEFORE those from the runtime config. @sbomer, what do you think? |
tomdegoede
commented
Nov 17, 2021
I think the env hook is already executed first since I append the existing config_startup_hooks to the env string_t. This was however not an explicit decision, nor do the tests currently validate it. |
sbomer
commented
Nov 17, 2021
Agreed, the env var should win, since the original design was addressing situations in which modifying deployed bits in the runtimeconfig was not an option. |
vitek-karas
commented
Nov 18, 2021
So we're in agreement, env. variable startup hooks should run before the runtime config ones.
Running the app will run both startup hooks, first the "VariableHook" and then the "RuntimeConfigHook" (and then the The code in this PR already works this way. Testing it will be a bit tricky, we don't have test helpers to test for order of messages in the output. The simplest way would be to grab the entire test output and implement the validation manually (search for first, and then search again from that point for the second). I think we should try to add a test for this, it's an important detail and it's easy to break in the future if the code changes. Please add a comment into the code that the order is intentional. |
tomdegoede
commented
Nov 18, 2021
@vitek-karas I have updated the testcase to consider stdOut order and added a comment in the code path. Please let me know if there is anything else to improve! Thanks :) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
8bb9a9c to
2be584fCompareUh oh!
There was an error while loading. Please reload this page.
2be584f to
faba436Compare
vitek-karas
left a comment
There was a problem hiding this comment.
@sbomer, can you please check the code as well (just to make sure, since this is both fix and tiny design change in one 😉)
tomdegoede
commented
Nov 19, 2021
@vitek-karas small beginners question: will this end up in an upcoming patch version for net6 or only in the next net7? Ideally our issue is resolved in net6. |
vitek-karas
commented
Nov 19, 2021
Currently the On its own I like this - specifically because of hot-reload using startup hooks. That said, this is the first time I've heard anybody specifying startup hooks in the runtimeconfig. I'll ask others how they would feel about this.. currently for me, it probably doesn't feel important enough to include in servicing. But there might be different expectations for some of the future servicing releases of .NET 6, so maybe that will change. |
agocke
commented
Nov 19, 2021
This looks like a good fix to me. Low risk, addresses an oversight in startup hooks specified through two different mechanisms. |
agocke
commented
Nov 19, 2021
/backport to release/6.0 |
Started backporting to release/6.0: https://github.com/dotnet/runtime/actions/runs/1482464925 |
agocke
commented
Nov 19, 2021
uhhh ?? @terrajobst assistance with the above? |
tomdegoede
commented
Nov 23, 2021
@agocke@terrajobst would be great if backporting is accepted! Thanks! |
terrajobst
commented
Nov 23, 2021
terrajobst
commented
Nov 23, 2021
Yeah, we're just figuring out how to convince our tooling first :-) |
agocke
commented
Nov 29, 2021
/backport to release/6.0 |
Started backporting to release/6.0: https://github.com/dotnet/runtime/actions/runs/1514956550 |
agocke
commented
Nov 29, 2021
/backport to release/6.0 |
Started backporting to release/6.0: https://github.com/dotnet/runtime/actions/runs/1515112560 |
When building/running an app via our Bazel build implementation we rely on a startup hook for assembly loading. We specify this in the runtimeconfig.json as a configProperty STARTUP_HOOKS.
When another startup hook is bootstrapped via the environment variable DOTNET_STARTUP_HOOKS this results in the following error:
In our case this environment variable is added by the IDE to handle net6.0 HotReloading.
Technically it is allowed to specify multiple startup hooks with a delimiter. This pull request resolves above error by merging startup hooks when they are specified in both locations.
Since I rarely visit C++ a detailed review is very welcome. I could not find any existing tests for this code path to extend/replicate but have tested that it resolves my issue. I have also taken the opportunity to fix some log_duplicate_property_errors that mistakenly list the StartUpHooks property key.