dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.07k stars 2.03k forks source link

Type string "Orleans.Providers.IMemoryStreamQueueGrain" cannot be resolved #2597

Closed galvesribeiro closed 7 years ago

galvesribeiro commented 7 years ago

Using latest code in master this exception happens when GrainClient.Initialize() is called:

Type string "Orleans.Providers.IMemoryStreamQueueGrain" cannot be resolved. image

I've never used that type :(

Silo config:

private static int InitializeOrleans(string deploymentId, string connectionString)
    {
        var config = new ClusterConfiguration();
        config.Globals.DataConnectionString = connectionString;
        config.Globals.DeploymentId = deploymentId;
        config.AddAzureTableStorageProvider();
        config.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.AzureTable;
        config.Globals.ReminderServiceType = GlobalConfiguration.ReminderServiceProviderType.AzureTable;
        config.Defaults.TraceFileName = "";
        config.Defaults.PropagateActivityId = true;
        config.Defaults.Port = 22222;
        config.Defaults.ProxyGatewayEndpoint = new IPEndPoint(IPAddress.Any, 11111);

        hostWrapper = new OrleansHostWrapper(config);
        return hostWrapper.Run();
    }

Client initialization:

static void InitializeOrleans(string deploymentId, string connectionString)
    {
        var config = new ClientConfiguration();
        config.DataConnectionString = connectionString;
        config.DeploymentId = deploymentId;
        config.PropagateActivityId = true;
        config.GatewayProvider = ClientConfiguration.GatewayProviderType.AzureTable;

        do
        {
            Console.WriteLine("Initializing...");
            GrainClient.Initialize(config);
            Thread.Sleep(500);
        } while (!GrainClient.IsInitialized);

        Console.WriteLine("Initialized!");
    }

StackTrace:


   at Orleans.Serialization.SerializationManager.ResolveTypeName(String typeName)
   at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, IDeserializationContext context)
   at GrainInterfaceDataDeserializer(Type , IDeserializationContext )
   at Orleans.Serialization.ILBasedSerializer.Deserialize(Type expectedType, IDeserializationContext context)
   at Orleans.Serialization.SerializationManager.FallbackDeserializer(IDeserializationContext context, Type expectedType)
   at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, IDeserializationContext context)
   at Orleans.Serialization.BuiltInTypes.DeserializeDictionary[K,V](Type expected, IDeserializationContext context)
   at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, IDeserializationContext context)
   at GrainInterfaceMapDeserializer(Type , IDeserializationContext )
   at Orleans.Serialization.ILBasedSerializer.Deserialize(Type expectedType, IDeserializationContext context)
   at Orleans.Serialization.SerializationManager.FallbackDeserializer(IDeserializationContext context, Type expectedType)
   at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, IDeserializationContext context)
   at Orleans.Serialization.BuiltInTypes.DeserializeOrleansResponse(Type expected, IDeserializationContext context)
   at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, IDeserializationContext context)
   at Orleans.Serialization.SerializationManager.Deserialize(Type t, BinaryTokenStreamReader stream)
   at Orleans.Runtime.Message.DeserializeBody(List`1 bytes)
   at Orleans.Runtime.Message.get_BodyObject()
   at Orleans.Runtime.GrainReference.ResponseCallback(Message message, TaskCompletionSource`1 context)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Orleans.GrainClient.InternalInitialize(ClientConfiguration config)
   at Program.InitializeOrleans(String deploymentId, String connectionString) in c:\users\gutem\documents\visual studio 2017\Projects\OrleansESTest\ESAPI\Program.cs:line 38
   at Program.Main(String[] args) in c:\users\gutem\documents\visual studio 2017\Projects\OrleansESTest\ESAPI\Program.cs:line 16

If we remove this line on the silo config config.AddAzureTableStorageProvider(); the exception doesn't happen (and ofc some other happen when activating a grain that require the storage provider).

This is the latest build from 2.0 TP release and include @sebastianburckhardt PR for Journaled grains.

The workaround suggested by @ReubenBond to add the Providers nuget and access any type in order to force it to load didn't worked.

Anyone has an idea on what could be happening? I wonder if that happens because of lack of some configuration for the Journaled grains. Maybe @sebastianburckhardt could jump in.

cc: @ReubenBond / @benjaminpetit

benjaminpetit commented 7 years ago

I tried the sample app you sent me (.net core 1.1), and it also fails on my machine, but because it cannot find some dll.

Do you reproduce this issue with the "full" .net?

galvesribeiro commented 7 years ago

@benjaminpetit I didn't tried on .net full framework. Only on .Net core. What dll are you missing? it works fine here if I add the hack @ReubenBond suggested (add the Providers dll)

benjaminpetit commented 7 years ago

After cleaning/reinstalling .net standard stuff, I have the same issue than you. I am trying to debug right now

galvesribeiro commented 7 years ago

Great! Ping me on Gitter or Skype if you need anything @benjaminpetit

benjaminpetit commented 7 years ago

I repro the current issue with Visual Studio RC and .net standard, but not with VS 2015 using full dotnet. It might simply be an issue with the current tooling?

galvesribeiro commented 7 years ago

@benjaminpetit I don't think so. The error happen in runtime, so no tooling is involved...

jdom commented 7 years ago

Could there be a regression with #2266? I believe that .NET Core apps are failing to start the client if not all of the grain interfaces in the silo are known to the client. Nevertheless, if you look at the code for GrainInterfaceData there is a [NonSerialized] attribute applied to the interface Type, which is probably the type failing to resolve while deserializing:

        [Serializable]
        internal class GrainInterfaceData
        {
            [NonSerialized]
            private readonly Type iface;
        // ...
      }
ReubenBond commented 7 years ago

@jdom I think you're right - I'll fix it

The attribute is not emitted in the resulting IL, it's a flag on the field - I'll see if I can achieve the correct behavior.

jdom commented 7 years ago

FWIW, @benjaminpetit tried to repro this in full .net replacing the fallback serializer with the ILBasedSerializer, and the GrainInteraceData did not try to serialize and deserialize that field, so it might be a difference in how it works in .NET Core. BTW, we should have some test coverage using a silo for end to end serialization using the ILBasedSerializer (because this might be an issue with the NETStandard version of the library, not necessarily just .NET Core).

ReubenBond commented 7 years ago

@jdom yes, I believe it's a discrepancy. I was looking at the IL code when @galvesribeiro was building Orleans on a Mac and wanted me to verify the codegen. It's not an ILBasedSerializer bug, it's more general than that. I get the feeling that .NET Core behavior changed from under us.

I've assigned myself and will investigate further - unless @benjaminpetit wants to do it?

jdom commented 7 years ago

yes, this is probably related to the fact that BinaryFormatter as well as this attribute (and SerializerAttribute) are defined in the System.Runtime.Serialization.Formatters package, which can optionally be included, so it means that the Type system isn't as integrated with it as in full .NET.