Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Session Synchronisation

I am developing a WebApp in PHP. The user will be able to click a button and the PHP code will end up calling a system exec. Since the WebApp will be using AJAX, there is the possibility that the user could click the button twice, or indeed click another button which would start another exec process.

Now, I know that I could write a little javascript that would disable the buttons until the single event has been completed. However, this is client side enforcement, which can easily been overwritten.

Is there somethig I could do on the PHP side to stop things like this happening? In my head, I have an idea of having a session variable act as a "semaphore" and before every script is executed, this variable would be checked and must return 0 before the script could continue.

Am I going about that the right way? Or does that just open a can of worms for deadlocks/race conditions?

Thanks

Update: Just to put it into context, the system I'm developing will be used to start, stop, and reimage Virtual Private Servers. If the reimaging button was pressed, the PHP script will call some bash script to start to re-image the VPSes. However if a user tried to start the VPS while this was being done....

like image 748
jtnire Avatar asked Nov 15 '22 00:11

jtnire


1 Answers

You could use jQuery.ajax() and set the option async to false:

async Default: true By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active

You could use it like this:

$.ajax({
    type: "POST",
    url: "file.php",
    async: false,
    data: data,
    success: function(return){
        alert("Success: "+return);
    }
});

If you want to add a loader just apply it as:

startLoader();
$.ajax({
    type: "POST",
    url: "file.php",
    async: false,
    data: data,
    success: function(return){
        alert("Success: "+return);
    }
});
endLoader();

However you PHP idea is simply not a good one. Opening a session and do all the process for this kind of thing is just useless and slow your script down. You should be asking yourself: Do I really need to block this?

If the answer is yes then do this: Create a table called processes in you database. Inside that table create 2 fields: One will be the process identifier: process_id; the second will be the process status: process_status. The first is an integer you will define with sha1(IMAGE). The second will be an integer: 1 for "busy", 0 for "free".

Then you could do something like this:

SELECT process_status FROM vps_processes WHERE process_id = sha1(CURRENT_IMAGE);

And check whatever it is 1 or 0. If it is 1 then block the script; If it is 0 then you query:

UPDATE vps_processes SET process_status = 1 WHERE process_id = sha1(CURRENT_IMAGE);

then run what you have to run and at the end of the script query:

UPDATE vps_processes SET process_status = 0 WHERE process_id = sha1(CURRENT_IMAGE);
like image 75
Shoe Avatar answered Nov 16 '22 23:11

Shoe