Advertisement
Guest User

Untitled

a guest
May 19th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.23 KB | None | 0 0
  1. <?php
  2.  
  3. namespace GoodbyeDeadlocks
  4.  
  5. use Predis\Client;
  6. use LogicException;
  7.  
  8. class Lock
  9. {
  10. /**
  11. * time to keep lock
  12. * when your script was dead the look will be keeping for that time
  13. * this is needed when a process is died and will never unlock the wallet
  14. * metric using minutes, by default = 10 minutes
  15. * @var integer
  16. */
  17. public $ttl = 600;
  18.  
  19. /**
  20. * when a lock can't be reached right now script should pause
  21. * that is needed so you will never hot your redis instance
  22. * @var integer
  23. */
  24. public $delay = 100;
  25.  
  26. /**
  27. * we don't want to remove other session locks due invalid logic
  28. * so this var will keep current locks list
  29. * @var array
  30. */
  31. public $locked = [];
  32.  
  33. public function __construct(Client $redis)
  34. {
  35. $this->redis = $redis;
  36. register_shutdown_function([$this, 'unlockEverything']);
  37. }
  38.  
  39. public function acquire(int $wallet)
  40. {
  41. if (func_num_args() > 1) {
  42. $wallets = func_get_args();
  43. sort($wallets);
  44. foreach ($wallets as $wallet) {
  45. $this->acquire($wallet);
  46. }
  47. return;
  48. }
  49.  
  50. if (in_array($wallet, $this->locked)) {
  51. // simple return true if taken lock is okay
  52. return true;
  53. // or throw on exception if you want to discover how it was achieved
  54. // throw new LogicException("Wallet $wallet was not locked in this session!");
  55. }
  56.  
  57. while (!$this->redis->set("wallet-$wallet", 1, 'EX', $this->ttl, 'NX')) {
  58. usleep($this->delay * 1000);
  59. }
  60.  
  61. $this->locked[] = $wallet;
  62. }
  63.  
  64. public function remove($wallet)
  65. {
  66. if (!in_array($wallet, $this->locked)) {
  67. throw new LogicException("Wallet $wallet was not locked in this session!");
  68. }
  69.  
  70. if (func_num_args() > 1) {
  71. $wallets = func_get_args();
  72. sort($wallets);
  73. foreach ($wallets as $wallet) {
  74. $this->remove($wallet);
  75. }
  76. return;
  77. }
  78.  
  79. $this->redis->del("wallet-$wallet");
  80. }
  81.  
  82. public function unlockEverything()
  83. {
  84. foreach ($this->locked as $key) {
  85. $this->remove($key);
  86. }
  87. }
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement