Clearly indicated that 'isTailCall' parameter of Proxy.Call is obsolete. It never had any influence, since tail calls are automatically induced (somewhere else).

This commit is contained in:
Christian Köllner 2019-11-06 18:48:25 +01:00
parent 51ecd00e82
commit 5f97d69f79
14 changed files with 48 additions and 50 deletions

View File

@ -141,7 +141,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, false)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -182,7 +182,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, false)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -223,7 +223,7 @@ namespace Capnp.Net.Runtime.Tests
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
CancellationToken ctx; CancellationToken ctx;
using (var answer = main.Call(0x1234567812345678, 0x3333, args, false)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -267,7 +267,7 @@ namespace Capnp.Net.Runtime.Tests
args.WriteData(0, 123456); args.WriteData(0, 123456);
CancellationToken ctx; CancellationToken ctx;
IPromisedAnswer answer; IPromisedAnswer answer;
using (answer = main.Call(0x1234567812345678, 0x3333, args, false)) using (answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -324,7 +324,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, false)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -361,7 +361,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, true)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
@ -372,7 +372,7 @@ namespace Capnp.Net.Runtime.Tests
args2.SetStruct(1, 0); args2.SetStruct(1, 0);
args2.WriteData(0, 654321); args2.WriteData(0, 654321);
using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2, false)) using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2))
{ {
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
Assert.AreEqual<ulong>(0x1234567812345678, interfaceId); Assert.AreEqual<ulong>(0x1234567812345678, interfaceId);
@ -434,7 +434,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, true)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
@ -464,7 +464,7 @@ namespace Capnp.Net.Runtime.Tests
args2.SetStruct(1, 0); args2.SetStruct(1, 0);
args2.WriteData(0, 654321); args2.WriteData(0, 654321);
using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2, false)) using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2))
{ {
Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout)); Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout));
Assert.IsTrue(mock2.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock2.WhenCalled.Wait(MediumTimeout));
@ -510,7 +510,7 @@ namespace Capnp.Net.Runtime.Tests
var args = DynamicSerializerState.CreateForRpc(); var args = DynamicSerializerState.CreateForRpc();
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
using (var answer = main.Call(0x1234567812345678, 0x3333, args, true)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
@ -524,8 +524,8 @@ namespace Capnp.Net.Runtime.Tests
args3.SetStruct(1, 0); args3.SetStruct(1, 0);
args3.WriteData(0, 222222); args3.WriteData(0, 222222);
using (var answer2 = pipelined.Call(0x1111111111111111, 0x1111, args2, false)) using (var answer2 = pipelined.Call(0x1111111111111111, 0x1111, args2))
using (var answer3 = pipelined.Call(0x2222222222222222, 0x2222, args3, false)) using (var answer3 = pipelined.Call(0x2222222222222222, 0x2222, args3))
{ {
(var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result;
@ -555,8 +555,8 @@ namespace Capnp.Net.Runtime.Tests
args5.SetStruct(1, 0); args5.SetStruct(1, 0);
args5.WriteData(0, 444444); args5.WriteData(0, 444444);
using (var answer4 = pipelined.Call(0x3333333333333333, 0x3333, args4, false)) using (var answer4 = pipelined.Call(0x3333333333333333, 0x3333, args4))
using (var answer5 = pipelined.Call(0x4444444444444444, 0x4444, args5, false)) using (var answer5 = pipelined.Call(0x4444444444444444, 0x4444, args5))
{ {
var call2 = mock2.WhenCalled; var call2 = mock2.WhenCalled;
var call3 = mock2.WhenCalled; var call3 = mock2.WhenCalled;
@ -628,7 +628,7 @@ namespace Capnp.Net.Runtime.Tests
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
BareProxy pipelined; BareProxy pipelined;
using (var answer = main.Call(0x1234567812345678, 0x3333, args, true)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
@ -643,7 +643,7 @@ namespace Capnp.Net.Runtime.Tests
try try
{ {
pipelined.Call(0x8765432187654321, 0x4444, args2, false); pipelined.Call(0x8765432187654321, 0x4444, args2);
Assert.Fail("Expected an exception here"); Assert.Fail("Expected an exception here");
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
@ -675,7 +675,7 @@ namespace Capnp.Net.Runtime.Tests
args.SetStruct(1, 0); args.SetStruct(1, 0);
args.WriteData(0, 123456); args.WriteData(0, 123456);
IPromisedAnswer answer2; IPromisedAnswer answer2;
using (var answer = main.Call(0x1234567812345678, 0x3333, args, true)) using (var answer = main.Call(0x1234567812345678, 0x3333, args))
{ {
Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout));
@ -685,7 +685,7 @@ namespace Capnp.Net.Runtime.Tests
args2.SetStruct(1, 0); args2.SetStruct(1, 0);
args2.WriteData(0, 654321); args2.WriteData(0, 654321);
answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2, false); answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2);
} }
using (answer2) using (answer2)

View File

@ -45,9 +45,9 @@
/// <param name="args">Method arguments</param> /// <param name="args">Method arguments</param>
/// <param name="tailCall">Whether it is a tail call</param> /// <param name="tailCall">Whether it is a tail call</param>
/// <returns>Answer promise</returns> /// <returns>Answer promise</returns>
public IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall) public IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
return base.Call(interfaceId, methodId, args, tailCall); return base.Call(interfaceId, methodId, args, default);
} }
} }
} }

