Spring WebFlux + Server Sent Events (SSE)

Introduction

What options we have to gather long processing data from the backend to send out to the UI?
Usually the followings:

  • open frequent connections – polling
  • keep an open connection – websocket

Server Sent Events

With Server Sent Events you’re able to send continuous updates from the server.
Imagine as a client subscription to a server for a stream.
Sometimes we don’t need a full bi-directional protocol (sending data back from client side), just a non-blocking data flow with the ability to process data row by row, while still receiving from the connection.
These are updates, time splitted data chunks from the server side to provide a fluent UI experience.

advantages:

disadvantages:

  • unidirectional protocol
  • simultaneous request limit (browser defaults: 6)

WebFlux

With reactive programming, the purpose of this type of data processing is the fluency and non-blocking nature.

There are more conceptual advantages, like: backpressure, split and delayed and limited processing of data.

It supports asynchronous and event-driven concept in programing with a fluent stream-like API.

The reactive API is present in Spring since version 5

It can be used with the specific content types in between:

  • backend-backend server-client (SOA/microservice calls)
  • backend-ui server client (server-browser calls)

Example Project

I picked some sample data about a movie database.
Our sample application is very simple: We stream the file line-by-line. Convert the data into a data model and producing the result as a stream to the endpoint.
The client side subscribed to the backend endpoint and processing the data line-by-line.
This way we have a stream from a datasource till the client visualization streamlined.

Backend stream logs

UI streaming processing and visualization

Besides the standard Flux stream we only needed to use the EVENT_STREAM Mediatype. While on the UI client side EventSource interface is required to capture the stream.

For more details see the Webflux + SSE example project: https://github.com/PazsitZ/webflux_sse

Multilevel-KeySearch

Why? What’s this all about?

This is a library to handle (store-search) multi level key attributes.
The implementation was driven by the need of

  • handle multiple level keys
  • flexible search
  • ranking/ordering

on the matches .

Lets consider data with multiple levels: category / subcategory / group / item levels for example.
If you want to find specific let’s say: subcategory, that’s an easy task. You can filter/map and you get it. But what if you have multiple attribute to match, multiple key lengths? How will you sort them? This task can be achieved, but requires more and more code and you lose fluency.

The details

The idea was, that you can easily instantiate keys, then define a collection. This way where you can pre-define the filter and sort algorithm on the collection itself, and you can use it almost the regular way.
The key has the capability to define wildcard, which is customizable.

As an example, we define a flexible matching keylength, an comparison which uses null as wildcard:

new CustomMultiKey(    
    KeyLengthRule.matchSmaller(),
    KeyComparisonRelation.equalAndAny(null),
    null
);

I choose map to store the keys, this provides even a value or it can be the key itself.

Let’s get some examples:

MultiKeyMap<String, String> map = getMap();
String aHuman = map.getIfAbsentFirst(map.newKey().addAny().add(HUMAN));

This way you will get all the human subcategory, and by your map it will be a sorted order, you will get the first one.

On the key and map you can define:

  • keylength rule
  • Comparison rule
  • Sorting rule

All the above have already implementations provided, but by the interfaces you can easily provide further custom rules.

What features are ahead?

My future ideas revolving around more query like syntax, parallel search and multi-rule definition.

The source is available: https://github.com/PazsitZ/multilevel-keysearch
The jars available: http://pazsitz.hu/repo/hu/pazsitz/keysearch/

Class-Method Caching

When you have the need of caching that’s a quite common topic, you can find many out-of-the-box solutions.

But what if if you want to cache whole class, with all the methods, maybe across your whole application?
My solution based on a proxy class and this way applies cache on all method invocations. The cache configuration of course can be defined, but the basis can see in the example:

ClassInterface class = new Class();
ClassInterface cachedClass = CacheClass.localCache(ClassInterface .class, class, CacheClass.CacheType.ACCESS, 30);

So in the above example we need an interface, a class instance and some configuration options for caching.
This way we’ll get a Proxy class, which will cache our methods, where we use the cachedClass instance.

This is all good, but what if we want to have caching across the application.

@Bean("classCached")
public ClassInterface getCachedClass() {
    ClassInterface class = new Class();
    ClassInterface cachedGloballyClass = CacheClass.globalCache(ClassInterface.class, class );
    return cachedGloballyClass;
}

This way whereever we inject the cached instance all of the invocation, will point the same instance, this way it will share the cachepool.

My implementation is using the guava caching library, hardwired for now.
But any caching library can serve inside the proxy solution.

The source is available: https://github.com/PazsitZ/methodcaching
The jars available: http://pazsitz.hu/repo/hu/pazsitz/methodcaching/