You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

IDIEP-79
Author Pavel Pereslegin 
Sponsor
Created13 Oct 2021
StatusDRAFT


Motivation

When implementing microservices, users are often faced with the task of separating the business logic from the common "middleware" logic.

An example of a typical “middleware” task is auditing calls to business service methods (the system must understand which user called which methods and with what result).

Modern frameworks such as gRPC and Apache Thrift provide a very flexible API for implementing request interceptors, with which you can solve almost any middleware task.

Apache Ignite does not provide any mechanisms for solving such problems in general. The user needs to implement it himself, which often results in a lot of boilerplate code. 

Description

Summary

The Ignite Service Grid must support the following capabilities:

  1. Ability to pass custom context from caller to service (similar to HTTP request headers).
  2. Ability to define custom interceptors for service calls.

Suggested design (draft)

Implementation entities

  1. RequestContext - mutable map of custom parameters to be implicitly passed to the service.
  2. Interceptor - executes before call service method.
  3. Listener - called after service method

Java API

Interceptor
/**
 * Service method call interceptor.
 */
public interface ServiceCallInterceptor {
    /**
     * Executes before service method invocation.
     *
     * @param mtdName Method name.
     * @param args Method arguments.
     * @param ctx Service request context.
     * @return Listener of the call result or {@code null}.
     */
    public @Nullable ServiceCallListener intercept(String mtdName, Object[] args, ServiceRequestContext ctx);
}
Listener
/**
 * Listener of the service method invocation.
 */
public interface ServiceCallListener {
    /**
     *
     * @param res Service method call result, if any.
     * @param t Error, if any.
     */
    public void onComplete(@Nullable Object res, @Nullable Throwable t);
}

Implementation requirements/limitations

  • All specified interceptors are guaranteed to be executed before calling the service method.
  • Listeners are notified asynchronously.
  • The server interceptor binds to the service itself (it must be executed where the service is implemented, if on Java then in Java, if on Net then in Net).
  • The client interceptor binds to the proxy invocation handler. In fact, the main task of the client interceptor is to transfer the parameters of the caller to the service instance (using the RequestContext).
  • If the interceptor throws an exception, the service method is not executed, but the rest of the interceptors are executed. This exception is passed to the user and to the listeners.
  • Any interceptor can change the RequestContext.
  • RequestContext must be accessible inside the service(?).

Example of usage diagram

Risks and Assumptions

// Describe project risks, such as API or binary compatibility issues, major protocol changes, etc.

Discussion Links

https://lists.apache.org/thread.html/r4236c1f23e524dc969bc55057467a2bbe7f9a59a6db7c7fcdc1b7d37%40%3Cdev.ignite.apache.org%3E

Reference Links

// Links to various reference documents, if applicable.

Tickets

// Links or report with relevant JIRA tickets.

  • No labels