Home
Categories
Dictionary
Glossary
Download
Project Details
Changes Log
What Links Here
FAQ
License

Invoking a service



The method ServiceInstance.invoke() allow to invoke a Service in a Module which is a provider of this Service. Note that this method will only have an effect after the start of the Framework.

Note that by default the framework will perform the invocation using a background Thread pool, using a ThreadPoolExecutor with only one Thread in the pool. However it is possible to customize the way the invocation will be performed:
  • default: Customizing the number of background threads used by the Thread pool
  • blocking: Calling the invoke method in the same Thread as the caller. This can be specified at the framework level, service level, or for each invocation
  • copy: Calling the invoke method in a background Thred, but copy the content of the service before making the call
  • Specifying the domain on which each Thread pool will be applied (by default there will be one Thread pool for each module)

Specifying the number of Threads in the pool

Main Article: framework properties

The servicesExecutorPool framework property allows to specify the number of Threads which will be used in the background Threads pool if the framework perform the services invocation in a background Thread. By default there is only one Thread in the pool.

Note that by default there will be one Thread pool for each module, but it is possible to override this behavior.

Specifying the mode of invocation

It is possible to change the mode of invocation:
  • A the framework level
  • A the service level
  • For each invocation

At the framework level

Main Article: framework properties

It is possible to set the mode of invocation at the framework level by specifying the serviceInvocationMode property:
  • By default, or if the property has the executorService value, the framework will perform the invocation in a background Thread
  • If the property has the blocking value, the framework will perform the invocation in the same Thread as the caller


For example:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <property key="serviceInvocationMode" value="blocking" />
      </files>

At the service level

It is possible to set the mode of invocation at the service level by specifying the value of the invocationMode attribute in the service definition:
  • By default the framework behavior will be used
  • If the attribute has the executorService value, the framework will perform the invocation in a background Thread
  • If the property has the blocking value, the framework will perform the invocation in the same Thread as the caller
Note that the value of the attribute will specify the behavior for this service only.

For example:
      <publish name="position" invocationMode="blocking" >
         <data name="latitude" type="float" />
         <data name="longitude" type="float" />
         <data name="altitude" type="float" />
      </publish>

For each invocation

It is possible to perform the invocation in the same Thread as the caller regardless of the configuration by calling the ServiceInstance.invokeAndBlock() method.

For example:
      eventService = module.getService("event");
      eventService.setDataBooleanValue("event", true);
      eventService.invokeAndBlock();
It is also possible to perform the invocation in another Thread but copying the content of the service priori to the call by calling the ServiceInstance.invokeAndCopy() method.

For example:
      eventService = module.getService("event");
      eventService.setDataBooleanValue("event", true);
      eventService.invokeAndCopy();

Example

For example:
      eventService = module.getService("event");
      eventService.setDataBooleanValue("event", true);
      eventService.invoke();
The method will return true if the invocation has been successful, and false in the following cases:
  • The Module which invokes the Service is not a provider of this Service
  • The Module which invokes the Service is not attached to the Service
  • The Module has invoked the Service before the start of the Framework

Specifying the domain of the Thread pools

By default there is one Thread pool for each module, but it is possible to create only one pool for the whole framework.

For example:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <property key="serviceInvocationDomain" value="global" />
      </files>

Ordering of the notifications

Default ordering

By default:
  • The serviceInvocationMode is executorService, which means that a Thread pool will be used
  • The servicesExecutorPool is 1, which means that only one Thread will be used
  • The serviceInvocationDomain is module, which means that there will be one pool for each module
It means that by default:
  • You will never loose any service invocation. By design of the Java Thread pool class, notifications are added in a queue
  • The ordering of invocations will be kept for one module, but not for the whole framework (because there is one pool for each module). If you want to be sure that the ordering will be kept globally, you must set the serviceInvocationDomain as global
  • You can never be sure of when the invocation will be performed. If you want to be sure that the notification is performed immediately, you must set the serviceInvocationMode as blocking


For example in the following use case the same module invoke two services in a short time: the existence of the pool with only one Thread for the module means that if the subscribers take a lot of time to process the notification, the second service will notify the subscribers after some time.
sequenceruntime2
In the case where two different modules invoke services, it is possible that a service which has been invoked after another one will be notified before if there is much more pressure on the Thread pool for the first module provider[1]
If you want to avoid that, you will need to use a global thread pool
:
sequenceruntime3

Using a global Thread pool

It is possible to keep the ordering of the invocations, but still use a background Thread for the invocations, by creating only one pool for the whole framework: For example:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <property key="serviceInvocationDomain" value="global" />
      </files>
Note that by default there is only one Thread in the pool, which ensures that the invocations are performed in the correct order.

Performing the invocation in an unique blocking Thread

In that case, each call will be blocking and performed in the caller Thread. For example:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <property key="serviceInvocationMode" value="blocking" />
      </files>

Notes

  1. ^ If you want to avoid that, you will need to use a global thread pool

See also


Categories: concepts

Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence