RedisCachePlugin.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. // This file is part of GNU social - https://www.gnu.org/software/social
  3. //
  4. // GNU social is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // GNU social is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Plguin inplementing Redis based caching
  18. *
  19. * @category Files
  20. * @package GNUsocial
  21. * @author Stéphane Bérubé <chimo@chromic.org>
  22. * @author Miguel Dantas <biodantas@gmail.com>
  23. * @copyright 2018, 2019 Free Software Foundation, Inc http://www.fsf.org
  24. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  25. */
  26. defined('GNUSOCIAL') || die();
  27. use Predis\Client;
  28. use Predis\PredisException;
  29. class RedisCachePlugin extends Plugin
  30. {
  31. const PLUGIN_VERSION = '0.1.0';
  32. // settings which can be set in config.php with addPlugin('Embed', ['param'=>'value', ...]);
  33. public $server = null;
  34. public $defaultExpiry = 86400; // 24h
  35. protected $client = null;
  36. public function onInitializePlugin()
  37. {
  38. $this->_ensureConn();
  39. return true;
  40. }
  41. private function _ensureConn()
  42. {
  43. if ($this->client === null) {
  44. $this->client = new Client($this->server);
  45. }
  46. }
  47. public function onStartCacheGet($key, &$value)
  48. {
  49. try {
  50. $this->_ensureConn();
  51. $ret = $this->client->get($key);
  52. } catch (PredisException $e) {
  53. common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage());
  54. return true;
  55. }
  56. // Hit, overwrite "value" and return false
  57. // to indicate we took care of this
  58. if ($ret !== null) {
  59. $value = unserialize($ret);
  60. return false;
  61. }
  62. // Miss, let GS do its thing
  63. return true;
  64. }
  65. public function onStartCacheSet($key, $value, $flag, $expiry, &$success)
  66. {
  67. $success = false;
  68. if (is_null($expiry)) {
  69. $expiry = $this->defaultExpiry;
  70. }
  71. try {
  72. $this->_ensureConn();
  73. $ret = $this->client->setex($key, $expiry, serialize($value));
  74. } catch (PredisException $e) {
  75. $ret = false;
  76. common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage());
  77. }
  78. if (is_bool($ret)
  79. || is_numeric($ret)) {
  80. $success = ($ret ? true : false);
  81. } elseif (is_object($ret) && method_exists($ret, 'getPayload')) {
  82. $success = ($ret->getPayload() === 'OK');
  83. }
  84. return !$success;
  85. }
  86. public function onStartCacheDelete($key)
  87. {
  88. if ($key === null) {
  89. return true;
  90. }
  91. try {
  92. $this->_ensureConn();
  93. $ret = $this->client->del($key);
  94. } catch (PredisException $e) {
  95. common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage());
  96. }
  97. // Let other caches delete stuff if we didn't succeed
  98. return isset($ret) && $ret === 1;
  99. }
  100. public function onStartCacheIncrement($key, $step, $value)
  101. {
  102. try {
  103. $this->_ensureConn();
  104. $this->client->incrby($key, $step);
  105. } catch (PredisException $e) {
  106. common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage());
  107. return true;
  108. }
  109. return false;
  110. }
  111. public function onPluginVersion(array &$versions): bool
  112. {
  113. $versions[] = [
  114. 'name' => 'RedisCache',
  115. 'version' => self::PLUGIN_VERSION,
  116. 'author' => 'Stéphane Bérubé (chimo)',
  117. 'homepage' => 'https://github.com/chimo/gs-rediscache',
  118. 'description' =>
  119. // TRANS: Plugin description.
  120. _m('Plugin implementing Redis as a backend for GNU social caching')
  121. ];
  122. return true;
  123. }
  124. }