1

Sometimes my application needs to wait for something. For example, in case of caching: if an object is not found in the cache, then the script sets a special value under its key, symbolizing the fact that its value is currently being calculated, and upon completion it writes it. If at the moment of calculation another client requests the same object, then the script will not recalculate it, but will simply wait for the first one. This is a simplified explanation, of course. I don't know how to do that correctly, but this behavior seems to me to be very logical.

In the process of testing a completely different thing, today I ran into a problem.

<?php
echo time() . "\n";
sleep(10); // usleep() has the same effect
echo time() . "\n";

At the same second, I open this page in a browser in two tabs and expect to see the same numbers, but… The tab that was opened later, in addition to its delay, for some reason, is waiting for the first tab delay (lame wording, but you understand me), so I see something like this: 1615749037 1615749047, 1615749047 1615749057. If you add more tabs, then each next one will wait for all the previous ones.

It broke my brain. This is not how I imagined it at all and was in this delusion for many years. I have not been able to find any information on this right now. First of all, I'm interested in how to achieve the desired result. Why sleep() behaves this way, I seem to be starting to guess, but I'll be glad if you share some information. Thank you!

UPD. Just in case, I checked this: if I add header('Cache-Control: no-cache, no-store, must-revalidate'), then nothing changes for me. But if I open tabs from different browsers, then there's no problem.

  • 1
    You could add a random query parameter to the URL and the phenomenon should disappear because the browser thinks two different pages are requested. – KIKO Software Mar 14 '21 at 20:20
  • 1
    @KIKOSoftware, it worked. But with the same address it doesn't work even with disabled caching (see updated post). That is, in a specific browser of a specific client, a blocking of a request to an already loading page is built-in? Then until when is the request blocked? Until the first byte is received? If so, then everything seems to be fine. But I have an extremely ambiguous impression. –  Mar 14 '21 at 20:34
  • 1
    I think that the logic behind this is: Why try to retrieve the page a second or third time if the first time hasn't succeeded yet. For all the browser knows the page might not even exist or download properly. – KIKO Software Mar 14 '21 at 20:52
  • 1
    @KIKOSoftware, there really is some logic in this, and it looks like this is how it works — the browser seems to be creating a queue of requests. I initially thought it was some kind of processes forks on the server side. I can't get to come up with any negative effects right now, if it works that way… Besides the emergence of such questions, of course. –  Mar 14 '21 at 21:20
  • @Bileslaw Interesting issue. Did you try Guest mode in Chrome? And did you try this with some odd browsers link `elinks` in terminal and `Dillo` or `rekonq` in GUI (both Linux browsers, you might find many Windows browsers that have genuine non-caching modes) – site80443 Jan 18 '23 at 11:25

1 Answers1

1

From reading I see two questions

1. How do I block a second request, while processing the first one?

For that my answer would be locks. For PHP specifically I'd recommend the Symfony lock component. You'll make both requests acquire a lock and only release it after you're done and the cache is generated.

2. Why do 2 requests fired at the same time wait for each other?

My guess here is that your browser has some built-in queuing/caching or whatnot. You can circumvent this by opening the same page in different browsers to see if that yields different results.

PtrTon
  • 3,705
  • 2
  • 14
  • 24