yii2: Mutex::isAcquired() is not working if is called in different process

What steps will reproduce the problem?

Define 2 actions in console Controller: ` public function actionA(){ $mutexName = ‘test_mutex’; $mutex = \Yii::createObject([ ‘class’ => \yii\mutex\FileMutex::class, ‘mutexPath’ => ‘@runtime/mutex’, ]);

    echo "acquire mutex\n";
    $mutex->acquire($mutexName);

    sleep(9999);

    echo "release mutex\n";
    $mutex->release($mutexName);
}

public function actionB(){
    $mutexName = 'test_mutex';
    $mutex = \Yii::createObject([
        'class' => \yii\mutex\FileMutex::class,
        'mutexPath' => '@runtime/mutex',
    ]);

    if($mutex->isAcquired($mutexName)){
        echo "mutex is acquired\n";
    }
    else {
        echo "mutex is not acquired\n";
    }
}

`

Open a console window and execute (let it in running): $ yii test/a acquire mutex

Open a second console window and execute: $ yii test/b mutex is not acquired

What is the expected result?

On second window is expected the output: mutex is acquired

What do you get instead?

On second window: mutex is not acquired Tested with DbMutex with same result

Additional info

Q A
Yii version 2.0.41
PHP version 7.3.9
Operating system Windows 10

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 27 (25 by maintainers)

Commits related to this issue

Most upvoted comments

I think the right solution here is to emphasize current method behavior.

@ivan-redooc That’s not the point. It seems there’s still a lot confusion here. Let me try again to explain the two use cases as I see it:

  1. Case in #18151: isAcquired() answers the question “Do we have the lock?” I.e. does the current instance of ActiveRecord in the current PHP process have obtained the lock? That’s what the implementation right now does. A parallel process gets false - even though the lock is not available!
  2. After the fix requested in this issue: isAcquired() answers the question “Does any PHP process have the lock?”. That’s what mutex is made for.

That’s something completely different. If we fix the issue here, the behavior will change from 1) to 2).

The code I showed above is a workaround for those that rely on behavior 1). It’s not a choice. The current implementation is simply flawed and does not get the point of a mutex.