WampSharp
WampSharp copied to clipboard
Error with (async) RawCallee and SupportsCancellation=false
I'm hosting a WAMP router within a ASP.NET Core project.
Within this Router project I'm registering an RPC method like:
_wampRpcOperationCatalog.Register(new WampMethodTest("test"), registerOptions);
The class WampMethodTest is a descendant of "AsyncLocalRpcOperation" and implements "SupportsCancellation" with "false".
To simplify the implementation, my invoke method looks like:
var result = new int[] {1, 2, 3};
return Task.FromResult( (object) result );
When calling this method from an AutobahnJS client, I get two different behaviours: a) Error Message with "no such procedure" and a protocol violation afterwards ("Getting a Result after an Error)
or
b) get the result and get a protocol violation afterwards ("Getting an Error after Result").
I debugged a bit and came to the following: WampRpcOperationCatalog.cs throws the "NoSuchProcedure" in the "InvokePattern" routine, if the previous result is "NULL". Stepping through the loop, brought me to the "InnerInvoke" method of AsyncLocalRpcOperation in AsyncLocalRpcOperation.cs:
....
if (SupportsCancellation)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
result = new CancellationTokenSourceInvocation(cancellationTokenSource);
token = cancellationTokenSource.Token;
}
.....
This means, that if "SupportsCancellation" is false, the "result" variable will be null. This will lead to the "NoSuchProcedure" error. The method it self is getting invoked and executed - this leads to the protocol error written above.
Workaround: set "SupportsCancellation" to true.
The SupportsCancellation
property was designed for remote callees, I never thought about the usage of registering such procedure in the RpcCatalog directly.
I guess the easiest fix would be to return a default UncancellableInvocation
which throws an exception from AsyncLocalRpcOperation
.
So actually it turns out that cancellation is not supported for operations registered using the Catalog directly. The WampRpcOperationCatalog
is sort of an internal implementation detail that should not be accessed directly, it should be accessed through a client, even if this is an internal client (for example the RealmServices
property uses this approach internally, I'm not sure if a RealmProxy
is also exposed to the user, but if not, it might be a good time to expose it).
Elad
I used the code from here: https://wampsharp.net/wamp2/roles/callee/raw-callee/
There the RpcCatalog is used to register a method (at least in the "Client" code).
I also tried to use realm.Services.RegisterCallee
but there my method just didn't get called - I assumed that this method is only for the Reflection Based Callees.
Can you explain your usage of the raw callee interface? Why can't you use the reflection based callee? Maybe I can design a nice feature for scenarios similar to yours.
Elad
I want to specify the identifier of the method at runtime (in this case, I want to prefix it with a string from the configuration).
With the (current) reflection API I have to specify the whole function name in the attribute (as far as I understood).
You can use a CalleeInterceptor which allows you to customize the procedure name.
Ok thx. Will try that the next time when I visit that code. Should we close this ticket or do you want to implement a bugfix?
Leave it open, I'll think about what I want to do with it.