See comments on issue #3: Pending questions shall fail when connection is broken.

Adjusted required version of .NET Core runtime from 2.2 to 2.1
This commit is contained in:
Christian Köllner 2019-07-07 17:12:49 +02:00
parent 97eb340261
commit eaecfda35e
5 changed files with 77 additions and 8 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace Capnp.Net.Runtime.Tests namespace Capnp.Net.Runtime.Tests
{ {
[TestClass] [TestClass]
public class TcpRpcAdvancedStuff: TestBase public class TcpRpcAdvancedStuff : TestBase
{ {
[TestMethod, Timeout(10000)] [TestMethod, Timeout(10000)]
public void MultiConnect() public void MultiConnect()
@ -88,5 +88,37 @@ namespace Capnp.Net.Runtime.Tests
} }
} }
} }
[TestMethod, Timeout(10000)]
public void ClosingServerWhileRequestingBootstrap()
{
for (int i = 0; i < 100; i++)
{
var server = SetupServer();
var counters = new Counters();
var tcs = new TaskCompletionSource<int>();
server.Main = new TestInterfaceImpl(counters, tcs);
using (var client = SetupClient())
{
Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout));
using (var main = client.GetMain<ITestInterface>())
{
server.Dispose();
// Resolution must either succeed or be cancelled. A hanging resolution would be inacceptable.
try
{
Assert.IsTrue(((IResolvingCapability)main).WhenResolved.Wait(MediumNonDbgTimeout));
}
catch (AggregateException)
{
}
}
}
}
}
} }
} }

View File

@ -751,7 +751,19 @@ namespace Capnp.Net.Runtime.Tests
using (var main = client.GetMain<ITestMoreStuff>()) using (var main = client.GetMain<ITestMoreStuff>())
{ {
var resolving = main as IResolvingCapability; var resolving = main as IResolvingCapability;
if (!resolving.WhenResolved.Wait(MediumNonDbgTimeout))
bool success;
try
{
success = resolving.WhenResolved.Wait(MediumNonDbgTimeout);
}
catch
{
success = false;
}
if (!success)
{ {
if (++retry == 5) if (++retry == 5)
{ {
@ -917,13 +929,24 @@ namespace Capnp.Net.Runtime.Tests
label: label:
using (var client = new TcpRpcClient("localhost", TcpPort)) using (var client = new TcpRpcClient("localhost", TcpPort))
{ {
Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout));
using (var main = client.GetMain<ITestMoreStuff>()) using (var main = client.GetMain<ITestMoreStuff>())
{ {
var resolving = main as IResolvingCapability; var resolving = main as IResolvingCapability;
if (!resolving.WhenResolved.Wait(MediumNonDbgTimeout))
bool success;
try
{
success = resolving.WhenResolved.Wait(MediumNonDbgTimeout);
}
catch
{
success = false;
}
if (!success)
{ {
if (++retry == 5) if (++retry == 5)
{ {

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -97,7 +98,14 @@ namespace Capnp.Rpc
{ {
_exportTable.Clear(); _exportTable.Clear();
_revExportTable.Clear(); _revExportTable.Clear();
_questionTable.Clear();
foreach (var question in _questionTable.Values.ToList())
{
question.OnException(new RpcException("RPC connection is broken. Task would never return."));
}
Debug.Assert(_questionTable.Count == 0);
_answerTable.Clear(); _answerTable.Clear();
_pendingDisembargos.Clear(); _pendingDisembargos.Clear();
} }

View File

@ -38,9 +38,15 @@ namespace Capnp.Rpc
{ {
async void SetupCancellation() async void SetupCancellation()
{ {
using (var registration = cancellationToken.Register(promisedAnswer.Dispose)) try
{
using (var registration = cancellationToken.Register(promisedAnswer.Dispose))
{
await promisedAnswer.WhenReturned;
}
}
catch
{ {
await promisedAnswer.WhenReturned;
} }
} }