[MDSAL-86] Split up BindingDOMRpcImplementationAdapter Created: 28/May/15  Updated: 28/Nov/22  Resolved: 25/Nov/22

Status: Resolved
Project: mdsal
Component/s: Binding runtime
Affects Version/s: None
Fix Version/s: 11.0.0

Type: Improvement Priority: Medium
Reporter: Robert Varga Assignee: Robert Varga
Resolution: Done Votes: 0
Labels: pt
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Relates
relates to MDSAL-796 DOMRpcService.registerImplementations... Resolved

 Description   

We create an instance of this class for each RPC registration, which means we need to dynamically create a SchemaPath on each invocation.

That schema path is used for lookup in the codec tree cache, which is lazily instantiated. Since we are using a different SchemaPath object on each lookup, equals() part of the cache lookup strays away from the identity comparison, leading to lost performance.

Break up the Adapter such that we maintain a per-method registration, which retains the registration SchemaPath. This will result in the lookup not allocating any objects and keeping on the identity path.



 Comments   
Comment by Robert Varga [ 05/Nov/19 ]

We will need to implement BindingCodecTree.getSubtreeCodec(SchemaNodeIdentifier), so that we can efficiently lookup RPC input/output as well as notifications. Once we have that, we can properly bind methods to their SchemaContext counterparts without having to go through the codec.

This should result in a BindingDOMRpcProviderServiceAdapter having a

Cache<Class<? extends RpcService>, RpcServiceClassContext> rpcServiceClasses;

populated lazily as services are registered. Furthermore RpcServiceClassContext should have the basic shape of:

final class RpcServiceClassContext implements Immutable {
    final ImmutableMap<SchemaNodeIdentifier, RpcServiceMethodContext> methods;
}

Note the methods map should not be used during invocation, only during decomposition of the RPC implementation – the keys are input to DOMRpcIdentifier and values form the invocation context, which in turn looks like this:

final class RpcServiceMethodContext implements Immutable {
    final QName inputQName; // Note: shared between all MethodContexts in a ClassContext
    final BindingNormalizedNodeCodec inputCodec;
    final BindingNormalizedNodeCodec outputCodec;
    final RpcMethodInvoker methodInvoker;
}

now when an implementation is registered, we look up the RpcServiceClassContext and for each RpcServiceMethodContext we create a DOMRpcImplementation, which has a pointer to the MethodContext and the RpcService object being registered.

During invocation we use the inputCodec/inputQName combo to create the DataObject representation of input and pass that to the methodInvoker. We then return a variation on LazyDOMRpcResultFuture, which actually holds a reference to outputCodec directly, not going through the codec/codecRegistry.

Note that since the DOMRpcImplementations created are not multiplexing but rather each points to a single YANG RPC, we do not consult DOMRpcImplementation.invokeRpc()'s first argument.

Comment by Robert Varga [ 05/Nov/19 ]

The problem with this decomposition, though, is that the resulting object would not be registered atomically – for that we will need an atomic

DOMRpcProviderService.registerRpcImplementations(Map<DOMRpcIdentifier, DOMRpcImplementation>);

method and have that implemented.

Comment by Robert Varga [ 04/Oct/22 ]

I think we can address this cleanly by removing the Adapter, as we won't be needing it.

Comment by Robert Varga [ 24/Nov/22 ]

Actually, we can implement an efficient split by reusing the DOM and Binding infra existing for single-RPC invocations.

Generated at Wed Feb 07 20:08:36 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.