IDIEP-46
Author
Sponsor
Created

 

Status

COMPLETED


Motivation

Thin clients should be able to invoke Ignite Services.

This IEP is about existing services (deployed to the cluster). Deployment is out of scope.

Description

Service invocation is a two-step process:

  • Get a Service Proxy by a string name and an optional sticky flag
  • Invoke a method by a string name and an argument array

Existing PlatformServices.java is a good start for the server-side logic, see OP_SERVICE_PROXY and OP_INVOKE.

But for thin clients, if we create a proxy by a separate operation we should store this resource somewhere on the server-side and we should also have an ability to close this resource when it's not needed anymore. So there is an additional operation on client-side needed to close the proxy explicitly. This is more complex from users point of view than the current approach for java thick client, so perhaps for thin client it's better to do both steps in one operation and create a service proxy on each method invocation. 

Benchmarking is needed to choose between these approaches.

Two operations approach

Operation codes

Two new client operations are required:

Name

Code

OP_SERVICE_GET_PROXY7000
OP_SERVICE_INVOKE7001

OP_SERVICE_GET_PROXY message format

Request
StringService name
byte

Flags:

0x01 Sticky flag

0x02 Keep binary flag

longTimeout
intCount of nodes selected to invoke service. If this value is 0, no server nodes should be explicitly listed in the message, but all server cluster nodes should be selected. 
UUID * count

Node IDs

Response
longresourceId

Resulting resourceId should be used to call the service with OP_SERVICE_INVOKE and to release the proxy with OP_RESOURCE_CLOSE.

OP_SERVICE_INVOKE message format

Request
longResource ID
StringMethod name
int[]Argument type IDs to resolve method (optional, can be NULL, see "service name resolve logic")  
intArgument count
Object * countArguments
Response
ObjectResult

One operation approach

In this case, sticky flag is useless since we always will create a new proxy for each request. 

Operation codes

New client operation is required:

Name

Code

OP_SERVICE_INVOKE7000

OP_SERVICE_INVOKE message format

Request
StringService name
byte

Flags:

0x01 Keep binary flag

0x02 "Has parameter types" flag (see "service name resolve logic")

longTimeout
intCount of nodes selected to invoke service. If this value is 0, no server nodes should be explicitly listed in the message, but all server cluster nodes should be selected. 
UUID * count

Node IDs

StringMethod name
intArgument count
(int? + Object) * countArgument type IDs to resolve method (if "has parameter types" flag is set) + Arguments
Response
ObjectResult

Benchmark results

Benchmarks were made by Yardstick framework with 4 servers and 4 drivers (each server and driver on own hardware host). Each driver has 128 threads to invoke cluster-singleton service. Each thread has its own client. Each benchmark was run for 3 minutes with 1 minute warmup. Service proxies were created at warmup, benchmark threads just invoke method from already created proxies. 

There 20 benchmarks totally were made (10 with the one-operation approach and 10 with the two-operations approach).

Results:

tps 1, op/sec, AVGlatency 1, nsec, AVGtps 2, op/sec, AVGlatency 2, nsec, AVGdelta tpsdelta latency
390113262510339393026002880,98%-0,95%
38330726715313708312762661-3,25%3,41%
378431270638138254026787671,09%-1,02%
372316275031437788427113881,50%-1,42%
38325826729523807902689943-0,64%0,64%
381941268163939800625734714,21%-4,03%
378778270399937997126953590,31%-0,32%
374484273575838026026948531,54%-1,50%
37953526983153750982731863-1,17%1,24%
37419627370323730182746522-0,31%0,35%

Conclusion: there is almost no difference between the one-operation approach and the two-operations approach (about 1% on average), so there is no reason to implement two-operations approach. Single-operation approach should be implemented as more convenient from the user's point of view.

Service method resolve logic

In .Net thick client implementation there is a method used to find an appropriate service method to invoke by method name and args values: PlatformServices.ServiceProxyHolder#getMethod. But methods of some interface can be overloaded and using only args values we don't have full information about args types, so sometimes we can't find method only by method name and args values for overloaded methods.

For example, if you have an interface like:

public interface TestServiceInterface {
    public String testMethod(String val);
    public String testMethod(Object val);
}

And invoke service like:

Object arg = null;
svc.testMethod(arg);

Java will resolve the correct method to call on client-side, but using only arg value (null) it's impossible to get exactly one method on the server-side (PlatformServices.ServiceProxyHolder#getMethod will throw an error in this case: Ambiguous proxy method 'testMethod')

To solve this problem we can pass additional information (parameter types) optionally instead of just method name. If parameter types are passed - method should be resolved using this information, if parameter types are not passed method should be resolved using argument values (the same way as PlatformServices.ServiceProxyHolder#getMethod).

To pass parameter types "has parameter types" flag of the request should be set. In this case, each argument is prefixed by int value - argument's binary type ID.

Client-side API (java thin client)

The new interface should be added for thin-client services to get service proxies:

ClientServices
public interface ClientServices {
    public ClientClusterGroup clusterGroup();
    public <T> T serviceProxy(String name, Class<? super T> svcItf);
    public <T> T serviceProxy(String name, Class<? super T> svcItf, long timeout);
}

Objects of this interface can be obtained using methods from IgniteClient:

IgniteClient
public ClientServices services();
public ClientServices services(ClientClusterGroup grp);

Risks and Assumptions

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

Discussion Links

http://apache-ignite-developers.2346864.n4.nabble.com/IEP-46-Thin-client-Service-invocation-td47504.html

Reference Links

// Links to various reference documents, if applicable.

Tickets

key summary type created updated due assignee reporter priority status resolution

JQL and issue key arguments for this macro require at least one Jira application link to be configured

  • No labels