My JSF app does the following:
User inputs rows of data into a input ares.
User hit submit, button action is wired up to call remote REST services (1 call per row data)
Result of each REST call persisted into DB.
Problem is this operation is synchronous and the user does not have control of the UI until the calls are finished.
Related
I have an application that can be reduced/simplify to this flow:
user sends request to app A
app A inserts info about the request and user into DB ( marked as "B in progress" and "C in progress")
app A pushes the data into queue and returns to user
app B retrieves data from queue and process it
app B finishes processing the data and marks record in DB as "B done"
app C retrieves data from queue and process it
app C finishes processing the data and marks record in DB as "C done"
In other words, user sends request to app, app saves the record to the database and send it to queue, app B and C takes request from queue and process it ( each app does different thing but requires data from request ) and when they are done i want to mark the request in db as done for both APP.
This can be achieved, if all apps share DB. However sharing the DB like this between microservices is considered anti-pattern.
What are some design patterns to solve this? Am i really left with only option - make app A expose rest API and call the endpoint from app B and C to update the row in DB?
Thanks for help!
This more sounds like choreography , event driven process. Instead of DB, did u consider using Kafka where status gets enriched at each publish.
I have a snippet from angular UI that will call myService.getNames() when user types in a letter in the field. The switchMap will cancel the previous request whenever the user types in another letter in the field.
.pipe(
debounceTime(500),
switchMap(value => this.myService.getNames(value))
)
This service will call the REST endpoint http://localhost:8080/listing?value=<value_sent_from_client>. The query for retrieving the list of names takes some time to complete. If the user edited the field 3 times, there will be 2 cancelled requests and 1 on-going request.
On the server side, how do you cancel the 2 previously running queries? Or will they get cancelled automatically?
You cannot cancel request on server side. The solution might be in more sophisticated algorithm, like:
each request are putting into queue and return immediately not waiting for processing to be finished (storing in DB, etc.)
queue replace previous items if new items are present from same user
client subscribes to updates from server via web-sockets
Or any other approach.
I have a rest API that will upload a file to AWS and return a success response to the user.
I now have a requirement where I should post the uploaded data's details to another service for reporting purposes.
But the problem here is, this posting of data should be done independently without altering the response time of the API.
i.e. After uploading has been completed, I should run a background process that will post the data to another service, meanwhile the success response should be sent back to the user without any delay.
I have gone through some solutions and I tried something like with below snippet:
if(uploadSuccess) {
response.setStatus(HttpsServletResponse.SC_OK);
//Post data to reporter
CompletableFuture.runAsync(() -> postUploadedData(fileName,
fileId));
}
With this approach the task is running in the background but the API response is held till the data post call has been completed.
Is there any other ways that I can achieve this?
My operation takes 30 mins to process which is invoked by a rest call request. i want to give the client an immediate response telling operation in progress,and processing should happen in another thread, what is the best way to crack this out,Is deferred result the only way.
30 minutes is a long time. I'd suggest you using websockets to push progress updates and operation status.
Since you are providing rest services, another approach could be to immediately return 'Accepted' (202) or 'Created' (201) to the client and provide a link to another service that would provide updates about the progress status of the processing. This way the client is free to decide whether to poll the server for updates, or just provide the user an 'update status' button.
Use a message queue (ActiveMQ, Redis).
Send request from client.
Controller gets request, post process/message in message queue.
Send response back to client saying it's processing.
Another thread to look for changes/new process in message queue.
Execute the process - Update the status in message queue each step is completed. - (started/running/completed/failed).
You can show the status of process everytime with the id of process in queue.
Objective: generate excel report.
i call a controller(JAVA) after clicking submit button from UI. After that, i populate data using procedure and do manipulation in service layer.which takes a long time, due to which i get gateway timeout error on UI (there is some amount of load on server).
So, now i was planning to call controller from UI and tell the user that excel report will be emailed to you, such that user wont wait on that screen for report.
You can do asynchronous task using spring with #Async annotation. for more detail you can have a look section 25.5.2 in spring.
Once user submits request from UI, just make an entry in database from your controller and give message to user saying "We have received your request and excel will be emailed to you".
Now in background there is job which is running, you can write this job at server side using Thread or better use Spring Batch. This job will do following
1) This will be continuously running thread, which will check is there any new entry from UI in this table, by some flag or so you can find this.
2) This job will generate excel file and email to customer
3) Once file is emailed, update flag = false in database, so that next time this job will take only flag = false records for next time processing.
Create a java program that would populate your excel sheet and rest of the things. Then in your servlet use
Process p=Runtime.getRuntime().exec(/*run your java program */);
this would create a parallel process and your servlet will end