-1

I am working on a Project where our client generates almost 500 request simultaneously. I am using the forkJoin to get all the responses as Array.

But the Server after 40-50 request Blocks the requests or sends only errors. I have to split these 500 requests in Chunks of 10 requests and loop over this chunks array and have to call forkJoin for each chunk, and convert observable to Promise.

Is there any way to get rid of this for loop over the chucks?

wentjun
  • 40,384
  • 10
  • 95
  • 107
user1592129
  • 461
  • 1
  • 5
  • 16
  • You could look into my solution posted here: https://stackoverflow.com/a/62872189/6513921 – ruth Oct 18 '21 at 13:28

1 Answers1

0

If I understand right you question, I think you are in a situation similar to this

const clientRequestParams = [params1, params2, ..., params500]
const requestAsObservables = clientRequestParams.map(params => {
  return myRequest(params)
})
forkJoin(requestAsObservables).subscribe(
  responses => {// do something with the array of responses}
)

and probably the problem is that the server can not load so many requests in parallel.

If my understanding is right and if, as you write, there is a limit of 10 for concurrent requests, you could try with mergeMap operator specifying also the concurrent parameter.

A solution could therefore be the following

const clientRequestParams = [params1, params2, ..., params500]
// use the from function from rxjs to create a stream of params
from(clientRequestParams).pipe(
   mergeMap(params => {
     return myRequest(params)
   }, 10) // 10 here is the concurrent parameter which limits the number of 
          // concurrent requests on the fly to 10
).subscribe(
   responseNotification => {
      // do something with the response that you get from one invocation
      // of the service in the server
   }
)

If you adopt this strategy, you limit the concurrency but you are not guaranteed the order in the sequence of the responses. In other words, the second request can return before the first one has returned. So you need to find some mechanism to link the response to the request. One simple way would be to return not only the response from the server, but also the params which you used to invoke that specific request. In this case the code would look like this

const clientRequestParams = [params1, params2, ..., params500]
// use the from function from rxjs to create a stream of params
from(clientRequestParams).pipe(
   mergeMap(params => {
     return myRequest(params).pipe(
        map(resp => {
           return {resp, params}
        })
     )
   }, 10) 
).subscribe(
   responseNotification => {
      // do something with the response that you get from one invocation
      // of the service in the server
   }
)

With this implementation you would create a stream which notifies both the response received from the server and the params used in that specific invocation.

You can adopt also other strategies, e.g. return the response and the sequence number representing that response, or maybe others.

Picci
  • 16,775
  • 13
  • 70
  • 113