From 4c68bf5a8a6be5ade3f6eea39f3810944050f2a5 Mon Sep 17 00:00:00 2001 From: zacksleo Date: Thu, 8 Nov 2018 23:18:09 +0800 Subject: [PATCH 1/4] enhance: mutex of onOneServer expires after 1 hour --- src/CallbackEvent.php | 5 +++-- src/Event.php | 14 ++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/CallbackEvent.php b/src/CallbackEvent.php index a11b3f7..735a8d9 100644 --- a/src/CallbackEvent.php +++ b/src/CallbackEvent.php @@ -69,10 +69,11 @@ public function run(Application $app) /** * Do not allow the event to overlap each other. * + * @param int $expiresAt * @return $this * @throws InvalidParamException */ - public function withoutOverlapping() + public function withoutOverlapping($expiresAt = 86400) { if (empty($this->_description)) { throw new InvalidParamException( @@ -80,7 +81,7 @@ public function withoutOverlapping() ); } - return parent::withoutOverlapping(); + return parent::withoutOverlapping($expiresAt); } /** diff --git a/src/Event.php b/src/Event.php index 3dfec6a..f8d0d69 100644 --- a/src/Event.php +++ b/src/Event.php @@ -508,12 +508,13 @@ public function user($user) /** * Do not allow the event to overlap each other. * + * @param int $expiresAt * @return $this */ - public function withoutOverlapping() + public function withoutOverlapping($expiresAt = 86400) { return $this->then(function() { - $this->_mutex->release($this->mutexName()); + $this->_mutex->release($this->mutexName(), $expiresAt); })->skip(function() { return !$this->_mutex->acquire($this->mutexName()); }); @@ -529,8 +530,13 @@ public function onOneServer() if ($this->_mutex instanceof FileMutex) { throw new InvalidConfigException('You must config mutex in the application component, except the FileMutex.'); } - - return $this->withoutOverlapping(); + $time = new \DateTime('now'); + $name = $this->mutexName() . $time->format('Hi'); + return $this->then(function() use ($name) { + $this->_mutex->release($name, 3600); + })->skip(function() use ($name) { + return !$this->_mutex->acquire($name); + }); } /** From 25098f5085e49197493dfc8925007d768b682540 Mon Sep 17 00:00:00 2001 From: zacksleo Date: Thu, 8 Nov 2018 23:23:08 +0800 Subject: [PATCH 2/4] fix(event): invalid expiredAt usage --- src/Event.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Event.php b/src/Event.php index f8d0d69..2a22b3f 100644 --- a/src/Event.php +++ b/src/Event.php @@ -514,9 +514,9 @@ public function user($user) public function withoutOverlapping($expiresAt = 86400) { return $this->then(function() { - $this->_mutex->release($this->mutexName(), $expiresAt); - })->skip(function() { - return !$this->_mutex->acquire($this->mutexName()); + $this->_mutex->release($this->mutexName()); + })->skip(function() use ($expiresAt) { + return !$this->_mutex->acquire($this->mutexName(), $expiresAt); }); } @@ -533,9 +533,9 @@ public function onOneServer() $time = new \DateTime('now'); $name = $this->mutexName() . $time->format('Hi'); return $this->then(function() use ($name) { - $this->_mutex->release($name, 3600); + $this->_mutex->release($name); })->skip(function() use ($name) { - return !$this->_mutex->acquire($name); + return !$this->_mutex->acquire($name, 3600); }); } From 3211e8519c04d309a4722827a2a2e9bb6ca686ef Mon Sep 17 00:00:00 2001 From: zacksleo Date: Fri, 9 Nov 2018 00:56:08 +0800 Subject: [PATCH 3/4] fix(event): onOneServer mutex must not release immediately --- src/Event.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Event.php b/src/Event.php index 2a22b3f..7b10c36 100644 --- a/src/Event.php +++ b/src/Event.php @@ -511,12 +511,12 @@ public function user($user) * @param int $expiresAt * @return $this */ - public function withoutOverlapping($expiresAt = 86400) + public function withoutOverlapping($expiresAt = 1440) { return $this->then(function() { $this->_mutex->release($this->mutexName()); })->skip(function() use ($expiresAt) { - return !$this->_mutex->acquire($this->mutexName(), $expiresAt); + return !$this->_mutex->acquire($this->mutexName(), $expiresAt * 60); }); } @@ -532,9 +532,7 @@ public function onOneServer() } $time = new \DateTime('now'); $name = $this->mutexName() . $time->format('Hi'); - return $this->then(function() use ($name) { - $this->_mutex->release($name); - })->skip(function() use ($name) { + return $this->skip(function() use ($name) { return !$this->_mutex->acquire($name, 3600); }); } From c8d2a72c1d2b2677538bf1588f9dece01fc4f263 Mon Sep 17 00:00:00 2001 From: zacksleo Date: Fri, 9 Nov 2018 10:54:23 +0800 Subject: [PATCH 4/4] fix(onOneServer): do not release the mutex immediately If the schedule run very quickly, then the mutex will be auto relese. Schedules on other servers may can also run. --- README.md | 1 + src/CallbackEvent.php | 2 +- src/Event.php | 16 ++++++++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dd0f5d8..353769f 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,7 @@ Below shows the redis mutex demo: 'components' => [ 'mutex' => [ 'class' => 'yii\redis\Mutex', + 'autoRelease' => false, // You should disable autoRelease here 'redis' => [ 'hostname' => 'localhost', 'port' => 6379, diff --git a/src/CallbackEvent.php b/src/CallbackEvent.php index 735a8d9..b960153 100644 --- a/src/CallbackEvent.php +++ b/src/CallbackEvent.php @@ -73,7 +73,7 @@ public function run(Application $app) * @return $this * @throws InvalidParamException */ - public function withoutOverlapping($expiresAt = 86400) + public function withoutOverlapping($expiresAt = 1440) { if (empty($this->_description)) { throw new InvalidParamException( diff --git a/src/Event.php b/src/Event.php index 7b10c36..aa372cb 100644 --- a/src/Event.php +++ b/src/Event.php @@ -11,7 +11,7 @@ use yii\base\InvalidConfigException; use yii\mail\MailerInterface; use yii\mutex\Mutex; -use yii\mutex\FileMutex; +use yii\redis\Mutex as RedisMutex; /** * Class Event @@ -513,10 +513,13 @@ public function user($user) */ public function withoutOverlapping($expiresAt = 1440) { + if ($this->_mutex instanceof RedisMutex) { + $this->_mutex->expire = $expiresAt * 60; + } return $this->then(function() { $this->_mutex->release($this->mutexName()); - })->skip(function() use ($expiresAt) { - return !$this->_mutex->acquire($this->mutexName(), $expiresAt * 60); + })->skip(function() { + return !$this->_mutex->acquire($this->mutexName()); }); } @@ -527,13 +530,14 @@ public function withoutOverlapping($expiresAt = 1440) */ public function onOneServer() { - if ($this->_mutex instanceof FileMutex) { - throw new InvalidConfigException('You must config mutex in the application component, except the FileMutex.'); + if (!$this->_mutex instanceof RedisMutex) { + throw new InvalidConfigException('You must config redis mutex in the application component.'); } $time = new \DateTime('now'); $name = $this->mutexName() . $time->format('Hi'); + $this->_mutex->expire = 3600; return $this->skip(function() use ($name) { - return !$this->_mutex->acquire($name, 3600); + return !$this->_mutex->acquire($name); }); }