Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace GoodbyeDeadlocks
- use Predis\Client;
- use LogicException;
- class Lock
- {
- /**
- * time to keep lock
- * when your script was dead the look will be keeping for that time
- * this is needed when a process is died and will never unlock the wallet
- * metric using minutes, by default = 10 minutes
- * @var integer
- */
- public $ttl = 600;
- /**
- * when a lock can't be reached right now script should pause
- * that is needed so you will never hot your redis instance
- * @var integer
- */
- public $delay = 100;
- /**
- * we don't want to remove other session locks due invalid logic
- * so this var will keep current locks list
- * @var array
- */
- public $locked = [];
- public function __construct(Client $redis)
- {
- $this->redis = $redis;
- register_shutdown_function([$this, 'unlockEverything']);
- }
- public function acquire(int $wallet)
- {
- if (func_num_args() > 1) {
- $wallets = func_get_args();
- sort($wallets);
- foreach ($wallets as $wallet) {
- $this->acquire($wallet);
- }
- return;
- }
- if (in_array($wallet, $this->locked)) {
- // simple return true if taken lock is okay
- return true;
- // or throw on exception if you want to discover how it was achieved
- // throw new LogicException("Wallet $wallet was not locked in this session!");
- }
- while (!$this->redis->set("wallet-$wallet", 1, 'EX', $this->ttl, 'NX')) {
- usleep($this->delay * 1000);
- }
- $this->locked[] = $wallet;
- }
- public function remove($wallet)
- {
- if (!in_array($wallet, $this->locked)) {
- throw new LogicException("Wallet $wallet was not locked in this session!");
- }
- if (func_num_args() > 1) {
- $wallets = func_get_args();
- sort($wallets);
- foreach ($wallets as $wallet) {
- $this->remove($wallet);
- }
- return;
- }
- $this->redis->del("wallet-$wallet");
- }
- public function unlockEverything()
- {
- foreach ($this->locked as $key) {
- $this->remove($key);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement