JLupin supports publish & subscribe pattern where many clients (microservices) communicate through a channel. Channels implements classic FIFO algorithm to process messages - a message which is put in the end of the channel by a publisher/writer waits to be taken from the front and deleted by a subscriber/reader.
Configuration allows to define many channels within one channel microservice but our recommendation is to define only one channel per one channel microservice (you can define multiple channel microservices to have more than one channel) to separate channels to different JVMs. This way your channels will be more resistant to failures, outages, overloads, etc.
Why reactive? Because it enables option to stream your result part by part (as one is ready). Great example is a list with result. If we compute elements one by one, already ready ones could be sent to client and shown to user. This way there is no need to wait for last element is computed to access the first one. With streaming option for HTTP requests (supported by WebFlux for example) it is possible to show end user results as they are computed without need to wait for whole computation is done.
With standard distribution JLupin offers channel microservice - available by name
channelMicroservice which contains service
Channels are provided on channel microservices, which are native microservices (so it has a standard
configuration.yml file) with additional configuration in
channels.yml file, where channels definitions are provided:
Lets assume that web application
WebApp1 makes an reactive request to the application microservice
SAMPLE channel to get the response, located on
channels_1 channel microservive. It uses the following reactive communication schema, as show on the following diagram:
The whole process has the following stages:
app_Amicroservice opens stream channel to
channels_1microservice and start acting as a publisher ready to send messages (using JLRMC entry point located on Main Server).
- The web application
WebApp1invokes a service on the
app_Amicroservice using JLRMC entry point on Main Server.
- Just after invoking the service the
WebApp1subscribes to stream channel
channels_1microservice. (it uses the same
app_Awhich got during service invocation).
- The microservice
app_Asends part of the response (for example: set of rows from database) as messages to channel
WebApp1as a subscriber is getting messages from channel
SAMPLEgradually and start processing them (for example: display on the screen).
If would like to try it in practice take a look at developer guide.
Configuration files are provided with channel microservices. If consists of two files:
This is a standard configuration file for native microservices, where some of the parameters have been adjusted to characteristic of their functions in the environment and should be always considered in the process of system design:
- amount of memory (HEAP)
- number of threads
This file contains channels definitions and their parameters.
Each entry in this section is a definition of a channel. The name of the entry is the name of a channel that should be used during channel communication. Each channel has the following set of parameters:
The appropriate part of the configuration file:
garbageThreadAmount: 4 channelTimeOutInMilliseconds: 60000 elementTimeOutInMilliseconds: 30000 waitTimeBetweenCheckingChannelsInMilliseconds: 5000 storageClassName: 'com.jlupin.impl.microservice.partofjlupin.asynchronous.storage.streamchannel.impl.memory.JLupinMemoryStreamChannelStorageImpl'
||The number of threads assigned to channel garbage collection process (cleaning channels).|
||The maximum time (expressed in milliseconds) that a channel can be opened for publishing. After this time the garbage collector closes the channel.|
||The maximum time (expressed in milliseconds) that a message is kept by a channel until it's sent to the subscriber. After this time the garbage collector discard the message.|
||The time period (expressed in milliseconds) at which the garbage collector check and clean a channel.|
||The implementation class of storage, where messages are located (default is in-memory)|
Example configuration (channels.yml)
CHANNELS: SAMPLE: garbageThreadAmount: 4 channelTimeOutInMilliseconds: 60000 elementTimeOutInMilliseconds: 30000 waitTimeBetweenCheckingChannelsInMilliseconds: 5000 storageClassName: 'com.jlupin.impl.microservice.partofjlupin.asynchronous.storage.streamchannel.impl.memory.JLupinMemoryStreamChannelStorageImpl'