Skip to content
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

Remove restrictions required by netstandard 1.x but available in 2.0 #3790

Merged

Conversation

heatonmatthew
Copy link
Contributor

@heatonmatthew heatonmatthew commented May 16, 2019

The serialization attribute, appdomains and cloneable interfaces are now supported in the netstandard2.0 libraries so can be re-enabled for dotnet core targets.

Also noticed that I included a fix in the TailChopping Router to catch AskTimeoutException and handle that in the same way as a TaskCanceledException. The associated unit test was routinely breaking without this change for me.

Building on work done in #3668

@Aaronontheweb
Copy link
Member

Thanks @heatonmatthew ! Just an FYI - you might get hit with some of these #3786 in the CI system. Known issue - not your fault. Going to be dealt with by #3788 and some other work our team is doing to clean up the test suite.

I'll look over this ASAP.

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a couple of questions, but overall looks really good

build.fsx Outdated
let outputBinariesNet45 = outputBinaries @@ "net45"
let outputBinariesNetStandard = outputBinaries @@ "netstandard1.6"
let outputBinariesNet45 = outputBinaries @@ "net452"
let outputBinariesNetStandard = outputBinaries @@ "netstandard2.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build.fsx changes look fine.

@@ -43,7 +43,6 @@ public AsyncReplayTimeoutException(string message)
{
}

#if SERIALIZATION
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't tell you how thrilled I am to get rid of this crap @heatonmatthew - so far, according to the CI system, the compiler and the test runtimes seem pretty happy with these changes so I don't have much to add on each individual change here.

@@ -106,20 +98,11 @@ internal static ConstructorInfo FindConfigConstructor(Type configUser)
var current = configUser;
while (current != null)
{

#if CORECLR
var ctorWithConfig = current
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably fine, but I'll need to see the feedback from the MNTR for certain

@@ -194,12 +194,8 @@ private void InstallCert()
}
finally
{
#if NET452 //netstandard 1.6 doesn't have close on store
store.Close();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@@ -34,7 +34,7 @@ public OnSubscribe(ISubscription subscription)
public override string ToString() => $"TestSubscriber.OnSubscribe({Subscription})";
}

public struct OnNext<T> : ISubscriberEvent
public struct OnNext<T> : ISubscriberEvent, IEquatable<OnNext<T>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I accidentally brought this across from a branch in which the FluentAssertions library had been upgraded. There were one or two tests that were failing in the assertion because there was no default comparer that worked correctly for these messages.

Probably best for me to remove this change for the time being?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's hurting anything, so no - you can leave it. Just wanted to make sure I wasn't overlooking something more gruesome (i.e. the entire Akka.Streams test suite exploded because equality was broken by some inexplicable platform change and this is the workaround.) But based on your explanation this sounds innocent enough. We'll keep it in.

