Search code examples
orleans

Call interception - How to determine wether a call is a system call


I am trying to create an interception method that only processes non-system calls. According to the docs both system and non-system calls are intercepted:

Outgoing grain call filters are invoked for all method calls to a grain and this includes calls to system methods made by Orleans.

However, I cannot find a way to make the distinction using any public method or property. Am I missing something?


Solution

  • I can think of two interpretations of what a system call could be here:

    1. Any call to an ISystemTarget
    2. Any call to an interface defined in one of the Orleans assemblies

    In the case of either, the simplest way to determine if a call fits that criteria is to use the InterfaceMethod property of the context which is passed to the call filter to check the DeclaringType of that MethodInfo.

    For example:

    siloBuilder.AddOutgoingGrainCallFilter(async context =>
    {
        var declaringType = context.InterfaceMethod?.DeclaringType;
    
        // Check if the type being called belongs to one of the Orleans assemblies
        // systemAssemblies here is a HashSet<Assembly> containing the Orleans assemblies
        var isSystemAssembly = declaringType != null
          && systemAssemblies.Contains(declaringType.Assembly);
    
        // Check if the type is an ISystemTarget
        var systemTarget = declaringType != null
          && typeof(ISystemTarget).IsAssignableFrom(declaringType);
    
        if (isSystemAssembly || systemTarget)
        {
            // This is a system call, so just continue invocation without any further action
            await context.Invoke();
        }
        else
        {
            // This is an application call
    
            // ... Inspect/modify the arguments here ...
    
            await context.Invoke();
    
            // ... inspect/modify return value here ...
        }
    })