Overview

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.

Figure 1. JLupin Reactive Channels Overview.

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 JLupinChannelManagerService.


Architecture

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:

Figure 2. JLupin Reactive Channels Architecture.

Lets assume that web application WebApp1 makes an reactive request to the application microservice app_A using 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:

Figure 3. JLupin Reactive Channels data flows.

The whole process has the following stages:

  1. The app_A microservice opens stream channel to SAMPLE located on channels_1 microservice and start acting as a publisher ready to send messages (using JLRMC entry point located on Main Server).
  2. The web application WebApp1invokes a service on the app_A microservice using JLRMC entry point on Main Server.
  3. Just after invoking the service the WebApp1 subscribes to stream channel SAMPLE located on channels_1 microservice. (it uses the same streamChannelId as microservice app_A which got during service invocation).
  4. The microservice app_A sends part of the response (for example: set of rows from database) as messages to channel SAMPLE.
  5. The WebApp1 as a subscriber is getting messages from channel SAMPLE gradually 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

Configuration files are provided with channel microservices. If consists of two files:

configuration.yml

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

channels.yml

This file contains channels definitions and their parameters.

Section 'CHANNELS'

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'

Description:

Parameter Description
garbageThreadAmount The number of threads assigned to channel garbage collection process (cleaning channels).
channelTimeOutInMilliseconds The maximum time (expressed in milliseconds) that a channel can be opened for publishing. After this time the garbage collector closes the channel.
elementTimeOutInMilliseconds 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.
waitTimeBetweenCheckingChannelsInMilliseconds The time period (expressed in milliseconds) at which the garbage collector check and clean a channel.
storageClassName 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'