5

I am working on a CRM we inherited. Long story short - there is a button that calls a php script which should run in background and we don't need to wait for response.

request(idata+'transferInTimeExec.php',{
    sync: false,
    preventCache:true,
    method:'GET'
});

Now, the transferInTimeExec.php takes an hour to run, it's a very complex script that deals with weekly timesheets for a recruitment company, processes them, does a lot of DB operations etc.

Using Chrome. Every time I press the button to run it, it blocks all the xhr calls until it finishes. CRM is "ajax heavy" and while the script is running, the user can't do anything, if they navigate to another subpage, no xhr requests will resolve until that process we started has finished. Even when I open a new browser tab and try to do something, it won't do it. If I open the CRM in another browser (Firefox) while the script is running, I can use the CRM.

In Network tab - the first one is pending, and as you can see all the subsequential calls to a different Ajax call wait (all have sync:false)

enter image description here

I even replaced the whole logic with PHP function sleep(30) to make it just do nothing for 30 seconds before returning anything - same issue.

I tried XHR in plain javascript, inside onClick on the button HTML markup, rather than Dojo methods - same issue.

I've done a brutal Search/Replace on the whole project, replacing sync:true to sync:false - nothing changed.

I have run out of ideas, maybe anyone here can help to figure this out? Is there a global switch for sync/async? What else could it be if not ajax issue?

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Varin
  • 2,354
  • 2
  • 20
  • 37
  • 1
    Is the request function an invocation of the 'request' library or a custom implementation? Could you perhaps include the code if it's customer, I'm thinking it could be using async/await rather than an async execution. – Tom Nijs Aug 20 '19 at 08:58
  • Did you check [this question](https://stackoverflow.com/questions/5585918/what-does-pending-mean-for-request-in-chrome-developer-window) ? – Accountant م Aug 20 '19 at 09:23
  • @TomNijs - it was the session issue in PHP. Request method is a Dojo method, not modified. – Varin Aug 20 '19 at 09:56

1 Answers1

3

Your script transferInTimeExec.php is probably using session. When thats the case, other AJAX Call would not initiate and instead wait for this AJAX Call to Finish so as to not overwrite the session data. Setting AJAX call to asynchronous does not change the behavior.

If this script takes 1 hour to run it is a bad idea to call it as an AJAX from UI. You should setup a Cron, hourly or daily, and perform all the operations in the backend. Of course, you will need to make some adjustment to the script if it is using session.

EDIT

You could use session_write_close(); at the top of your script. This tells the PHP that this script would not write anything to the Session so other AJAX Calls are free to use the Session. However be careful to not write anything to Session after this as this will result in an error.

ascsoftw
  • 3,466
  • 2
  • 15
  • 23
  • It is using session, as it needs a couple of variables stored in the session. I didn't know about this mechanics. I will try a hacky fix to first fetch those variables and then call the actual script without having to use session in itself. Will report right back. I know it'd be better to run cron, but this has to be "on button press". I could put a bool in database and run cron every minute BUT actually run only if that bool is `true` but that's something they wouldn't pay me for as its out of scope... – Varin Aug 20 '19 at 09:05
  • From the browser's point of view a session is just a cookie, I don't think it has something to do with this behavior of synchronizing the requests! – Accountant م Aug 20 '19 at 09:17
  • @Accountantم This is not related to Browser. It is caused by PHP. Check this. https://stackoverflow.com/questions/12401358/why-should-session-write-close-be-used-in-long-polling – ascsoftw Aug 20 '19 at 09:23
  • @ascsoftw oooh, I get it , so the requests have been fired but the server is not responding ? I thought that the browser is blocking the requests (didn't send them to server at all waiting for the first one to responde), is that right ? – Accountant م Aug 20 '19 at 09:26
  • yes. as per OP it takes about 1 hour to complete the script. So the browser is waiting. Since its a Session issue, OP is able to open the website in another browser and it works fine there. – ascsoftw Aug 20 '19 at 09:28
  • Ok, both solutions work, either calling first ajax, getting vars from session and then calling another one with those variables. Or, using the `session_write_close();` Thank you for this, you saved me a lot of time. Does `session_write_close()` affect anything apart from the script that is being run? As in, if I call it in that php file, will this affect anything else that is being run during that time at all? For example, if another script that runs at the same time writes something to session? – Varin Aug 20 '19 at 09:55
  • session_write_close() should only be written into this particular script. As long as this script is not writing anything to DB, it would not affect anything else that is being run at the same time. – ascsoftw Aug 20 '19 at 09:57
  • @ascsoftw Oh I did, and I approved as a valid answer as well :) – Varin Aug 20 '19 at 10:19
  • This answer deserves more attention – Accountant م Aug 20 '19 at 19:49