-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
internal runtime API to return hot reload capabilities #50111
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
/cc @tmat @mikem8361 @tommcdon |
That looks weird. I think we should define this just in term of the possitive capabilities. Is there a reason why not just use a flags enum for this? |
Potential alternative design is to avoid introducing a new API for this and just use the existing |
The assumption was that there wouldn't be that many negative and the set would be empty for .NET Framework/.NET 5.
64 might not be enough bits. |
It would be useful to see the full set we expect to add for .NET 5.
This should not be called HotReload. We have dropped "HotReload" from the apply delta API as well. |
For .NET 5, it would be an empty set - the same as .NET Framework. For Mono we are discussing the set here: dotnet/roslyn#49010 (comment). Something like: |
Good question. I think that would need to be special-cased as "nothing is supported". |
For reference, here are all the current rude edits. They do not map to metadata edits directly, but you can get sense of what is reported. |
Can you paste it here once the full set of capabilities is determined?
It does not sound that bad to me (vs. having to keep explaining till forwever the reason behind the possitive/negative split). |
Sure. In time the negative ones become obsolete as Mono implements more features. The same happens with Roslyn's Rude Edits. We obsolete them as we allow more edits. The problem with listing everything that should be enabled is also that we'd need to implement each of the positive capability in Roslyn - we can't assume that certain capabilities are always present. With negative ones it's much easier - we only need to revisit reporting rude edits that are affected by something that Mono does not have. We don't need to revisit every single rude edit and condition it based on a set of positive capabilities. |
You do not have to. You can check whether the baseline is available, and disable all edits if it is not. |
By "baseline" you mean .NET 5 - Mono 6? We could do that. Seems useless then to list capabilities in two places and subtract them, essentially ignoring them. I guess another way of doing this would be to have a single capability |
So, how about this?
(exact names TBD) |
I assume that .NET 6 would also include everything in .NET 5 bucket. Also, is the list really exactly the same between .NET 5 and .NET Framework? I thought that made some EnC improvements in .NET Core. Sounds reasonable (exact names TBD). |
Yes, fixed. |
I am not aware of any (so far). |
Updated the proposal with summary of the above discussion: positive flags; .NET5 CoreCLR - .NET 6 MonoVM as |
How is the hotreload agent going to use this API? I assume that it will just enumerate everything, serializes it and sends it over to the manager to inform the compiler. That makes me think - would it be better just have an API that returns string?
The string can be space separated list. The exact names are not visible in the API surface so making them pretty is less important. I think the negatives that were in the original proposal would be acceptable in this case (e.g. prefix the name with minus). And you do not have to go through API review and documentation for every EnC improvement. |
A string would be fine with me. |
I do not think we want to attach trimming of the hot reload support to the capabilities string. It should be separate - already tracked by #51159. |
We feel that rather than string tokenization this should just be a flags enum. partial class RuntimeFeatures
{
[Flags]
public enum AssemblyUpdateFeatures : long
{
None = 0,
RuntimeEdits = 1 << 0,
AddDefinitionToExistingType = 1 << 1,
...
}
public static AssemblyUpdateFeatures AssemblyApplyUpdateCapabilities { get; }
} is what got doodled during the discussion, those names weren't really discussed. |
As @jkotas pointed out a string has benefits over enum. Beside those that Jan mentioned the components consuming this API do not target .NET 6, so there is no real value in making the values strongly typed. We will need to parse the values from strings/int anyways. |
Does this actually need to be a public API? Can this be just an internal API, called via private reflection, just like the hot reload update handlers? |
In the API review, the feedback I heard was:
I don't think there's a technical need for it to be public. |
Then let's just keep it internal and return string. We have a ton of internal surface to support debuggers, so an internal method like this would not be an outlier. |
If it's going to be internal, I prefer to make it a method, rather than a property (easier to call from reflection), and also move it to |
Adding infrastructure for hot reload testing. For each test we define a new library assembly project. The `.csproj` has a `DeltaScript` property that specifies a JSON file that lists the name of an initial source file, and a list of updated versions of that file. The `hotreload-delta-gen` tool runs during the build to read the delta script and create deltas that incorporate the updates. The main testsuite references all the test assemblies, and when a test runs, it calls `ApplyUpdateUtil.ApplyUpdate` to load subsequent deltas and then compares the results before and after an update. Dependencies: - https://github.com/dotnet/hotreload-utils the `hotreload-delta-gen` binary must be installed and on the PATH (TODO: package it as a dotnet tool and publish to a transport nuget package) Needs work: - Mono test runs need to pass the `FEATURE_MONO_METADATA_UPDATE` property to msbuild to the test project. This is because not every mono configuration includes hot reload support. Eventually this should be subsumed by the runtime API to querty hot reload capabilities dotnet#50111 - All runs need to pass `DOTNET_MODIFIABLE_ASSEMBLIES=debug` to the testsuite. Hot reload only works when: - the assemblies are compiled with the Debug compiler setting, - and, if the runtime is tarted with the above environment variable set. - The GenerateHotReloadDeltas.targets needs some output file work to run `hotreload-delta-gen` less frequently. Right now it runs every time even if everything is up to date. For CI testing we should ideally compile the deltas ahead of time once. To try it out locally: 1. checkout and build `hotreload-utils` and do `dotnet publish --self-contained -r <RID>` to put `hotreload-delta-gen` into that projects' `artifacts/...` forlder. Add the publish folder to your `$PATH` 2. In dotnet/runtime run ``` DOTNET_MODIFIABLE_ASSEMBLIES=debug MONO_ENV_OPTIONS=--interp ./dotnet.sh build src/libraries/System.Runtime.Loader/tests /p:MonoMetadataUpdate=true /t:Test ``` (CoreCLR doesn't need `MONO_ENV_OPTIONS` or `MonoMetadataUpdate`)
MonoVM and CoreCLR will both support hot reload in .NET 6. However the actual set of supported (non-"rude") edits are different between the runtimes. In future releases the capabilities of both runtimes will evolve. Part of #44806 and #45629
Related roslyn issue: dotnet/roslyn#49010
In a hot reload editing session, the runtime and the Roslyn compiler (mediated by a communication mechanism such as
dotnet watch
or the Visual Studio debugger) will need to agree on the supported edits.One approach would be to build into Roslyn the knowledge of the capabilities of each runtime based on the reported runtime version. However in this case it would be difficult to mix compiler and runtime versions. Also if the runtime wants to disable an edit in a servicing release, it would require closely coupling servicing releases of (potentially several) Roslyn versions and the runtime.
Another approach is to expose a new API implemented by the runtime that returns a list of the supported capabilities:
The specific format of the return value would be implementation defined and in practice it would be a contract between the runtimes and Roslyn.
Example of capabilities description
(This is for illustration only and not part of the API definition)
For example the string might be a space separated sequence of tokens from the following set:
Baseline
,RuntimeEdits
,AddDefinitionToExistingType
,NewTypeDefinition
. The proposal is to represent .NET 5 CoreCLR capabilities asBaseline
plus everything that .NET 5 CoreCLR can do minus what .NET 6 MonoVM can do. That is, .NET 5 MonoVM would be represented by the empty set of capabilities, .NET 5 CoreCLR asBaseline
plus everything that CoreCLR can do that .NET6 Mono cannot. In future releases, as MonoVM catches up it will start returningAddDefinitionToExistingType
(for example). In future releases when one or both runtimes add a new capability, it will be added to the enumeration. In summary:"Baseline AddDefinitionToExistingType NewTypeDefinition "
(and ... TBD based on Mono capabilities )"RuntimeEdits"
""
"Baseline RuntimeEdits"
The text was updated successfully, but these errors were encountered: