WebFlux - handle each item asynchronously before returning - spring-boot

I am fairly new to WebFlux and I am looking for what seems to be a pretty normal usage pattern. Basically what I have is a Spring Controller which returns a Flux< A > (where A is a row fetched from the DB using R2DBC). I want to do an async operation on each received object (for instance I want to send a push notification for each object, for which I also need to make a call to the DB for the users push token and then send the push). The operations should be done asynchronously, so the API end-users receive their data with no delay. Is there some pattern for this already?

Related

springboot endpoint async response

I am working on a springboot REST API.
I have one endpoint whih is in charge of doing several treatments.
I would like that each time a treatment is done it return it back right away to the caller.
so it will not wait that the entire treatments are done before returning a result.
#async is not exactly what I want because it will run a new thread for the whole endpoint and will return a result when all treatments will be done.
Even, I tried a threadPoolExecutor and I used one thread by treatment but also I cannot return each thread result right away. I have to wait that all threads end before returning the result.
So is there away that will take care of each treatment and return it own result right away when it is done?
Depending on your architecture you have a few option:
you would send the request as it is now; on the backend side you would generate a new id for the request, and send back that id to the client. Now the client could subscribe to the websocket and wait for the backend to push the id related result to the websocket.
you could use a messaging solution which would be similar to the previous one, but with Kafka, RabbitMQ, ...
you could implement a polling mechanism between the two side: you would return an id like in the previous options and the client would check the status of the request with the id periodically from the backend. When the status is completed, it could fetch the result from another endpoint using the id.

Is filter the right place to handle service calls based on header values in Spring?

Looking to make a service call based on a header value.
I can see two options:
1) Do it from the controller which is mainly used for a different service.
2) Add a filter which will do this by reading the request context.
Want to know what's the best way to handle this in a Spring application.
I guess it depends on your requirements.
Controller:
If you have to make service calls for preparing the response of a specific controller. For example, you have a controller say:
/employee
fand or preparing the response of this endpoint you need to call say staff service.
In this case, it's better to handle such calls in controllers.
Filter:
If you want to intercept each request and perform some operation on the request before sending it to the controller or before sending the response to the client.
A use case here can be checking the roles of the user by intercepting all requests.
As we know by using the filter, we can perform two operations at two instances −
Before sending the request to the controller
Before sending a response to the client.
In this case, OncePerRequestFilter is quite useful from the spring web module.
Quoting the documentation :
Filter base class that aims to guarantee a single execution per request dispatch, on any servlet container.

Python Requests - Batch API calls

I am working on an API to push records from a database to endpoint.
I have managed to write a piece of code which grabs the records, it's parsing them and finally pushing to API and works just fine.
It manages to push around 400 req/min and I was wondering if I can batch this requests to make it a bit more performant, but I can't wrap my head around how this can be achieved.
The API call url is:
http://call-url.com/service/{id}
Consider payload for id:
id = 101
{
"stars":3
"position":5
"date":"2002-04-30T10:00:00+00:00"
}
url = http://call-url.com/service/101
I am using python and requests module to push the records.
As we speak I am grabbing the records and parsing load for each individual id and pushing them.
I bumped into asyncio and threading so far, but I need to ensure I don't push the same request twice.
Is it possible to push more than 1 record at once?
Thank you,
You can utilize any AMQP message broker. RabbitMQ for example. The concept is simple, just check the tutorial. Split your script to main.py (read DB, prepares payloads and push them to the queue) and worker.py (get payload from the queue and send to API), and then just spawn as many worker.py processes as you need...

Blocking message pending 10000 for BLOCKING..using spring websockets

I am facing the following error while using spring websockets:
Use case: On our server side code we have a fucntionality to search values in data base..if the values are not present in database..it will hit a servlet and get the data..The second part i.e., hitting servlet and getting the data is asynchronous call.
So for one request there are multiple things we have to search for in data base..
Example: In request we got a some parameter channel: 1
This channel is mapped to multiple ids say 1 is mapped to 1,2,3,4,5
In websocket once the request comes to server i will extract the channel and get all the id's mapped and run a loop over id's as follows:
for(int i=0;i<ids.length;i++)
{
SomeObject databaseRespObj=callToDatabase(i); //SomeObject contains two fields value exists and string values
if(!databaseRespObj.valuesExists)
{
AsynchronouscallToServelt(i);
//once response received it will send message immediately using session
}
}
While execution of above server side code,some times only i am facing the below error.
java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendString(WebSocketRemoteEndpoint.java:379) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.springframework.web.socket.adapter.jetty.JettyWebSocketSession.sendTextMessage(JettyWebSocketSession.java:188) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
Sorry if the above framing of the question is not clear.Will spring support sending asynchronous messages like normal javax websocket does Session.getAsyncRemote().sendText(String text)
What is the configuration made in spring to send asynchronous messages using websocket session
From what I understand, you have multiple threads sending messages on the same RemoteEndpoint when the asynchronous technique kicks in.
Seems very similar to this :
WebSocket async send can result in blocked send once queue filled
I don't thing you necessarily have to use Futures or mechanisms described in the above post.
What I don't really get is : why doing asynchronous call to servlets ? Ofcourse several could send messages on the same RemoteEndPoint..
But can't you simply make synchronous calls to the relevant classes and keep the same request-response flow that you use when records are found in your database ? :)
UPDATE
Since you added in comments the fact that you need to focus on speed, and since it seems that your current solution is not applicable, let's maybe have a look at the problem from a different angle.
I'm not a websocket expert but as far as I understand what you try to achieve with the asynch servlet calls is not possible.
However, if you change the design/config of your project, this should be achievable.
Personally I use Websockets to be able to send a message to an arbitrary user that did not necessarily made a request - as long as he is connected, he must get the message.
To do this, I simply use the SimpMessagingTemplate class offered by Spring in their websocket support. To send a message to ANY USER THAT I WANT, I do this :
#Autowired
SimpMessagingTemplate smt;
(.......)
smt.convertAndSendToUser(recipient.getUsername(), "/queue/notify", payload);
So in your case, you could, in your loop :
make class instance method calls (instead of a servlet, no network transit, you cannot be faster ! Just a call to your biz-logic / service / whatever)
every time a method returns data, use the SimpMessagingTemplate like in the snippet here above :)
you can still do it asynchronously if you want ! :)
By doing this, you reduce latency (calling servlets adds alot), and have a reliable technique.
You can easily and quickly send thousands of messages to one user or to several users, at your own discretion, without stumbling upon the "10000 for BLOCKING" problem, which probably comes from more than 1 servlet "answering the same question" ;)
To obtain a SimpMessagingTemplate from Spring, you will need to use the <websocket:message-broker> tag or the equivalent non-xml-java-config.
I suggest to check this doc which has more info :
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
and the following post I created on SO where I am using it (I've got another problem in the post, related to spring configuration and context hierarchies, but at least you have some template code to look at, the code is working) :
Spring Websocket : receiving nothing from SimpMessagingTemplate
Spring : how to expose SimpMessagingTemplate bean to root context ?

Tracking ajax request status in a Flux application

We're refactoring a large Backbone application to use Flux to help solve some tight coupling and event / data flow issues. However, we haven't yet figured out how to handle cases where we need to know the status of a specific ajax request
When a controller component requests some data from a flux store, and that data has not yet been loaded, we trigger an ajax request to fetch the data. We dispatch one action when the request is initiated, and another on success or failure.
This is sufficient to load the correct data, and update the stores once the data has been loaded. But, we have some cases where we need to know whether a certain ajax request is pending or completed - sometimes just to display a spinner in one or more views, or sometimes to block other actions until the data is loaded.
Are there any patterns that people are using for this sort of behavior in flux/react apps? here are a few approaches I've considered:
Have a 'request status' store that knows whether there is a pending, completed, or failed request of any type. This works well for simple cases like 'is there a pending request for workout data', but becomes complicated if we want to get more granular 'is there a pending request for workout id 123'
Have all of the stores track whether the relevant data requests are pending or not, and return that status data as part of the store api - i.e. WorkoutStore.getWorkout would return something like { status: 'pending', data: {} }. The problem with this approach is that it seems like this sort of state shouldn't be mixed in with the domain data as it's really a separate concern. Also, now every consumer of the workout store api needs to handle this 'response with status' instead of just the relevant domain data
Ignore request status - either the data is there and the controller/view act on it, or the data isn't there and the controller/view don't act on it. Simpler, but probably not sufficient for our purposes
The solutions to this problem vary quite a bit based on the needs of the application, and I can't say that I know of a one-size-fits-all solution.
Often, #3 is fine, and your React components simply decide whether to show a spinner based on whether a prop is null.
When you need better tracking of requests, you may need this tracking at the level of the request itself, or you might instead need this at the level of the data that is being updated. These are two different needs that require similar, but slightly different approaches. Both solutions use a client-side id to track the request, like you have described in #1.
If the component that calls the action creator needs to know the state of the request, you create a requestID and hang on to that in this.state. Later, the component will examine a collection of requests passed down through props to see if the requestID is present as a key. If so, it can read the request status there, and clear the state. A RequestStore sounds like a fine place to store and manage that state.
However, if you need to know the status of the request at the level of a particular record, one way to manage this is to have your records in the store hold on to both a clientID and a more canonical (server-side) id. This way you can create the clientID as part of an optimistic update, and when the response comes back from the server, you can clear the clientID.
Another solution that we've been using on a few projects at Facebook is to create an action queue as an adjunct to the store. The action queue is a second storage area. All of your getters draw from both the store itself and the data in the action queue. So your optimistic updates don't actually update the store until the response comes back from the server.

Resources