WampSharp icon indicating copy to clipboard operation
WampSharp copied to clipboard

Error with (async) RawCallee and SupportsCancellation=false

Open jensweigele opened this issue 5 years ago • 8 comments

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.

jensweigele avatar Apr 29 '19 14:04 jensweigele

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.

darkl avatar Apr 29 '19 14:04 darkl

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

darkl avatar Apr 29 '19 15:04 darkl

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.

jensweigele avatar Apr 29 '19 15:04 jensweigele

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

darkl avatar Apr 29 '19 21:04 darkl

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).

jensweigele avatar Apr 29 '19 21:04 jensweigele

You can use a CalleeInterceptor which allows you to customize the procedure name.

darkl avatar Apr 29 '19 22:04 darkl

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?

jensweigele avatar May 05 '19 21:05 jensweigele

Leave it open, I'll think about what I want to do with it.

darkl avatar May 05 '19 22:05 darkl