grpc/grpc-dotnet

NotImplementedException when calling a grpc service from a WCF service under Windows Server 2019

CobraCalle opened this issue · 6 comments

What version of gRPC and what language are you using?

2.58

What operating system (Linux, Windows,...) and version?

Windows Server 2019

What runtime / compiler are you using (e.g. .NET Core SDK version dotnet --info)

.NET 4.8

What did you do?

If possible, provide a recipe for reproducing the error. Try being specific and include code snippets if helpful.

What did you expect to see?

We have a WCF-Service and this service tries to make a Grpc-Call to another service. Calling the grpc-server results in a NotImplementedException. But this is only the case when calling the grpc service out of a wcf-service running under Windows Server 2019. A test program (.NET 4.8 (same as our wcf-service)) can make the grpc call with out problems. Calling the service out of the wcd-service unter Windows Server 2022 or Windows 11 works fine too.

What did you see instead?

A NotImplementedException is thrown. Here is the stack trace:

CLRVersion..........: 4.0.30319.42000
ExceptionType.......: Grpc.Core.RpcException
ExceptionSource.....: mscorlib
ExceptionMessage....: Status(StatusCode="Internal", Detail="Error starting gRPC call. NotImplementedException: Die Methode oder der Vorgang ist nicht implementiert.", DebugException="System.NotImplementedException: Die Methode oder der Vorgang ist nicht implementiert.")
ExceptionTargetSite.: System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw
ExceptionStacktrace.:    bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
                         bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
                         bei ProtoBuf.Grpc.Internal.Reshape.<UnaryTaskAsyncImpl>d__16`2.MoveNext() in /_/src/protobuf-net.Grpc/Internal/Reshape.cs:Zeile 554.
                      --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
                         bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
                         bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
                         bei Diomex.Framework.Graphics.Omniverse.KitAgent.Client.KitAgentClient.<CreateProcessAsync>d__13.MoveNext()
                      --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
                         bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
                         bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
                         bei Diomex.Framework.Graphics.Omniverse.RenderSession`1.<TryRenderAsync>d__27.MoveNext()
                      --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
                         bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
                         bei Diomex.Framework.Graphics.ThreeD.Rendering.RenderSession`2.<>c__DisplayClass11_0.<<RenderInternal>b__2>d.MoveNext()
	ExceptionType.......: System.NotImplementedException
	ExceptionSource.....: Grpc.Core.Api
	ExceptionMessage....: Die Methode oder der Vorgang ist nicht implementiert.
	ExceptionTargetSite.: Grpc.Core.DeserializationContext.PayloadAsReadOnlySequence
	ExceptionStacktrace.:    bei Grpc.Core.DeserializationContext.PayloadAsReadOnlySequence()
	                         bei ProtoBuf.Grpc.Configuration.ProtoBufMarshallerFactory.ContextualDeserialize[T](DeserializationContext context) in /_/src/protobuf-net.Grpc/Configuration/ProtoBufMarshallerFactory.cs:Zeile 158.
	                         bei Grpc.Net.Client.Internal.StreamExtensions.<ReadMessageAsync>d__4`1.MoveNext()
	                      --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
	                         bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	                         bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	                         bei Grpc.Net.Client.Internal.GrpcCall`2.<ReadMessageAsync>d__98.MoveNext()
	                      --- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
	                         bei System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	                         bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	                         bei Grpc.Net.Client.Internal.GrpcCall`2.<RunCall>d__82.MoveNext()

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).

See TROUBLESHOOTING.md for how to diagnose problems better.

Anything else we should know about your project / environment?

It looks like this is a bug in protobuf-net.Grpc. It is calling into this method:

public virtual System.Buffers.ReadOnlySequence<byte> PayloadAsReadOnlySequence()
{
throw new NotImplementedException();
}

protobuf-net.Grpc hasn't implemented support for it.

Create an issue https://github.com/protobuf-net/protobuf-net.Grpc

cc @mgravell

The DeserializationContext here comes from the calling gRPC implementation (not protobuf-net.Grpc) - I'm very confused, but will look ASAP

Ditto DefaultDeserializationContext appears to implement this; question: what version of Grpc.Net.Client are you using? Edit: looks to be 2.58, my bad (read the post, Marc!)

@JamesNK this is weird; I don't think this is protobuf-net's fault; it feels like somehow we got a weird and unexpected context instance. The prebuilts have supported this since forever years ago; the best I can suggest here is for protobuf-net.Grpc to anticipate and catch this exception, and re-wrap it with a "context.GetType().AssemblyQualifiedName" hint in the message, so we know what we were given!

There is no feature discovery API for this - contexts are expected to support this usage (I seem to recall advocating for making it abstract, but I didn't win the discussion)

Or perhaps better: maybe the DeserializationContext base type should include this blame step when it throws the exception, i.e. throw new NotImplementedException("Feature not implemented by " + GetType().AssemblyQualifiedName) so at least we'd be able to see what we're dealing with

This usage dates back to 2019: #376

  • Option 1: I'm chasing shadows and looking at the wrong stuff entirely
  • Option 2: you somehow have an ancient dll; can you treble check that you have an active package reference to current bits? In particular, maybe check the assembly versions (internal metadata) of the Grpc.Core and protobuf-net.Grpc assemblies in your output folder?

Using a very old version of Grpc.Net.Client (or Grpc.Core, maybe your .NET Framework app is using an ancient version of Grpc.Core without you realizing it) is a likely cause.

@CobraCalle Please double check your app source code. If the source code says it is using the right version, check the assemblies that are actually deployed.