Skip to content

> This approach works well for the simple case where one wants to do something simple before/after each grain call, but call specific actions would be difficult. #9580

Open
@sumansuhag

Description

@sumansuhag

The Per-Grain-class Request Interceptors feature, merged in pull request #965, allows users to override the Grain.Invoke method to perform request interception on a per-grain-class level. This feature enables developers to execute custom logic before and after a grain call, modifying the request context, arguments, and return values as needed.

public class InterceptRequestGrain : Grain, ISomeGrain
{
protected override Task Invoke(InvokeMethodRequest request, IGrainMethodInvoker invoker)
{
RequestContext.Set("InterceptedValue", 74);
return base.Invoke(request, invoker);
}
// Other methods...
}

In this example, the InterceptRequestGrain class overrides the Invoke method to set a value in the request context before calling the base Invoke method.

Grain Call Filters:

Grain call filters provide a way to intercept grain calls, executing code before and after the call. There are two types of filters:

  • Incoming Call Filters: Executed when receiving a call.
  • Outgoing Call Filters: Executed when making a call.

You can implement grain call filters by creating classes that implement IIncomingGrainCallFilter or IOutgoingGrainCallFilter interfaces.

Example of Incoming Grain Call Filter:

public class LoggingCallFilter : IIncomingGrainCallFilter
{
private readonly Logger _logger;

public LoggingCallFilter(Factory<string, Logger> loggerFactory) 
{
    _logger = loggerFactory(nameof(LoggingCallFilter));
}

public async Task Invoke(IIncomingGrainCallContext context) 
{
    try 
    {
        await context.Invoke();
        var msg = string.Format("{0}.{1}({2}) returned value {3}", context.Grain.GetType(), context.InterfaceMethod.Name, string.Join(", ", context.Arguments), context.Result);
        _logger.Info(msg);
    } 
    catch (Exception exception) 
    {
        var msg = string.Format("{0}.{1}({2}) threw an exception: {3}", context.Grain.GetType(), context.InterfaceMethod.Name, string.Join(", ", context.Arguments), exception);
        _logger.Info(msg);
        throw;
    }
}

}

This filter logs information about grain method invocations, including the method name, arguments, and return values.

Registering Grain Call Filters:

You can register grain call filters using Dependency Injection. Here's an example:

siloHostBuilder.AddIncomingGrainCallFilter();

This registers the LoggingCallFilter class as an incoming grain call filter ¹.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions