Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

file_get_contents appears to be caching, lock script issue

Tags:

php

locking

Let's say we need some lock-script that we make sure two scripts are never running at same time:

if(file_get_contents('test.txt')) { // this is always empty...
   die("Another script is running in background!");
}
file_put_contents('test.txt', 'busy!');
sleep(10); // heavy work here
file_put_contents('test.txt', '');

it still allows me to run two scripts at same time. It looks like result of file_get_contents() are cached?

How to fix it? I want to use files, not DB.


Edit: I already managed to do the lock-script using flock() (thanks to Levi Morrison)

Anyway I am still curious why file_get_contents works in so unexpected behaviour?

like image 218
Peter Avatar asked Nov 03 '22 08:11

Peter


1 Answers

I was able to reproduce it and figure the problem. At first it looked the way you described: I requested the script in browser and while it was running I checked file contents - it was busy!. Then I run second script and in browser it was also loading, same as first one. I thought it's also running, but it was not.

It's pretty easy to figure, if instead of busy! you add something random, like:

file_put_contents('test.txt', 'busy washing ' . (mt_rand(1, 999) * 99999) . ' dishes');

Run the same two scripts the same way and monitor file contents. At first, it will be what first script wrote. Say busy washing 1 dishes. Then you will see the content change to what second script writes, the number will be different.

Basically, what happens is second script waits while first one finishes and only then starts. Funny enough, by finishing, first script clears the file, which lets second script run normally, but it looks in browser like they are both working at the same time. In fact, second script runs twice as much time, as the first one.

I've encountered that behaviour when doing heavy asynchronous requests via AJAX and requesting same website page in another browser tab. Until the script finishes I couldn't load the tab.

So long story short, there's no issue! If you queue that scripts via cron they will be run separately and second one will finish by finding that the file is not empty.

like image 193
Ranty Avatar answered Nov 15 '22 13:11

Ranty