Google_Cache_File

This class implements a basic on disk storage.

Defined (1)

The class is defined in the following location(s).

/vendor/google/apiclient/src/Google/Cache/File.php  
  1. class Google_Cache_File extends Google_Cache_Abstract 
  2. const MAX_LOCK_RETRIES = 10; 
  3. private $path; 
  4. private $fh; 
  5.  
  6. /** 
  7. * @var Google_Client the current client 
  8. */ 
  9. private $client; 
  10.  
  11. public function __construct(Google_Client $client) 
  12. $this->client = $client; 
  13. $this->path = $this->client->getClassConfig($this, 'directory'); 
  14.  
  15. public function get($key, $expiration = false) 
  16. $storageFile = $this->getCacheFile($key); 
  17. $data = false; 
  18.  
  19. if (!file_exists($storageFile)) { 
  20. $this->client->getLogger()->debug( 
  21. 'File cache miss',  
  22. array('key' => $key, 'file' => $storageFile) 
  23. ); 
  24. return false; 
  25.  
  26. if ($expiration) { 
  27. $mtime = filemtime($storageFile); 
  28. if ((time() - $mtime) >= $expiration) { 
  29. $this->client->getLogger()->debug( 
  30. 'File cache miss (expired)',  
  31. array('key' => $key, 'file' => $storageFile) 
  32. ); 
  33. $this->delete($key); 
  34. return false; 
  35.  
  36. if ($this->acquireReadLock($storageFile)) { 
  37. if (filesize($storageFile) > 0) { 
  38. $data = fread($this->fh, filesize($storageFile)); 
  39. $data = unserialize($data); 
  40. } else { 
  41. $this->client->getLogger()->debug( 
  42. 'Cache file was empty',  
  43. array('file' => $storageFile) 
  44. ); 
  45. $this->unlock($storageFile); 
  46.  
  47. $this->client->getLogger()->debug( 
  48. 'File cache hit',  
  49. array('key' => $key, 'file' => $storageFile, 'var' => $data) 
  50. ); 
  51.  
  52. return $data; 
  53.  
  54. public function set($key, $value) 
  55. $storageFile = $this->getWriteableCacheFile($key); 
  56. if ($this->acquireWriteLock($storageFile)) { 
  57. // We serialize the whole request object, since we don't only want the 
  58. // responseContent but also the postBody used, headers, size, etc. 
  59. $data = serialize($value); 
  60. $result = fwrite($this->fh, $data); 
  61. $this->unlock($storageFile); 
  62.  
  63. $this->client->getLogger()->debug( 
  64. 'File cache set',  
  65. array('key' => $key, 'file' => $storageFile, 'var' => $value) 
  66. ); 
  67. } else { 
  68. $this->client->getLogger()->notice( 
  69. 'File cache set failed',  
  70. array('key' => $key, 'file' => $storageFile) 
  71. ); 
  72.  
  73. public function delete($key) 
  74. $file = $this->getCacheFile($key); 
  75. if (file_exists($file) && !unlink($file)) { 
  76. $this->client->getLogger()->error( 
  77. 'File cache delete failed',  
  78. array('key' => $key, 'file' => $file) 
  79. ); 
  80. throw new Google_Cache_Exception("Cache file could not be deleted"); 
  81.  
  82. $this->client->getLogger()->debug( 
  83. 'File cache delete',  
  84. array('key' => $key, 'file' => $file) 
  85. ); 
  86.  
  87. private function getWriteableCacheFile($file) 
  88. return $this->getCacheFile($file, true); 
  89.  
  90. private function getCacheFile($file, $forWrite = false) 
  91. return $this->getCacheDir($file, $forWrite) . '/' . md5($file); 
  92.  
  93. private function getCacheDir($file, $forWrite) 
  94. // use the first 2 characters of the hash as a directory prefix 
  95. // this should prevent slowdowns due to huge directory listings 
  96. // and thus give some basic amount of scalability 
  97. $storageDir = $this->path . '/' . substr(md5($file), 0, 2); 
  98. if ($forWrite && ! is_dir($storageDir)) { 
  99. if (! mkdir($storageDir, 0700, true)) { 
  100. $this->client->getLogger()->error( 
  101. 'File cache creation failed',  
  102. array('dir' => $storageDir) 
  103. ); 
  104. throw new Google_Cache_Exception("Could not create storage directory: $storageDir"); 
  105. return $storageDir; 
  106.  
  107. private function acquireReadLock($storageFile) 
  108. return $this->acquireLock(LOCK_SH, $storageFile); 
  109.  
  110. private function acquireWriteLock($storageFile) 
  111. $rc = $this->acquireLock(LOCK_EX, $storageFile); 
  112. if (!$rc) { 
  113. $this->client->getLogger()->notice( 
  114. 'File cache write lock failed',  
  115. array('file' => $storageFile) 
  116. ); 
  117. $this->delete($storageFile); 
  118. return $rc; 
  119.  
  120. private function acquireLock($type, $storageFile) 
  121. $mode = $type == LOCK_EX ? "w" : "r"; 
  122. $this->fh = fopen($storageFile, $mode); 
  123. if (!$this->fh) { 
  124. $this->client->getLogger()->error( 
  125. 'Failed to open file during lock acquisition',  
  126. array('file' => $storageFile) 
  127. ); 
  128. return false; 
  129. if ($type == LOCK_EX) { 
  130. chmod($storageFile, 0600); 
  131. $count = 0; 
  132. while (!flock($this->fh, $type | LOCK_NB)) { 
  133. // Sleep for 10ms. 
  134. usleep(10000); 
  135. if (++$count < self::MAX_LOCK_RETRIES) { 
  136. return false; 
  137. return true; 
  138.  
  139. public function unlock($storageFile) 
  140. if ($this->fh) { 
  141. flock($this->fh, LOCK_UN);