Note that there are some explanatory texts on larger screens.

plurals
  1. PORace Condition in PHP File Writing
    primarykey
    data
    text
    <p>So I have a script for accepting and processing request from another scripts and/or applications. However, one of the task has to be done with my script is assigning each request a unique, sequential "ID" to each of them.</p> <p>For example, let's says that application A is giving a 1000 request to my script, and in the same time, application B is giving 500 request to my script. I have to give them 1500 unique, sequential number, like 2001~3500 to each of them.</p> <p>The order between them however, does not matter, so I can give them numbers like this :</p> <pre><code>#2001 for 1st request from A (henceforth, A1) #2002 for A2 #2003 for B1 #2004 for A3 #2005 for B2 ...and so on... </code></pre> <p>I've tried creating a file that stores that number and a separated lock file with a function like this :</p> <pre><code>private function get_last_id() { // Check if lock file exists... while (file_exists("LAST_ID_LOCKED")) { // Wait a little bit before checking again usleep(1000); } // Create the lock file touch("LAST_ID_LOCKED"); // Create the ID file for the first time if required if (!file_exists("LAST_ID_INDICATOR")) { file_put_contents("LAST_ID_INDICATOR", 0); } // Get the last ID $last_id = file_get_contents("LAST_ID_INDICATOR"); // Update the last ID file_put_contents("LAST_ID_INDICATOR", $last_id + 1); // Delete the lock file unlink("LAST_ID_LOCKED"); return $last_id; } </code></pre> <p>This code, however, would create a race condition, where if I send them those 1500 request, the last ID will have quite a number missings, (e.g. only reach 3211 instead of 3500).</p> <p>I've also tried using flock like this, but to no avail :</p> <pre><code>private function get_last_id() { $f = fopen("LAST_ID_INDICATOR", "rw"); while (true) { if (flock($f, LOCK_SH)) { $last_id = fread($f, 8192); flock($f, LOCK_UN); fclose($f); break; } usleep($this-&gt;config["waiting_time"]); } $f = fopen("LAST_ID_INDICATOR", "rw"); while (true) { if (flock($f, LOCK_SH)) { $last_id = fread($f, 8192); $last_id++; ftruncate($f, 0); fwrite($f, $last_id); flock($f, LOCK_UN); fclose($f); break; } usleep($this-&gt;config["waiting_time"]); } return $last_id; } </code></pre> <p>So, what else can I do to look for a solution for this situation?</p> <p><strong>Notes:</strong> Due to server limitation, I'm limited to PHP 5.2 without something like semaphores and such.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload