2

I have created a REST API that receives a HTTP POST request(array of json requests) from UI. This would trigger a Xquery code which would spawn the requests to execute some functionalities and it may 10-30 mins to get completed.

If the request gets into the XQuery code, we just want to send the response back with status "Upload triggered successfully" and let the task on server side continue running in background without UI waiting for the process to get completed. As the task runs in background, a report document is inserted and the completed request count is updated after each request process complete.

Please find below the code outline for the same.

declare function local:upload-record($req-xml, $chunk-size,$upload-uri){
    if (exists($req-xml))
    then (
    let $log := xdmp:log("Upload started")
    <!-- some code to execute functionalities-->

                     ,
                      xdmp:spawn-function(function(){ 
                        local:upload-record(subsequence($req-xml, $chunk-size+1), $chunk-size,$upload-uri) 
                          }, 
                        <options xmlns="xdmp:eval">
                        <result>true</result>
                        
                        <update>true</update>
                        <commit>auto</commit>
                        </options>))
                   
     return $response)
     else xdmp:log("Job completed successfully")
};

let $req := xdmp:get-request-body("json")/node()

let $config := json:config("custom")
let $req-xml := json:transform-from-json($req,$config)
let $chunk-size := 10

let $resp := local:upload-record($req-xml, $chunk-size,$upload-uri)
  
return <response>Upload triggered successfully</response>

I need help in implementing below questions.

  1. To return status response once the request reached ML code without UI waiting for the process to get completed.
  2. Determine proper chunk size based on number of requests.(min req count: 1 max:1000).Maximum number of threads configured for the app server is 32.

Please let me know your thoughts. Thanks in advance!

Antony
  • 183
  • 8
  • 1
    Is your issue that it is sitting waiting for all to process? Remove `true` so that it doesn't wait for each call to resolve and return data (or set it to `false`). – Mads Hansen Jul 22 '22 at 14:23
  • 1
    As for chunk size, pick a value that you think is reasonable for a single transaction. You can spawn more batches than you have appserver threads, they will just queue up and drain as the requests are completed. – Mads Hansen Jul 22 '22 at 14:25
  • @ Mads Hansen ,Your previous suggestion to change false is reducing the response time a bit but this is still taking 2 seconds for a request. When the user uploads like 100 records ,he has to wait for around 2 mins to get the message. Is there any other way to execute the local:upload method () as a separate transaction and execute the next line immediately after calling the method? – Antony Jul 25 '22 at 09:46
  • Look and see where the time is spent. If they are uploading a giant payload that needs to be converted and then recursively processed, how much of that time is in `let $req-xml := json:transform-from-json($req,$config)` and how much of the time is the recursive processing? Try running the code in Query Console with the Profile tab and see where the time is spent. – Mads Hansen Jul 25 '22 at 11:53
  • @MadsHansen The Deep % of 99% is spent in local:upload-record() method only. Because inside this I'm calling three functionalities, which is done by one http-get and two http-post calls. The http get and one of the post is taking longer time. Json transformation does not take so much time here. Is it possible to return the status first to client server and then execute this function at the background? – Antony Jul 26 '22 at 09:17
  • 1
    Any difference if you spawn the initial call to the recursive function? `let $resp := xdmp:spawn-function(function() { local:upload-record($req-xml, $chunk-size,$upload-uri) }, false)` – Mads Hansen Jul 26 '22 at 15:25

1 Answers1

1

Spawn the initial call to the recursive function and set the result option to false so that it doesn't wait to execute and resolve the results.

let $resp := xdmp:spawn-function(function() { 
    local:upload-record($req-xml, $chunk-size,$upload-uri) 
  }, 
  <options xmlns="xdmp:eval"><result>false</result></options> ) 
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147