-
Notifications
You must be signed in to change notification settings - Fork 26
Interception
Interception is conceptually very close to membranes (if not the same), although the APIs look different. It can be thought as a universal capability hook mechanism which enables an interception policy to control (monitor, defer, modify, redirect, reject) any calls on its intercepted capabilities. There is also the possibility to transitively intercept capabilities which are passed to or from the target capability during the method call.
Enough of theory. For using interception, implement Capnp.Rpc.Interception.IInterceptionPolicy
:
public interface IInterceptionPolicy: IEquatable<IInterceptionPolicy>
{
void OnCallFromAlice(CallContext callContext);
void OnReturnFromBob(CallContext callContext);
}
The IEquatable<IInterceptionPolicy>
contract helps the Capnp.Net.Runtime
identifying whether a given capability is already intercepted or not in the presence of multiple interception policies. There is an extension method Attach
for attaching the policy to a capability. Intercepting the bootstrap capability on client side would look like this:
`
TcpRpcClient client = ...;
IInterceptionPolicy policy = ...;
var interceptedMain = policy.Attach(client.GetMain<IYourInterface>());
Server side:
TcpRpcServer server = ...;
IInterceptionPolicy policy = ...;
server.Main = policy.Attach<IYourInterface>(new YourInterfaceImpl());
Once you did this, the policy's two callback methods get notify as follows:
-
OnCallFromAlice
gets invoked when a caller attempts to call a method. -
OnReturnFromBob
gets invoked when the callee has returned.
It is important to understand that it is completely up to the policy what happens in turn. Indeed, explicit action is required for anything to happen. I.e. leaving OnCallFromAlice
with an empty implementation means "never deliver that call".
Both OnCallFromAlice
and OnReturnFromBob
receive a CallContext
parameter which encapsulates the intercepted call. It provides you with several properties and methods for taking control. When inside OnCallFromAlice(CallContext cc)
you may choose from the following:
- Inspect or modify input arguments from
InArgs
. - Intercept all input arguments' capabilities:
InterceptInCaps()
- Forward the call to its original target:
ForwardToBob()
- Redirect the call to a different target: Overwrite
Bob
, thenForwardToBob()
. - Answer the call by yourself: Set
OutArgs
, then callReturnToAlice()
. - Return the call in canceled or faulted state: Set
ReturnCanceled
orException
, respectively, then callReturnToAlice()
.
Inside OnReturnFromBob(CallContext cc)
you'll have another bunch of options:
- Inspect or modify output arguments from
OutArgs
. - Intercept all output arguments' capabilities:
InterceptOutCaps()
- Choose whether the call should appear returned, faulted, or canceled (yes, you may also "heal" an originally faulted call by setting appropriate
OutArgs
and settingException
tonull
, if you find that useful).
Of course, you may also put the CallContext
object in a queue, pull it out later and then do something with it. The sky is the limit.