Search code examples
laravellockinglaravel-cache

Why $time from $lock=Cache::lock('name', $time) should be greater than the updating Cache time?


I placed this code inside a Route::get() method only to test it quicker. So this is how it looks:

use Illuminate\Support\Facades\Cache;

Route::get('/cache', function(){

  $lock = Cache::lock('test', 4);

  if($lock->get()){
    Cache::put('name', 'SomeName'.now());
    dump(Cache::get('name'));
    sleep(5);
    // dump('inside get');
  }else{
    dump('locked');
  }
  // $lock->release();
});

If you reach this route from two browsers (almost)at the same time. They both will respond with the result from dump(Cache::get('name'));. Shouldn't the second browser respond be "locked"? Because when it calls the $lock->get() that is supposed to return false? And that because when the second browser tries to reach this route the lock should be still set.

That same code works just fine if the time required for the code after the $lock = Cache::lock('test', 4) to be executed is less than 4. If you set the sleep($sec) when $sec<4 you will see that the first browser reaching this route will respond with the result from Cache::get('name') and the second browser will respond with "locked" as expected.

Can anyone explain why is this happening? Isn't it suppose that any get() method to that lock, expect the first one, to return false for that amount of time the lock has been set? I used 2 different browsers but it works the same with 2 tabs from the same browser too.


Solution

  • I saw this question I asked, well now I can say that the problem I was trying to solve here was not because of the atomic lock. The problem here is the sleep method. If the time provided to the sleep method is bigger than the time that a lock will live, it means when the next request it's able to hit the route the lock time will expire(will be released). And that's because let's say you have defined a route like this:

    Route::get('case/{value}', function($value){
      if($value){
        dump('hit-1');
      }else{
        sleep(5);
        dump('hit-0');
      }
    });
    

    And you open two browser tabs with the same URL that hits this route something like:

    127.0.0.1:8000/case/0

    and

    127.0.0.1:8000/case/1

    It will show you that the first route will take 5sec to finish execution and even if the second request is sent almost at the same time with the first request, still it will wait to finish the first one and then run. This means the second request will last 5sec(from the first request) plus the time it took to run.

    Back to the asked question the lock time will expire by the time the second request will get it or said differently run the $lock->get() statement.