83 lines
2.3 KiB
C#
Raw Normal View History

using Microsoft.Extensions.Logging;
using System;
2019-06-12 21:56:55 +02:00
using System.Threading;
using System.Threading.Tasks;
namespace Capnp.Rpc
{
class Vine : Skeleton
{
2020-03-31 22:01:43 +02:00
public static Skeleton Create(ConsumedCapability? cap)
2019-06-12 21:56:55 +02:00
{
if (cap is LocalCapability lcap)
return lcap.ProvidedCap;
else
return new Vine(cap);
}
2020-03-31 22:01:43 +02:00
Vine(ConsumedCapability? consumedCap)
2019-06-12 21:56:55 +02:00
{
2020-03-31 22:01:43 +02:00
Proxy = new Proxy(consumedCap);
#if DebugFinalizers
CreatorStackTrace = Environment.StackTrace;
#endif
}
#if DebugFinalizers
~Vine()
{
Logger.LogWarning($"Caught orphaned Vine, created from here: {CreatorStackTrace}.");
Dispose(false);
2019-06-12 21:56:55 +02:00
}
ILogger Logger { get; } = Logging.CreateLogger<Vine>();
string CreatorStackTrace { get; }
#endif
2019-06-12 21:56:55 +02:00
internal override void Bind(object impl)
{
throw new NotImplementedException();
}
public Proxy Proxy { get; }
public async override Task<AnswerOrCounterquestion> Invoke(
ulong interfaceId, ushort methodId, DeserializerState args,
CancellationToken cancellationToken = default)
{
var promisedAnswer = Proxy.Call(interfaceId, methodId, (DynamicSerializerState)args, default);
2019-06-12 21:56:55 +02:00
if (promisedAnswer is PendingQuestion pendingQuestion && pendingQuestion.RpcEndpoint == Impatient.AskingEndpoint)
{
async void SetupCancellation()
{
try
{
2020-03-10 21:55:34 +01:00
using var registration = cancellationToken.Register(promisedAnswer.Dispose);
await promisedAnswer.WhenReturned;
}
catch
2019-06-12 21:56:55 +02:00
{
}
}
SetupCancellation();
return pendingQuestion;
}
else
{
2020-03-10 21:55:34 +01:00
using var registration = cancellationToken.Register(promisedAnswer.Dispose);
return (DynamicSerializerState)await promisedAnswer.WhenReturned;
2019-06-12 21:56:55 +02:00
}
}
protected override void Dispose(bool disposing)
{
Proxy.Dispose();
base.Dispose(disposing);
}
}
2020-01-11 17:56:12 +01:00
}