[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/google/Google/Cache/ -> File.php (source)

   1  <?php
   2  /*
   3   * Copyright 2008 Google Inc.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   */
  17  
  18  require_once "Google/Cache/Abstract.php";
  19  require_once "Google/Cache/Exception.php";
  20  
  21  /*
  22   * This class implements a basic on disk storage. While that does
  23   * work quite well it's not the most elegant and scalable solution.
  24   * It will also get you into a heap of trouble when you try to run
  25   * this in a clustered environment.
  26   *
  27   * @author Chris Chabot <[email protected]>
  28   */
  29  class Google_Cache_File extends Google_Cache_Abstract
  30  {
  31    const MAX_LOCK_RETRIES = 10;
  32    private $path;
  33    private $fh;
  34  
  35    public function __construct(Google_Client $client)
  36    {
  37      $this->path = $client->getClassConfig($this, 'directory');
  38    }
  39    
  40    public function get($key, $expiration = false)
  41    {
  42      $storageFile = $this->getCacheFile($key);
  43      $data = false;
  44      
  45      if (!file_exists($storageFile)) {
  46        return false;
  47      }
  48  
  49      if ($expiration) {
  50        $mtime = filemtime($storageFile);
  51        if ((time() - $mtime) >= $expiration) {
  52          $this->delete($key);
  53          return false;
  54        }
  55      }
  56  
  57      if ($this->acquireReadLock($storageFile)) {
  58        $data = fread($this->fh, filesize($storageFile));
  59        $data =  unserialize($data);
  60        $this->unlock($storageFile);
  61      }
  62  
  63      return $data;
  64    }
  65  
  66    public function set($key, $value)
  67    {
  68      $storageFile = $this->getWriteableCacheFile($key);
  69      if ($this->acquireWriteLock($storageFile)) {
  70        // We serialize the whole request object, since we don't only want the
  71        // responseContent but also the postBody used, headers, size, etc.
  72        $data = serialize($value);
  73        $result = fwrite($this->fh, $data);
  74        $this->unlock($storageFile);
  75      }
  76    }
  77  
  78    public function delete($key)
  79    {
  80      $file = $this->getCacheFile($key);
  81      if (file_exists($file) && !unlink($file)) {
  82        throw new Google_Cache_Exception("Cache file could not be deleted");
  83      }
  84    }
  85    
  86    private function getWriteableCacheFile($file)
  87    {
  88      return $this->getCacheFile($file, true);
  89    }
  90  
  91    private function getCacheFile($file, $forWrite = false)
  92    {
  93      return $this->getCacheDir($file, $forWrite) . '/' . md5($file);
  94    }
  95    
  96    private function getCacheDir($file, $forWrite)
  97    {
  98      // use the first 2 characters of the hash as a directory prefix
  99      // this should prevent slowdowns due to huge directory listings
 100      // and thus give some basic amount of scalability
 101      $storageDir = $this->path . '/' . substr(md5($file), 0, 2);
 102      if ($forWrite && ! is_dir($storageDir)) {
 103        if (! mkdir($storageDir, 0755, true)) {
 104          throw new Google_Cache_Exception("Could not create storage directory: $storageDir");
 105        }
 106      }
 107      return $storageDir;
 108    }
 109    
 110    private function acquireReadLock($storageFile)
 111    {
 112      return $this->acquireLock(LOCK_SH, $storageFile);
 113    }
 114    
 115    private function acquireWriteLock($storageFile)
 116    {
 117      $rc = $this->acquireLock(LOCK_EX, $storageFile);
 118      if (!$rc) {
 119        $this->delete($storageFile);
 120      }
 121      return $rc;
 122    }
 123    
 124    private function acquireLock($type, $storageFile)
 125    {
 126      $mode = $type == LOCK_EX ? "w" : "r";
 127      $this->fh = fopen($storageFile, $mode);
 128      $count = 0;
 129      while (!flock($this->fh, $type | LOCK_NB)) {
 130        // Sleep for 10ms.
 131        usleep(10000);
 132        if (++$count < self::MAX_LOCK_RETRIES) {
 133          return false;
 134        }
 135      }
 136      return true;
 137    }
 138    
 139    public function unlock($storageFile)
 140    {
 141      if ($this->fh) {
 142        flock($this->fh, LOCK_UN);
 143      }
 144    }
 145  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1