View File

@ -10,7 +10,7 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
public abstract class ConsumedCapability public abstract class ConsumedCapability
{ {
internal abstract IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall); internal abstract IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args);
/// <summary> /// <summary>
/// Request the RPC engine to release this capability from its import table, /// Request the RPC engine to release this capability from its import table,

View File

@ -289,7 +289,7 @@ namespace Capnp.Rpc.Interception
throw new InvalidOperationException("Bob is null"); throw new InvalidOperationException("Bob is null");
} }
var answer = BobProxy.Call(InterfaceId, MethodId, InArgs.Rewrap<DynamicSerializerState>(), false, CancelToBob); var answer = BobProxy.Call(InterfaceId, MethodId, InArgs.Rewrap<DynamicSerializerState>(), default, CancelToBob);
State = InterceptionState.ForwardedToBob; State = InterceptionState.ForwardedToBob;

View File

@ -19,7 +19,7 @@
InterceptedCapability.Release(); InterceptedCapability.Release();
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
var cc = new CallContext(this, interfaceId, methodId, args); var cc = new CallContext(this, interfaceId, methodId, args);
Policy.OnCallFromAlice(cc); Policy.OnCallFromAlice(cc);

View File

@ -81,9 +81,7 @@ namespace Capnp.Rpc
public Task<Proxy> WhenResolved { get; } public Task<Proxy> WhenResolved { get; }
async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken)
DynamicSerializerState args, bool pipeline,
CancellationToken cancellationToken)
{ {
var cap = await WhenResolved; var cap = await WhenResolved;
@ -92,7 +90,7 @@ namespace Capnp.Rpc
if (cap == null) if (cap == null)
throw new RpcException("Broken capability"); throw new RpcException("Broken capability");
var call = cap.Call(interfaceId, methodId, args, pipeline); var call = cap.Call(interfaceId, methodId, args, default);
var whenReturned = call.WhenReturned; var whenReturned = call.WhenReturned;
using (var registration = cancellationToken.Register(call.Dispose)) using (var registration = cancellationToken.Register(call.Dispose))
@ -101,10 +99,10 @@ namespace Capnp.Rpc
} }
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, pipeline, cts.Token)); return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, cts.Token));
} }
} }
} }

View File

@ -57,9 +57,7 @@ namespace Capnp.Rpc
} }
} }
async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken)
DynamicSerializerState args, bool pipeline,
CancellationToken cancellationToken)
{ {
var cap = await AwaitResolved(); var cap = await AwaitResolved();
@ -68,7 +66,7 @@ namespace Capnp.Rpc
if (cap == null) if (cap == null)
throw new RpcException("Broken capability"); throw new RpcException("Broken capability");
var call = cap.Call(interfaceId, methodId, args, pipeline); var call = cap.Call(interfaceId, methodId, args, default);
var whenReturned = call.WhenReturned; var whenReturned = call.WhenReturned;
using (var registration = cancellationToken.Register(() => call.Dispose())) using (var registration = cancellationToken.Register(() => call.Dispose()))
@ -77,10 +75,10 @@ namespace Capnp.Rpc
} }
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, pipeline, cts.Token)); return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, cts.Token));
} }
protected override void ReleaseRemotely() protected override void ReleaseRemotely()

View File

@ -42,7 +42,7 @@ namespace Capnp.Rpc
ProvidedCap.Relinquish(); ProvidedCap.Relinquish();
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var call = ProvidedCap.Invoke(interfaceId, methodId, args, cts.Token); var call = ProvidedCap.Invoke(interfaceId, methodId, args, cts.Token);

View File

@ -169,13 +169,13 @@ namespace Capnp.Rpc
wr.ImportedCap = _remoteId; wr.ImportedCap = _remoteId;
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
lock (_reentrancyBlocker) lock (_reentrancyBlocker)
{ {
if (_resolvedCap.Task.IsCompleted) if (_resolvedCap.Task.IsCompleted)
{ {
return CallOnResolution(interfaceId, methodId, args, pipeline); return CallOnResolution(interfaceId, methodId, args);
} }
else else
{ {
@ -184,7 +184,7 @@ namespace Capnp.Rpc
} }
} }
var promisedAnswer = base.DoCall(interfaceId, methodId, args, pipeline); var promisedAnswer = base.DoCall(interfaceId, methodId, args);
TrackCall(promisedAnswer.WhenReturned); TrackCall(promisedAnswer.WhenReturned);
return promisedAnswer; return promisedAnswer;
} }

View File

@ -66,13 +66,15 @@ namespace Capnp.Rpc
/// <param name="interfaceId">Interface ID to call</param> /// <param name="interfaceId">Interface ID to call</param>
/// <param name="methodId">Method ID to call</param> /// <param name="methodId">Method ID to call</param>
/// <param name="args">Method arguments ("param struct")</param> /// <param name="args">Method arguments ("param struct")</param>
/// <param name="tailCall">Whether it is a tail call</param> /// <param name="obsoleteAndIgnored">This flag is ignored. It is there to preserve compatibility with the
/// code generator and will be removed in future versions.</param>
/// <param name="cancellationToken">For cancelling an ongoing method call</param> /// <param name="cancellationToken">For cancelling an ongoing method call</param>
/// <returns>An answer promise</returns> /// <returns>An answer promise</returns>
/// <exception cref="ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception> /// <exception cref="ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception>
/// <exception cref="InvalidOperationException">Capability is broken.</exception> /// <exception cref="InvalidOperationException">Capability is broken.</exception>
/// <exception cref="System.IO.IOException">An I/O error occurs.</exception> /// <exception cref="System.IO.IOException">An I/O error occurs.</exception>
protected internal IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall, CancellationToken cancellationToken = default) protected internal IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args,
bool obsoleteAndIgnored, CancellationToken cancellationToken = default)
{ {
if (_disposedValue) if (_disposedValue)
throw new ObjectDisposedException(nameof(Proxy)); throw new ObjectDisposedException(nameof(Proxy));
@ -80,7 +82,7 @@ namespace Capnp.Rpc
if (ConsumedCap == null) if (ConsumedCap == null)
throw new InvalidOperationException("Cannot call null capability"); throw new InvalidOperationException("Cannot call null capability");
var answer = ConsumedCap.DoCall(interfaceId, methodId, args, tailCall); var answer = ConsumedCap.DoCall(interfaceId, methodId, args);
if (cancellationToken.CanBeCanceled) if (cancellationToken.CanBeCanceled)
{ {

View File

@ -99,7 +99,7 @@ namespace Capnp.Rpc
_access.Serialize(wr.PromisedAnswer); _access.Serialize(wr.PromisedAnswer);
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
lock (_question.ReentrancyBlocker) lock (_question.ReentrancyBlocker)
{ {
@ -111,7 +111,7 @@ namespace Capnp.Rpc
throw new RpcException("Answer did not resolve to expected capability"); throw new RpcException("Answer did not resolve to expected capability");
} }
return CallOnResolution(interfaceId, methodId, args, pipeline); return CallOnResolution(interfaceId, methodId, args);
} }
else else
{ {
@ -130,7 +130,7 @@ namespace Capnp.Rpc
_question.DisallowFinish(); _question.DisallowFinish();
++_pendingCallsOnPromise; ++_pendingCallsOnPromise;
var promisedAnswer = base.DoCall(interfaceId, methodId, args, pipeline); var promisedAnswer = base.DoCall(interfaceId, methodId, args);
ReAllowFinishWhenDone(promisedAnswer.WhenReturned); ReAllowFinishWhenDone(promisedAnswer.WhenReturned);
async void DecrementPendingCallsOnPromiseWhenReturned() async void DecrementPendingCallsOnPromiseWhenReturned()

View File

@ -15,7 +15,7 @@ namespace Capnp.Rpc
_ep = ep; _ep = ep;
} }
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall) internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
var call = SetupMessage(args, interfaceId, methodId); var call = SetupMessage(args, interfaceId, methodId);
Debug.Assert(call.Target.which != MessageTarget.WHICH.undefined); Debug.Assert(call.Target.which != MessageTarget.WHICH.undefined);

View File

@ -29,7 +29,7 @@ namespace Capnp.Rpc
protected abstract void GetMessageTarget(MessageTarget.WRITER wr); protected abstract void GetMessageTarget(MessageTarget.WRITER wr);
protected IPromisedAnswer CallOnResolution(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline) protected IPromisedAnswer CallOnResolution(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{ {
try try
{ {
@ -62,7 +62,7 @@ namespace Capnp.Rpc
#if DebugEmbargos #if DebugEmbargos
Logger.LogDebug("Direct call"); Logger.LogDebug("Direct call");
#endif #endif
return ResolvedCap.Call(interfaceId, methodId, args, pipeline); return ResolvedCap.Call(interfaceId, methodId, args, default);
} }
else else
{ {
@ -90,7 +90,7 @@ namespace Capnp.Rpc
cancellationTokenSource.Token.ThrowIfCancellationRequested(); cancellationTokenSource.Token.ThrowIfCancellationRequested();
return ResolvedCap.Call(interfaceId, methodId, args, pipeline); return ResolvedCap.Call(interfaceId, methodId, args, default);
}, TaskContinuationOptions.ExecuteSynchronously); }, TaskContinuationOptions.ExecuteSynchronously);

View File

@ -32,7 +32,7 @@ namespace Capnp.Rpc
ulong interfaceId, ushort methodId, DeserializerState args, ulong interfaceId, ushort methodId, DeserializerState args,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var promisedAnswer = Proxy.Call(interfaceId, methodId, (DynamicSerializerState)args, false); var promisedAnswer = Proxy.Call(interfaceId, methodId, (DynamicSerializerState)args, default);
if (promisedAnswer is PendingQuestion pendingQuestion && pendingQuestion.RpcEndpoint == Impatient.AskingEndpoint) if (promisedAnswer is PendingQuestion pendingQuestion && pendingQuestion.RpcEndpoint == Impatient.AskingEndpoint)
{ {