// test which intermittently can fail because all messages are actually serviced
// by a single thread from the pool. Happens under load, presumably when the processor
// finds it more efficient to keep thread locality of the execution.
Thread.Sleep(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation - makes sense.

@@ -224,7 +222,7 @@ internal sealed class ThreadPoolExecutorServiceFactory : ExecutorServiceConfigur
/// <returns>TBD</returns>
public override ExecutorService Produce(string id)
{
#if APPDOMAIN
#if UNSAFE_THREADING
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
catch (AskTimeoutException)
{
completion.TrySetResult(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, is this your fix from your other PR @heatonmatthew ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is. Happy to remove it if you want them separated?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it's fine to keep it in. Just wanted to make sure I understood what it was.

@Aaronontheweb Aaronontheweb added this to the 1.4.0 milestone May 16, 2019
Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heatonmatthew answered my questions - looks good to me. Ready for merge once CI completes.

@heatonmatthew
Copy link
Contributor Author

@Aaronontheweb I've been doing some testing of the Akka.Persistence.SqlServer project building against a version of this branch. I've found an assumption in the Akka.Persistence.TCK.Journal.JournalSpec regarding JSON serialization that are not universally true that I think are worth mentioning.

The test is attempting to force JSON serialization to fail by implementing a test event as shown below:

        /// <summary>
        /// JSON serializer should fail on this
        /// </summary>
        private class NotSerializableEvent : ISerializable
        {
            public NotSerializableEvent(bool foo) { }

            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                throw new NotImplementedException();
            }
        }

Now that we are running this against a netcoreapp2.1 target, it fails consistently. Thinking it through, I'm a little dubious that the comment about the class failing JSON serialization makes complete sense (because JSON serialization is different to .NET runtime serialization). After playing around with this a bit, I think that the Newtonsoft library author actually agrees with me because the behavior differs between versions as follows:

Runtime Newtonsoft 9.x Newtonsoft 12.x
net452 Exception OK
netcore2.1 OK OK

I can't think of a scenario in which anyone would be relying on this behaviour in a real non-test application (i.e. deliberately trying to break JSON serialization) but I thought it's worth a broader ponder.

Now the tests can be easily fixed by changing the test class to the following.

        /// <summary>
        /// JSON serializer should fail on this
        /// </summary>
        private class NotSerializableEvent : ISerializable
        {
            public NotSerializableEvent(bool foo) { }

            public string Data => throw new NotImplementedException();

            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                throw new NotImplementedException();
            }
        }

Do you have any strong opinion about whether this is likely to be a broader concern?

@Aaronontheweb
Copy link
Member

I need to look at this again once I'm finished with the changes in #3744

@Aaronontheweb
Copy link
Member

@heatonmatthew regarding your earlier comment, can you link me to the test classes where this should fail? Trying to understand your comment from earlier.

@heatonmatthew
Copy link
Contributor Author

@Aaronontheweb sorry for the slow response. The test in question is Journal_optionally_may_reject_non_serializable_events.

In the master branch, the entire test including the NotSerializableEvent is not built for Dotnet Core because of a #if !CORECLR block. It was probably switched out for netcore originally because serialization wasn't supported at that time.

I removed the compiler directive in my branch which is probably why I'm seeing the error but the mainline tests aren't yet.

@Aaronontheweb
Copy link
Member

Got it, thanks @heatonmatthew - I'll see about getting this merged in ASAP. Going to re-run CI now with many of the other changes we've made.

@Aaronontheweb
Copy link
Member

For some reason our incremental build system isn't detecting any changes here - wonder if that has to do with build.fsx's changes. Let me investigate that.

@Aaronontheweb Aaronontheweb modified the milestones: 1.4.0, 1.4.1 and Later Feb 28, 2020
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.2, 1.4.3, 1.4.4 Mar 13, 2020
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.4, 1.4.5 Mar 31, 2020
@Arkatufus
Copy link
Contributor

Everything should pass now

serializationInfo.AddValue(field.Key, _wrappedPayloadSupport.PayloadFrom(field.Value));
var payload = _wrappedPayloadSupport.PayloadFrom(field.Value);
if (payload is ExceptionData exception)
payload = ExceptionFromProto(exception);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old code would fail if it encounters an Exception property inside an Exception, have to make sure that the serializer recurse through these

@@ -137,5 +149,8 @@ public Exception ExceptionFromProtoNet(Proto.Msg.ExceptionData proto)

return obj;
}

private string ValueOrNull(string value)
=> string.IsNullOrEmpty(value) ? null : value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default value for strings inside an Exception is null, have to convert proto empty strings to null to make a proper Exception object

if (_defaultProperties.Contains(info.Name)) continue;
if (info.Value is Exception exceptionValue)
{
var exceptionPayload = ExceptionToProto(exceptionValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old code would fail if it encounters an Exception property inside an Exception, have to make sure that the serializer recurse through these

@Arkatufus
Copy link
Contributor

Still need to test that exceptions in Akka.Cluster are serialized properly

@Aaronontheweb Aaronontheweb modified the milestones: 1.4.19, 1.4.20 Apr 21, 2021
@Aaronontheweb
Copy link
Member

Going to move this into 1.4.20 just because 1.4.19 is already quite a big release, but this looks good to me thus far

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Aaronontheweb Aaronontheweb enabled auto-merge (squash) May 3, 2021 22:59
@Aaronontheweb
Copy link
Member

@Arkatufus this test is now failing on every run (racily) on this PR since your changes:

ForkJoinExecutor should terminate all threads upon all attached actors shutting down

Please revert

@Aaronontheweb
Copy link
Member

@Arkatufus seeing this show up in the MNTR for .NET 5 / .NET Core 3.1

Failed to load test details for [Akka.Cluster.Tests.MultiNode.SingletonClusterWithAccrualFailureDetectorMultiNode] test class: System.IO.FileNotFoundException: Could not load file or assembly 'D:\a\1\s\src\core\Akka.MultiNodeTestRunner\bin\Release\net5.0\win10-x64\publish\Akka.Cluster.Tests.MultiNode.dll'. The system cannot find the file specified.
File name: 'D:\a\1\s\src\core\Akka.MultiNodeTestRunner\bin\Release\net5.0\win10-x64\publish\Akka.Cluster.Tests.MultiNode.dll'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)

That's why everything is running in 15 minutes. Any ideas on this?

@Aaronontheweb
Copy link
Member

Looks like it's working now - must have been an intermittent issue.

@Aaronontheweb Aaronontheweb merged commit 55c1175 into akkadotnet:dev May 10, 2021
This was referenced May 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants