Link to home
Start Free TrialLog in
Avatar of cubic77
cubic77Flag for Finland

asked on

How do I make sure a file is processed before it is altered?

A remote server sends data to me (POST). I have a PHP script (receive.php) that receives the data and store it in a file. Then, a totally different script (process.php) reads that file, process its content and empty the file (this way it will prepare the file for the next write and it won't process the same data twice).

But the remote server may send data to my receive.php script while process.php script is still processing the file. How do I solve this problem?
Avatar of Lukasz Chmielewski
Lukasz Chmielewski
Flag of Poland image

Avatar of florjan
florjan

Php file operators. So check if file is not null. If it isnt write to other files. You could have a for sentence for less code. If you need anymore help I'll help you as soon as I come home.
Avatar of Beverley Portlock
A queue is your best bet.

Instead of allowing the scripts to access the file directly, get them to write into a table which holds the file's name and the next operation as well as any data. A separate script can then be run on a schedule to inspect the queue and process any work

-- UNTESTED --

CREATE TABLE processQueue (

  id INT NOT NULL auto_increment,
  filename VARCHAR(255) NOT NULL,
  command VARCHAR(32) NOT NULL,
  data TEXT NOT NULL,
  PRIMARY KEY(id)  

);


Then INSERT INTO processQueue ( filename, command, data ) VALUES (........ etc.....);

Have your scheduled script pull off the oldest record

SELECT * FROM processQueue ORDER BY filename, id LIMIT 1

apply the changes and then remove the work record

DELETE FROM processQueue where id = $id

This ensures that all operations on a file are performed sequentially. Have the job run every few minutes and if the queue is empty then just terminate the job. If you know that the changes will take fraction of a second then you might decide to process up to 10 commands or whatever works for you before you run out of processor time.

Using a database will be helpful. But if you don't want to use a database, you can try the following.

Since you might still want to allow your application to receive updates even though there is still a file being processed, just allow the page to continue receiving requests. (that means, not locking the file)

My idea is to create a temporary directory that contains files you want processed. For example, you can create a queue/ directory. Each time a file is received, you put a file in that directory with a random file name. You can use file_put_contents() or move_uploaded_file() or simply rename(), you weren't able to mention how you receive files in receive.php.


Now, the other file which processes these files, loops to check for files in that directory:
<?php
$dir = "queue/";
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false && filetype($dir . $file) == 'file') {
            // this is a file in the queue directory. Now, do something with $dir.$file
            // and make sure you delete the file after to indicate you're done processing it:
            // unlink($dir.$file);
        }
        closedir($dh);
    }
}
?>

... and delete the file after processing it. This way, you can accept multiple files for processing and have it processed sequentially and you don't need to use a database. The readdir() function would return the files in the order in which they are created in the file system.
This sounds like a strange application design.  Regarding this, "a totally different script (process.php) reads that file" -- how does that script get started?  And why would you want to re-use the file name?  Why not have the receive.php script collect the data, write the file, and then start the process.php script?  You would want to use a different file name (maybe using a timestamp) for each received data set.  Once process.php has completed its work, it could unlink() the file.
Avatar of cubic77

ASKER

@Ray_Paseur

> Why not have the receive.php script collect the data, write the file, and then start the process.php script?
Actually this is what I am doing right now.
If you're doing it that way and you use a different file name for each new file, you should be on firm ground, at least with this end of the application.
Avatar of cubic77

ASKER

>If you're doing it that way and you use a different file name for each new file, you should be on firm ground
Indeed it may be the best approach. Also, this way I can remove the need of using a data base to store my data. I can read the data directly from those files.
That may be true.  Not sure what kind of data you have, but larger "blobs" of information like images or video are better in the file system, whereas smaller, succinct, searchable pieces seem to be most useful in a data base.  It's part art and part science ;)
ASKER CERTIFIED SOLUTION
Avatar of cubic77
cubic77
Flag of Finland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cubic77

ASKER

no other solid solution provided