-
Couldn't load subscription status.
- Fork 4.9k
Better handle resx scenarios #38012
Better handle resx scenarios #38012
Conversation
There were two resx scenarios that we weren't handling well. 1. BinaryFormatted data that is missing the type information BinaryFormatted data never takes the type into account, it's only used to check the deserialized data after it's read. In the old resx reader it would deserialize the data in the build task, only to reserialize it back, recording the type information. Since we're eliminating build time deserialziation we cannot do this, so just permit the payload to flow through without recording the type information. This is effectively what happened before since the user never recorded the type information in the resx so it isn't introducing any new opportunity for inconsistencies. To implement this I used the existing ResX format with a sentinel type to indicate that the BinaryFormatter payload type was unknown. 2. Primitive types stored as string ResX reader deserialized all types during the build, we're trying to eliminate this as it results in build time / cross-framework type loading. In doing so we lose the ability to handle primitive types since the only way we currently write primitive types is when they are passed in as live objects. To fix this, we'll make the string-based type converter method aware of primitive types, and permit it to deserialize those primitive types (IOW: parse the string via typeconverter) so that we still write these as primitive resources. We'll rename this method to AddResource to indicate it is more generic than just handling pre-serialized data. To identify primitive types we use a string comparer to match the type name written in the resx, and map it to a known type (in the build framework).
|
@ViktorHofer have a look at this: https://mc.dot.net/#/user/dotnet-bot/pr~2Fdotnet~2Fcorefx~2Frefs~2Fpull~2F38012~2Fmerge/test~2Ffunctional~2Fcli~2Finnerloop~2F/20190529.1/workItem/System.Runtime.WindowsRuntime.Tests/wilogs. Tests passed but the job was fire-balled because some script activity after the test timed out. What is it doing? |
|
Linux musl failures all appear to be https://github.com/dotnet/core-eng/issues/6327. Which @MattGal is working on. |
@MattGal it seems you are doing additional logic after the test invocation which modifies the ExitCode. I thought you were capturing the ExitCode and set it at the end of the script but apparently that's not the case. |
|
@ViktorHofer yes, this is what is called a "timeout". That means the work item ran longer than it was expected to, and was killed. As a timed-out work item has no exit code, I had to pick one, which years ago I arbitrarily picked -3 for (as it doesn't match common Windows/Linux exit codes). We also send events to make it disambiguate-able from a real exit -3, though either is a failure. You can tell this from the logs: Common causes for this include variable-length work item timing, too-short of a timeout being set for a given work item, extreme network slowness, or issues with a service the work item is talking to. Guessing from the logs here something took a long time in test-reporter.py but it didn't keep logging. |
|
OK I didn't look into the py script. Thanks! |
|
I recognized this is a timeout, however the test itself finished with plenty of time left. The thing that timed out was a bunch of shady post-test activity involving installing python which I don't think is any of ours... Test log: Then in the run_client.py log: So whatever started after the test completed ran for another 10 minutes and eventually caused the test to be killed. |
|
@ericstj That's a good question for @alexperovich when he gets in, he wrote the test-reporter python script which comes from dotnet/arcade. Usually that script logs more to the console, but my most likely guess as to what could have gone wrong would be network slowness in the VSTS API, which is what this reporter script spends most of its time doing. From a Helix client's perspective it's currently a black box. You told it to do something and kill it if it ran > 15 minutes, it took > 15 minutes. I know there's an effort to make the VSTS API reporting occur outside your timeout, but I wouldn't expect this for about a month or so (as it will require a fair bit of plumbing and teaching the Helix client about VSTS) |
|
Looked to me like it was just spending 10 minutes installing python, but it could be that he just forgot to log anything from that script. |
|
That test reporter script needs to use pip to install the vsts package so it can talk to azure devops to report test results. If the network is having problems on that machine I can see that install taking 10 minutes. It is only done once per machine though so it won't happen again on the same machine. We could probably add some machine setup stuff to do this install when we setup the machines. |
That would be a good idea. |
src/System.Resources.Extensions/src/System/Resources/Extensions/PreserializedResourceWriter.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/PreserializedResourceWriter.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/PreserializedResourceWriter.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Outdated
Show resolved
Hide resolved
src/System.Resources.Extensions/src/System/Resources/Extensions/PreserializedResourceWriter.cs
Outdated
Show resolved
Hide resolved
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.
Other than my questions/Comments, LGTM
src/System.Resources.Extensions/src/System/Resources/Extensions/PreserializedResourceWriter.cs
Outdated
Show resolved
Hide resolved
| // directly add strings | ||
| if (primitiveType == typeof(string)) | ||
| { | ||
| AddResource(name, value); |
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.
This is interesting, since I have similar code in the resgen task. But that also has to handle the ResXFileRef->text file with specified encoding case, so I don't think I can just rely on this. I don't see a reason to not have it, though.
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.
My thought was that you can pretty much plumb the no-mime-type/non-ResXFileRef case straight through to this API. For mime-types and ResXFileRef you'll need to do some work in translating to different calls. Hopefully those can largely just pass the string value of the type through. Let me know if you have cases where those methods require "primitive type" knowledge.
src/System.Resources.Extensions/src/System/Resources/Extensions/TypeNameComparer.cs
Outdated
Show resolved
Hide resolved
| // Compare two type names ignoring version | ||
| // If a type name is missing assembly, we assume it came from mscorlib | ||
| // since this is what Type.GetType will do. | ||
| public bool Equals(string assemblyQualifiedTypeName1, string assemblyQualifiedTypeName2) |
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.
@benvillalobos, just making you aware of this. I suspect we're going to want to have a very similar spanified implementation in RAR at some point.
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.
Be careful about the mscorlib-isms and the missing name cases here. Those aren't so general purpose. Also note that I didn't bother improving the comparison of culture/key that could be done in a non-allocating way if you care about perf. Also this ignores version which RAR very much cares about. This is more of a reference and not a reusable bit of code.
| public void AddResource(string name, System.IO.Stream value, bool closeAfterWrite = false) { } | ||
| public void AddResource(string name, object value) { } | ||
| public void AddResource(string name, string value) { } | ||
| public void AddResource(string name, string typeName, string value) { } |
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.
I don't feel strongly about AddResource(string, string, string) versus AddTypeConverterResource(string, string, string) writing different things to the .resources file depending on the types involved. From my perspective, that's an implementation detail I don't deeply care about, but I don't mind the rename either.
Co-Authored-By: Rainer Sigwald <raines@microsoft.com>
|
Merging. If we get feedback on API we can address in mop up PR. |
Includes a darc subscription for System.Resources.Extensions and reaction to dotnet/corefx#38012: * AddResource(string,string,string) instead of removed AddTypeConverterResource * Stop specifying type for BinaryFormattedResource.
* Better handle resx scenarios There were two resx scenarios that we weren't handling well. 1. BinaryFormatted data that is missing the type information BinaryFormatted data never takes the type into account, it's only used to check the deserialized data after it's read. In the old resx reader it would deserialize the data in the build task, only to reserialize it back, recording the type information. Since we're eliminating build time deserialziation we cannot do this, so just permit the payload to flow through without recording the type information. This is effectively what happened before since the user never recorded the type information in the resx so it isn't introducing any new opportunity for inconsistencies. To implement this I used the existing ResX format with a sentinel type to indicate that the BinaryFormatter payload type was unknown. 2. Primitive types stored as string ResX reader deserialized all types during the build, we're trying to eliminate this as it results in build time / cross-framework type loading. In doing so we lose the ability to handle primitive types since the only way we currently write primitive types is when they are passed in as live objects. To fix this, we'll make the string-based type converter method aware of primitive types, and permit it to deserialize those primitive types (IOW: parse the string via typeconverter) so that we still write these as primitive resources. We'll rename this method to AddResource to indicate it is more generic than just handling pre-serialized data. To identify primitive types we use a string comparer to match the type name written in the resx, and map it to a known type (in the build framework). * Respond to feedback * Apply suggestions from code review Co-Authored-By: Rainer Sigwald <raines@microsoft.com> Commit migrated from dotnet/corefx@00c7405
There were two resx scenarios that we weren't handling well.
BinaryFormatted data never takes the type into account, it's only used
to check the deserialized data after it's read. In the old resx reader
it would deserialize the data in the build task, only to reserialize it
back, recording the type information. Since we're eliminating build
time deserialziation we cannot do this, so just permit the payload to
flow through without recording the type information. This is
effectively what happened before since the user never recorded the
type information in the resx so it isn't introducing any new opportunity
for inconsistencies. To implement this I used the existing ResX format
with a sentinel type to indicate that the BinaryFormatter payload type
was unknown.
ResX reader deserialized all types during the build, we're trying to
eliminate this as it results in build time / cross-framework type
loading. In doing so we lose the ability to handle primitive types
since the only way we currently write primitive types is when they
are passed in as live objects. To fix this, we'll make the string-based
type converter method aware of primitive types, and permit it to
deserialize those primitive types (IOW: parse the string via
typeconverter) so that we still write these as primitive resources.
We'll rename this method to AddResource to indicate it is more
generic than just handling pre-serialized data. To identify primitive types
we use a string comparer to match the type name written in the resx,
and map it to a known type (in the build framework).