mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 14:51:41 +01:00
refactored IResolvingCapability to hide ConsumedCapability
This commit is contained in:
parent
4bf0e970c2
commit
d7f937a9c0
@ -8,8 +8,15 @@ namespace Capnp.Rpc
|
|||||||
public interface IResolvingCapability
|
public interface IResolvingCapability
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will eventually give the resolved capability.
|
/// Completes when the capability gets resolved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<ConsumedCapability?> WhenResolved { get; }
|
Task WhenResolved { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the resolved capability
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Capability interface or <see cref="BareProxy"/></typeparam>
|
||||||
|
/// <returns>the resolved capability, or null if it did not resolve yet</returns>
|
||||||
|
T? GetResolvedCapability<T>() where T: class;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,10 +17,11 @@ namespace Capnp.Rpc
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly Task<Proxy>? _proxyTask;
|
readonly Task<Proxy>? _proxyTask;
|
||||||
|
readonly Task<ConsumedCapability?> _capTask;
|
||||||
|
|
||||||
public LazyCapability(Task<ConsumedCapability?> capabilityTask)
|
public LazyCapability(Task<ConsumedCapability?> capabilityTask)
|
||||||
{
|
{
|
||||||
WhenResolved = capabilityTask;
|
_capTask = capabilityTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LazyCapability(Task<Proxy> proxyTask)
|
public LazyCapability(Task<Proxy> proxyTask)
|
||||||
@ -29,7 +30,7 @@ namespace Capnp.Rpc
|
|||||||
|
|
||||||
async Task<ConsumedCapability?> AwaitCap() => (await _proxyTask!).ConsumedCap;
|
async Task<ConsumedCapability?> AwaitCap() => (await _proxyTask!).ConsumedCap;
|
||||||
|
|
||||||
WhenResolved = AwaitCap();
|
_capTask = AwaitCap();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||||
@ -40,7 +41,7 @@ namespace Capnp.Rpc
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WhenResolved.Result?.Freeze(out boundEndpoint);
|
_capTask.Result?.Freeze(out boundEndpoint);
|
||||||
}
|
}
|
||||||
catch (AggregateException exception)
|
catch (AggregateException exception)
|
||||||
{
|
{
|
||||||
@ -61,7 +62,7 @@ namespace Capnp.Rpc
|
|||||||
{
|
{
|
||||||
if (WhenResolved.ReplacementTaskIsCompletedSuccessfully())
|
if (WhenResolved.ReplacementTaskIsCompletedSuccessfully())
|
||||||
{
|
{
|
||||||
using var proxy = new Proxy(WhenResolved.Result);
|
using var proxy = GetResolvedCapability<BareProxy>()!;
|
||||||
return proxy.Export(endpoint, writer);
|
return proxy.Export(endpoint, writer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -84,14 +85,33 @@ namespace Capnp.Rpc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ConsumedCapability?> WhenResolved { get; }
|
public Task WhenResolved => _capTask;
|
||||||
|
|
||||||
|
public T? GetResolvedCapability<T>() where T: class
|
||||||
|
{
|
||||||
|
if (_capTask.IsCompleted)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return CapabilityReflection.CreateProxy<T>(_capTask.Result) as T;
|
||||||
|
}
|
||||||
|
catch (AggregateException exception)
|
||||||
|
{
|
||||||
|
throw exception.InnerException!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken)
|
async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
ConsumedCapability? cap;
|
ConsumedCapability? cap;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cap = await WhenResolved;
|
cap = await _capTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -21,9 +21,6 @@ namespace Capnp.Rpc
|
|||||||
public LocalAnswerCapability(Task<Proxy> proxyTask)
|
public LocalAnswerCapability(Task<Proxy> proxyTask)
|
||||||
{
|
{
|
||||||
_whenResolvedProxy = proxyTask;
|
_whenResolvedProxy = proxyTask;
|
||||||
|
|
||||||
async Task<ConsumedCapability?> AwaitResolved() => (await _whenResolvedProxy).ConsumedCap;
|
|
||||||
WhenResolved = AwaitResolved();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalAnswerCapability(Task<DeserializerState> answer, MemberAccessPath access):
|
public LocalAnswerCapability(Task<DeserializerState> answer, MemberAccessPath access):
|
||||||
@ -42,7 +39,9 @@ namespace Capnp.Rpc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<ConsumedCapability?> WhenResolved { get; private set; }
|
public Task WhenResolved => _whenResolvedProxy;
|
||||||
|
|
||||||
|
public T? GetResolvedCapability<T>() where T : class => _whenResolvedProxy.GetResolvedCapability<T>();
|
||||||
|
|
||||||
internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
|
internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
|
||||||
{
|
{
|
||||||
|
@ -16,11 +16,12 @@ namespace Capnp.Rpc
|
|||||||
{
|
{
|
||||||
_remoteId = remoteId;
|
_remoteId = remoteId;
|
||||||
|
|
||||||
async Task<Proxy> AwaitProxy() => new Proxy(await WhenResolved);
|
async Task<Proxy> AwaitProxy() => new Proxy(await _resolvedCap.Task);
|
||||||
_whenResolvedProxy = AwaitProxy();
|
_whenResolvedProxy = AwaitProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<ConsumedCapability?> WhenResolved => _resolvedCap.Task;
|
public override Task WhenResolved => _resolvedCap.Task;
|
||||||
|
public override T? GetResolvedCapability<T>() where T: class => _whenResolvedProxy.GetResolvedCapability<T>();
|
||||||
|
|
||||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@ namespace Capnp.Rpc
|
|||||||
/// <typeparam name="T">Capability interface</typeparam>
|
/// <typeparam name="T">Capability interface</typeparam>
|
||||||
/// <param name="obj">instance to share</param>
|
/// <param name="obj">instance to share</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T Share<T>(T obj) where T: class
|
public static T Share<T>(T obj) where T : class
|
||||||
{
|
{
|
||||||
if (obj is Proxy proxy)
|
if (obj is Proxy proxy)
|
||||||
return proxy.Cast<T>(false);
|
return proxy.Cast<T>(false);
|
||||||
@ -32,18 +32,30 @@ namespace Capnp.Rpc
|
|||||||
bool _disposedValue = false;
|
bool _disposedValue = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will eventually give the resolved capability, if this is a promised capability.
|
/// Completes when the capability gets resolved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Task<ConsumedCapability?> WhenResolved
|
public Task WhenResolved
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ConsumedCap is IResolvingCapability resolving ?
|
return ConsumedCap is IResolvingCapability resolving ?
|
||||||
resolving.WhenResolved :
|
resolving.WhenResolved : Task.CompletedTask;
|
||||||
Task.FromResult(ConsumedCap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the resolved capability
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Capability interface or <see cref="BareProxy"/></typeparam>
|
||||||
|
/// <returns>the resolved capability, or null if it did not resolve yet</returns>
|
||||||
|
public T? GetResolvedCapability<T>() where T : class
|
||||||
|
{
|
||||||
|
if (ConsumedCap is IResolvingCapability resolving)
|
||||||
|
return resolving.GetResolvedCapability<T>();
|
||||||
|
else
|
||||||
|
return CapabilityReflection.CreateProxy<T>(ConsumedCap) as T;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Underlying low-level capability
|
/// Underlying low-level capability
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -23,18 +23,6 @@ namespace Capnp.Rpc
|
|||||||
_question = question ?? throw new ArgumentNullException(nameof(question));
|
_question = question ?? throw new ArgumentNullException(nameof(question));
|
||||||
_access = access ?? throw new ArgumentNullException(nameof(access));
|
_access = access ?? throw new ArgumentNullException(nameof(access));
|
||||||
_whenResolvedProxy = proxyTask ?? throw new ArgumentNullException(nameof(proxyTask));
|
_whenResolvedProxy = proxyTask ?? throw new ArgumentNullException(nameof(proxyTask));
|
||||||
|
|
||||||
async Task<ConsumedCapability?> AwaitWhenResolved()
|
|
||||||
{
|
|
||||||
var proxy = await _whenResolvedProxy;
|
|
||||||
|
|
||||||
if (_question.IsTailCall)
|
|
||||||
throw new InvalidOperationException("Question is a tail call, so won't resolve back.");
|
|
||||||
|
|
||||||
return proxy.ConsumedCap;
|
|
||||||
}
|
|
||||||
|
|
||||||
WhenResolved = AwaitWhenResolved();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task<Proxy> TransferOwnershipToDummyProxy(PendingQuestion question, MemberAccessPath access)
|
static async Task<Proxy> TransferOwnershipToDummyProxy(PendingQuestion question, MemberAccessPath access)
|
||||||
@ -81,7 +69,7 @@ namespace Capnp.Rpc
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return WhenResolved.Result;
|
return _whenResolvedProxy.Result.ConsumedCap;
|
||||||
}
|
}
|
||||||
catch (AggregateException exception)
|
catch (AggregateException exception)
|
||||||
{
|
{
|
||||||
@ -96,7 +84,9 @@ namespace Capnp.Rpc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<ConsumedCapability?> WhenResolved { get; }
|
public override Task WhenResolved => _whenResolvedProxy;
|
||||||
|
|
||||||
|
public override T? GetResolvedCapability<T>() where T: class => _whenResolvedProxy.GetResolvedCapability<T>();
|
||||||
|
|
||||||
protected override void GetMessageTarget(MessageTarget.WRITER wr)
|
protected override void GetMessageTarget(MessageTarget.WRITER wr)
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,8 @@ namespace Capnp.Rpc
|
|||||||
ILogger Logger { get; } = Logging.CreateLogger<RemoteResolvingCapability>();
|
ILogger Logger { get; } = Logging.CreateLogger<RemoteResolvingCapability>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public abstract Task<ConsumedCapability?> WhenResolved { get; }
|
public abstract Task WhenResolved { get; }
|
||||||
|
public abstract T? GetResolvedCapability<T>() where T : class;
|
||||||
|
|
||||||
protected RemoteResolvingCapability(IRpcEndpoint ep) : base(ep)
|
protected RemoteResolvingCapability(IRpcEndpoint ep) : base(ep)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,9 @@ namespace Capnp.Rpc
|
|||||||
{
|
{
|
||||||
while (cap is IResolvingCapability resolving)
|
while (cap is IResolvingCapability resolving)
|
||||||
{
|
{
|
||||||
cap = await resolving.WhenResolved;
|
await resolving.WhenResolved;
|
||||||
|
using var proxy = resolving.GetResolvedCapability<BareProxy>()!;
|
||||||
|
cap = proxy.ConsumedCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cap;
|
return cap;
|
||||||
@ -30,7 +32,9 @@ namespace Capnp.Rpc
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var resolvedCap = await Unwrap(await cap.WhenResolved);
|
await cap.WhenResolved;
|
||||||
|
using var proxy = cap.GetResolvedCapability<BareProxy>()!;
|
||||||
|
var resolvedCap = await Unwrap(proxy.ConsumedCap);
|
||||||
endpoint.Resolve(preliminaryId, vine, () => resolvedCap!);
|
endpoint.Resolve(preliminaryId, vine, () => resolvedCap!);
|
||||||
}
|
}
|
||||||
catch (System.Exception exception)
|
catch (System.Exception exception)
|
||||||
@ -68,5 +72,24 @@ namespace Capnp.Rpc
|
|||||||
default: return BareProxy.FromImpl(obj);
|
default: return BareProxy.FromImpl(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T? GetResolvedCapability<T>(this Task<Proxy> proxyTask) where T: class
|
||||||
|
{
|
||||||
|
if (proxyTask.IsCompleted)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return proxyTask.Result.Cast<T>(false);
|
||||||
|
}
|
||||||
|
catch (AggregateException exception)
|
||||||
|
{
|
||||||
|
throw exception.InnerException!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user