KXStudio Website https://kx.studio/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.9KB

  1. <?php
  2. class MemCacher{
  3. public function __construct($url, $config){
  4. $raw_hosts = (array)$config->cache_memcached_hosts;
  5. $this->user = (logged_in()) ? Visitor::current()->login : "guest" ;
  6. $this->memcache = new Memcache();
  7. $this->url = $url;
  8. $this->config = $config;
  9. $disable_module = true;
  10. foreach($raw_hosts as $raw){
  11. $raw = trim($raw);
  12. if($raw == '') continue;
  13. $stack = explode(':', $raw);
  14. $host = false;
  15. $port = 11211;
  16. if(count($stack) == 9 or count($stack) == 2){ # ipv6 with port is 9, ipv4 with port is 2
  17. $port = array_pop($stack);
  18. }
  19. if(count($stack) == 1){
  20. $host = $stack[0];
  21. }
  22. if(count($stack) == 8){ # ipv6 is 8 entries
  23. $host = implode(':', $stack);
  24. }
  25. if($host === false and count($stack) > 0){ # probably a uri for other transit
  26. $host = implode(':', $stack);
  27. $port = 0; # other transit requires a port of 0
  28. }
  29. if($host === false){
  30. error_log("Memcached error: $raw is an invalid host address");
  31. }else{
  32. $this->memcache->addServer($host, $port);
  33. $disable_module = false;
  34. }
  35. }
  36. //$disable_module = true;
  37. if ($disable_module)
  38. cancel_module("cacher");
  39. }
  40. function build_key($value){
  41. $prefix = '';
  42. if($prefix and $prefix != ''){
  43. $prefix = "chyrp_$prefix_";
  44. }else{
  45. $prefix = "chyrp_";
  46. }
  47. return $prefix . $value;
  48. }
  49. public function url_available(){
  50. $this->keys = array();
  51. $this->keys[] = $this->build_key("global");
  52. $this->keys[] = $this->build_key("url=" . $this->url);
  53. $this->keys[] = $this->build_key("user=" . $this->user);
  54. $this->keys[] = $this->user_url_key = $this->build_key("user_url=/" . $this->user . '/' . $this->url);
  55. $this->cache_result = $this->memcache->get($this->keys);
  56. return $this->cached_copy_valid();
  57. }
  58. function cached_copy_valid(){
  59. if(!array_key_exists($this->user_url_key, $this->cache_result))
  60. return false;
  61. $copy = $this->cache_result[$this->user_url_key];
  62. $time = $copy['timestamp'];
  63. foreach(array_keys($this->cache_result) as $k){
  64. if($k != $this->user_url_key && $this->cache_result[$k] > $time)
  65. return false;
  66. }
  67. return true;
  68. }
  69. public function get(){
  70. $hash = $this->cache_result[$this->user_url_key];
  71. if(DEBUG)
  72. error_log("Memcache: From cache, modified at " . $hash['timestamp'] . " - " . $this->user_url_key);
  73. $cache = array('contents' => $hash['value'], 'headers' => array());
  74. return $cache;
  75. }
  76. public function set($value){
  77. $hash = array( 'timestamp' => time(), 'value' => $value );
  78. $result = $this->memcache->set($this->user_url_key, $hash, false, Config::current()->cache_expire);
  79. if(!$result){
  80. exit("Memcache: set failed for " . $this->user_url_key);
  81. }
  82. }
  83. public function regenerate() {
  84. $this->memcache->set($this->build_key('global'), time());
  85. }
  86. public function regenerate_local($user = null) {
  87. if($user == null) $user = 'guest';
  88. $this->memcache->set($this->build_key("user=" . $user), time());
  89. }
  90. public function remove_caches_for($url) {
  91. $this->memcache->set($this->build_key("url=" . $url), time());
  92. }
  93. }