'Groovy PromiseMap - Can I limit the asynchronous thread pool?

I am making a (quick and dirty) Batching API that allows the UI to send a selection of REST API calls and get results for all of them at once.

I am using PromiseMap to make some asynchronous REST calls to the relevant services, which get collected afterward.

There could be a large number of threads that need to run, and I would like to throttle the number of threads that run at the same time, similar to Executor's thread pool.

Is this possible without physically separating the threads into multiple PromiseMaps and chaining them? I haven't found anything online describing limiting the thread pool.

//get requested calls
JSONArray callsToMake=request.JSON as JSONArray 

//registers calls in promise map
def promiseMap = new PromiseMap()
//Can I limit this Map as a thread pool to, say, run 10 at a time until finished

data.each {
def tempVar=it
promiseMap[tempVar.id]={makeCall(tempVar.method, "${basePath}${tempVar.to}" as String, tempVar.body)}
}

def result=promiseMap.get()
def resultList=parseResults(result)
response.status=HttpStatusCodes.ACCEPTED
render resultList as JSON

I'm hoping there's a fairly straight-forward setting that I may be ignorant of.

Thank you.



Solution 1:[1]

withPool doesn't seem to be working. Just incase if anyone is looking to limit threads here is what i did. We can create a custom Group with custom ThreadPool and specify the number of the Threads.

def customGroup = new DefaultPGroup(new DefaultPool(true, 5))
try {
  Dataflow.usingGroup(customGroup, {
    def promises = new PromiseList()
    (1..100).each { number ->
      promises << {
        log.info "Performing Task ${number}"
        Thread.sleep(200)
        number++
      }
    }
    def result = promises.get()
  })
}
finally {
  customGroup.shutdown()
}

Solution 2:[2]

Use

runtime 'org.grails:grails-async-gpars'

at build.gradle And

GParsExecutorsPool.withPool(10){service ->
    Shop.list().each{shop ->
        Item.list().each{item ->
            service.submit({createOrder(shop, item)} as Runnable)
        }
    }
}

in your Service for example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JChap
Solution 2 Onoroco