aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.Core/Internal/AsyncCallBase.cs')
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs50
1 files changed, 29 insertions, 21 deletions
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 4d20394644..3e2c57c9b5 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -33,10 +33,12 @@
using System;
using System.Diagnostics;
+using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
+
using Grpc.Core.Internal;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
@@ -50,6 +52,7 @@ namespace Grpc.Core.Internal
internal abstract class AsyncCallBase<TWrite, TRead>
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>();
+ protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message.");
readonly Func<TWrite, byte[]> serializer;
readonly Func<byte[], TRead> deserializer;
@@ -100,11 +103,10 @@ namespace Grpc.Core.Internal
/// <summary>
/// Requests cancelling the call with given status.
/// </summary>
- public void CancelWithStatus(Status status)
+ protected void CancelWithStatus(Status status)
{
lock (myLock)
{
- Preconditions.CheckState(started);
cancelRequested = true;
if (!disposed)
@@ -177,6 +179,11 @@ namespace Grpc.Core.Internal
return false;
}
+ protected abstract bool IsClient
+ {
+ get;
+ }
+
private void ReleaseResources()
{
if (call != null)
@@ -224,33 +231,31 @@ namespace Grpc.Core.Internal
return serializer(msg);
}
- protected bool TrySerialize(TWrite msg, out byte[] payload)
+ protected Exception TrySerialize(TWrite msg, out byte[] payload)
{
try
{
payload = serializer(msg);
- return true;
+ return null;
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured while trying to serialize message");
payload = null;
- return false;
+ return e;
}
}
- protected bool TryDeserialize(byte[] payload, out TRead msg)
+ protected Exception TryDeserialize(byte[] payload, out TRead msg)
{
try
{
msg = deserializer(payload);
- return true;
+ return null;
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured while trying to deserialize message.");
msg = default(TRead);
- return false;
+ return e;
}
}
@@ -319,6 +324,9 @@ namespace Grpc.Core.Internal
/// </summary>
protected void HandleReadFinished(bool success, byte[] receivedMessage)
{
+ TRead msg = default(TRead);
+ var deserializeException = (success && receivedMessage != null) ? TryDeserialize(receivedMessage, out msg) : null;
+
AsyncCompletionDelegate<TRead> origCompletionDelegate = null;
lock (myLock)
{
@@ -331,23 +339,23 @@ namespace Grpc.Core.Internal
readingDone = true;
}
+ if (deserializeException != null && IsClient)
+ {
+ readingDone = true;
+ CancelWithStatus(DeserializeResponseFailureStatus);
+ }
+
ReleaseResourcesIfPossible();
}
- // TODO: handle the case when error occured...
+ // TODO: handle the case when success==false
- if (receivedMessage != null)
- {
- // TODO: handle deserialization error
- TRead msg;
- TryDeserialize(receivedMessage, out msg);
-
- FireCompletion(origCompletionDelegate, msg, null);
- }
- else
+ if (deserializeException != null && !IsClient)
{
- FireCompletion(origCompletionDelegate, default(TRead), null);
+ FireCompletion(origCompletionDelegate, default(TRead), new IOException("Failed to deserialize request message.", deserializeException));
+ return;
}
+ FireCompletion(origCompletionDelegate, msg, null);
}
}
} \ No newline at end of file