Guest User

Untitled

a guest
Dec 31st, 2015
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.41 KB | None | 0 0
  1. <?
  2. /**
  3.  *        @author         Varun Shoor <varun.shoor@kayako.com>
  4.  */
  5.  
  6.  
  7. namespace SWIFT\Library;
  8.  
  9.  
  10. use SWIFT\Library\Exception;
  11.  
  12. /**
  13.  * The lock class is used to prevent race conditions in tasks (recurring etc.).
  14.  *
  15.  * @author           Varun Shoor <varun.shoor@kayako.com>
  16.  */
  17. class Lock
  18. {
  19.     const DEFAULT_EXPIRY = 30; // in minutes
  20.  
  21.     // string
  22.     protected $name;
  23.  
  24.     /**
  25.      * @author Varun Shoor
  26.      *
  27.      * @param string $name
  28.      */
  29.     public function __construct($name)
  30.     {
  31.         $this->setName($name);
  32.     }
  33.  
  34.     /**
  35.      * @return Lock
  36.      * @throws Exception\InvalidArgument
  37.      */
  38.     protected function setName($name)
  39.     {
  40.         if (empty($name)) {
  41.             throw new Exception\InvalidArgument;
  42.         }
  43.  
  44.         $this->name = $name;
  45.     }
  46.  
  47.     /**
  48.      * @author Varun Shoor <varun.shoor@kayako.com>
  49.      *
  50.      * @return string
  51.      * @todo name should be returned instead of 'this'
  52.      */
  53.     public function getName()
  54.     {
  55.         return $this;
  56.     }
  57.  
  58.     /**
  59.      * Attempts to create a new lock, if one already exists, returns false
  60.      *
  61.      * @author Varun Shoor <varun.shoor@kayako.com>
  62.      * @todo realease the lock, implement file time modification based on expiry
  63.      *
  64.      * @param string $name
  65.      * @param int $expiry (OPTIONAL) In minutes
  66.      *
  67.      * @return Lock
  68.      * @throws Exception\InvalidArgument
  69.      */
  70.     static public function create($name, $expiry = 0)
  71.     {
  72.         $name = clean($name);
  73.  
  74.         if (empty($name)) {
  75.             throw new Exception\InvalidArgument;
  76.         } // If the lock already exists, we need to check whether it has expired
  77.         elseif (self::exists($name)) {
  78.             $Lock = new self($name);
  79.  
  80.             // If the lock has expired, we need to release it before proceeding
  81.             if (!$Lock->HasExpired()) {
  82.                 /*
  83.                  * @todo Release the lock here
  84.                  */
  85.             } // Apparently the lock is still active, we cant proceed!
  86.             else {
  87.                 return null;
  88.             }
  89.         }
  90.  
  91.         if (empty($expiry)) {
  92.             $expiry = time() + (60 * self::DEFAULT_EXPIRY);
  93.         }
  94.  
  95.         file_put_contents(self::getCacheName($name), self::getContents($expiry));
  96.  
  97.         /*
  98.          * @todo Implement file time modification based on expiry
  99.          */
  100.  
  101.         return new self($name);
  102.     }
  103.  
  104.     /**
  105.      * @author Varun Shoor <varun.shoor@kayako.com>
  106.      *
  107.      * @param string $name
  108.      *
  109.      * @return boolean
  110.      */
  111.     static public function exists($name)
  112.     {
  113.         $name = clean($name);
  114.  
  115.         if (empty($name)) {
  116.             throw new Exception\InvalidArgument;
  117.         }
  118.  
  119.         $cache = new self($name);
  120.  
  121.         if (!$cache->getJSON()) {
  122.             return false;
  123.         }
  124.  
  125.         $cache->increment();
  126.  
  127.         return true;
  128.     }
  129.  
  130.     /**
  131.      * @author Varun Shoor <varun.shoor@kayako.com>
  132.      *
  133.      * @param \stdClass $json
  134.      *
  135.      * @return Lock
  136.      */
  137.     public function update(\stdClass $json)
  138.     {
  139.         file_put_contents(self::getCacheName($this->getName()), json_encode($json));
  140.  
  141.         return $this;
  142.     }
  143.  
  144.     /**
  145.      * @author Varun Shoor <varun.shoor@kayako.com>
  146.      *
  147.      * @return Lock
  148.      */
  149.     function increment()
  150.     {
  151.         $json = $this->getJSON();
  152.         if (!$json) {
  153.             return $this;
  154.         }
  155.  
  156.         // Extend the expiry
  157.         $json->expiry = $json->expiry + (60 * self::DEFAULT_EXPIRY);
  158.  
  159.         $json->hits++;
  160.  
  161.         return $this->update($json);
  162.     }
  163.  
  164.     /**
  165.      * @author Varun Shoor <varun.shoor@kayako.com>
  166.      *
  167.      * @return object
  168.      */
  169.     public function ReleaseTheLock()
  170.     {
  171.         if (!self::exists($this->getName())) {
  172.             return $this;
  173.         }
  174.  
  175.         unlink(self::getCacheName($this->getName()));
  176.  
  177.         return $this;
  178.     }
  179.  
  180.     /**
  181.      * @author Varun Shoor <varun.shoor@kayako.com>
  182.      *
  183.      * @return int|false
  184.      */
  185.     public function getExpiry()
  186.     {
  187.         return $this->getValue('expiry');
  188.     }
  189.  
  190.     /**
  191.      * @author Varun Shoor <varun.shoor@kayako.com>
  192.      *
  193.      * @return int|false
  194.      */
  195.     public function getHits()
  196.     {
  197.         return $this->getValue('hits');
  198.     }
  199.  
  200.     /**
  201.      * @author Varun Shoor <varun.shoor@kayako.com>
  202.      *
  203.      * @return object
  204.      */
  205.     public function getJSON()
  206.     {
  207.         $json = file_get_contents(self::getCacheName($this->getName()));
  208.  
  209.         // JSON decoding failed? We will need to clean things up
  210.         if ($json == false) {
  211.             return null;
  212.         }
  213.  
  214.         return (object) $json;
  215.     }
  216.  
  217.     /**
  218.      * @author Varun Shoor <varun.shoor@kayako.com>
  219.      *
  220.      * @param string $name
  221.      *
  222.      * @return string|false
  223.      * @throws Exception\InvalidArgument
  224.      */
  225.     function getValue($name)
  226.     {
  227.         if (empty($name)) {
  228.             throw new Exception\InvalidArgument;
  229.         }
  230.  
  231.         $json = $this->getJSON();
  232.         if (!$json || !isset($json->{$name})) {
  233.             return false;
  234.         }
  235.         return $json->{$name};
  236.     }
  237.  
  238.     /**
  239.      * @author Varun Shoor <varun.shoor@kayako.com>
  240.      *
  241.      * @return boolean
  242.      */
  243.     function HasExpired()
  244.     {
  245.         $expiry = $this->getExpiry();
  246.         if ($expiry === false || $expiry < NOW) {
  247.             $this->ReleaseTheLock();
  248.             return true;
  249.         }
  250.         return false;
  251.     }
  252.  
  253.     /**
  254.      * @author Varun Shoor <varun.shoor@kayako.com>
  255.      *
  256.      * @return json
  257.      */
  258.     public function __toString()
  259.     {
  260.         return json_encode ($this->getJSON(), JSON_PRETTY_PRINT);
  261.     }
  262.  
  263.     /**
  264.      * @author Varun Shoor <varun.shoor@kayako.com>
  265.      *
  266.      * @param string $name
  267.      *
  268.      * @return string
  269.      */
  270.     static protected function getCacheName($name)
  271.     {
  272.         return 'lock.' . $name;
  273.     }
  274.  
  275.     /**
  276.      * @author Varun Shoor <varun.shoor@kayako.com>
  277.      *
  278.      * @param  integer $expiry
  279.      * @param  integer $hits
  280.      *
  281.      * @return object
  282.      */
  283.     static protected function getContents($expiry, $hits = 1)
  284.     {
  285.         return (object) array(
  286.             'expiry' => $expiry,
  287.             'hits'   => $hits
  288.         );
  289.     }
  290. }
  291.   
  292. ?>
Add Comment
Please, Sign In to add comment