Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoke interceptor broken for generic grains #2358

Closed
dancvogel opened this issue Oct 28, 2016 · 8 comments
Closed

Invoke interceptor broken for generic grains #2358

dancvogel opened this issue Oct 28, 2016 · 8 comments
Assignees
Labels
Milestone

Comments

@dancvogel
Copy link

Just upgraded to 1.3.0 and am having issue with generic grains.

An example interface and class that's showing this issue:

public interface IGenericTest<T> : IGrainWithIntegerKey
{
    Task<T> PrintType(T obj);
}
public class GenericTestGrain<T> : Grain, IGenericTest<T>
{
    public Task<T> Print(T obj)
    {
        Debug.WriteLine("TEST");
        return Task.FromResult(obj);
    }
}

Also have invoke interceptor setup up, for simplicity looks like this:

providerRuntime.SetInvokeInterceptor((method, request, grain, invoker) =>
{
    return invoker.Invoke(grain, request);
});

then using the grain like:

var grain = await GrainFactory.GetGrain<IGenericTest<int>>(0); // Runs without error.
await grain.Print(1);

Getting the grain seems to be fine, but when I call the method on the grain I get:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Orleans.InterceptedMethodInvokerCache.GetInterfaceToImplementationMap(Int32 interfaceId, Type implementationType)
at Orleans.InterceptedMethodInvokerCache.CreateInterceptedMethodInvoker(Type implementationType, Int32 interfaceId, IGrainMethodInvoker invoker)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Orleans.InterceptedMethodInvokerCache.GetOrCreate(Type implementationType, Int32 interfaceId, IGrainMethodInvoker invoker)
at Orleans.Runtime.InsideRuntimeClient.InvokeWithInterceptors(IAddressable target, InvokeMethodRequest request, IGrainMethodInvoker invoker)
at Orleans.Runtime.InsideRuntimeClient.<Invoke>d__57.MoveNext()

When I remove the SetInvokeInterceptor call everything is happy. Seems like the code is trying to use the typed interface name as the key instead of the generic.

@sergeybykov
Copy link
Contributor

To clarify, the exact same code works in 1.2.3/1.2.4?

@dancvogel
Copy link
Author

I wasn't using the SetInvokeInterceptor before. I just updated from 1.1.3 to 1.3.0. so didn't have it as an option. Was using a custom wrapping before.

@sergeybykov
Copy link
Contributor

Then sounds like a bug (unsupported case) with interceptors.

@sergeybykov
Copy link
Contributor

If there's a quick fix, we could include it in 1.3.1 that we are in the process of assembling.

@ajorkowski
Copy link

ajorkowski commented Oct 28, 2016

In the InterceptedMethodInvokerCache.GetInterfaceToImplementationMap method, the line that is failing is:

GrainInterfaceUtils.GetMethods(interfaceTypes[interfaceId])

The problem is that the interfaceId is from the message, which I think is the compile-time id, whereas the dictionary is being built by the runtime interface (I think). Maybe it should fallback to the passed in type?

var interfaceType = interfaceTypes.ContainsKey(interfaceId) ? interfaceTypes[interfaceId] : implementationType;

GrainInterfaceUtils.GetMethods(interfaceType)

Although that doesn't seem entirely correct, since that would be grabbing the methods from a non-interface?

@gabikliot
Copy link
Contributor

There was a similar question, generic grains without interceptors, on Stack overflow.

@dancvogel
Copy link
Author

@gabikliot It is probably mine. I asked there before I discovered the interceptor thing and decided it was a bug (unsupported case) in Orleans.

@ReubenBond ReubenBond self-assigned this Oct 29, 2016
@sergeybykov sergeybykov modified the milestone: 1.4.0 Nov 3, 2016
ReubenBond added a commit to ReubenBond/orleans that referenced this issue Dec 8, 2016
jason-bragg pushed a commit that referenced this issue Dec 9, 2016
* Fix #2358: Invoke interceptor broken for generic grains

* Address review feedback
@ReubenBond
Copy link
Member

Hi @dancvogel, the issue has been fixed in master and will be included in the next release

@dotnet dotnet locked as resolved and limited conversation to collaborators Sep 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants