| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * GNU social - a federating social network | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Plguin inplementing Redis based caching | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * LICENCE: This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @category  Files | 
					
						
							|  |  |  |  * @package   GNUsocial | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |  * @author    Stéphane Bérubé <chimo@chromic.org> | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |  * @author    Miguel Dantas <biodantas@gmail.com> | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |  * @copyright 2018, 2019 Free Software Foundation http://fsf.org | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | 
					
						
							|  |  |  |  * @link      https://www.gnu.org/software/social/ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | defined('GNUSOCIAL') || die(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  | use Predis\Client; | 
					
						
							|  |  |  | use Predis\PredisException; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | class RedisCachePlugin extends Plugin | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-11 02:20:54 +00:00
										 |  |  |     const PLUGIN_VERSION = '0.1.0'; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |     // settings which can be set in config.php with addPlugin('Embed', ['param'=>'value', ...]);
 | 
					
						
							|  |  |  |     public $server = null; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     public $defaultExpiry = 86400; // 24h
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected $client = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     function onInitializePlugin() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->_ensureConn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function _ensureConn() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($this->client === null) { | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |             $this->client = new Client($this->server); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheGet(&$key, &$value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  |             $ret = $this->client->get($key); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Hit, overwrite "value" and return false
 | 
					
						
							|  |  |  |         // to indicate we took care of this
 | 
					
						
							|  |  |  |         if ($ret !== null) { | 
					
						
							|  |  |  |             $value = unserialize($ret); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Miss, let GS do its thing
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($expiry === null) { | 
					
						
							|  |  |  |             $expiry = $this->defaultExpiry; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $ret = $this->client->setex($key, $expiry, serialize($value)); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Fix 'Call to a member function getPayload() on null'
Trying to enable the RedisCache with the latest nightly, getting this with the daemon:
sep 25 11:40:18 friedrich startdaemons.sh[21428]: PHP Fatal error:  Uncaught Error: Call to a member function getPayload() on null in /var/www/social/plugins/RedisCache/RedisCachePlugin.php:96
sep 25 11:40:18 friedrich startdaemons.sh[21428]: Stack trace:
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #0 /var/www/social/lib/util/event.php(89): RedisCachePlugin->onStartCacheSet('gnusocial:herds...', Object(HubSub), NULL, 86400, false)
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #1 /var/www/social/lib/cache/cache.php(202): Event::handle('StartCacheSet', Array)
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #2 /var/www/social/classes/Memcached_DataObject.php(520): Cache->set('gnusocial:herds...', Object(HubSub))
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #3 /var/www/social/classes/Memcached_DataObject.php(52): Memcached_DataObject->encache()
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #4 /var/www/social/classes/Managed_DataObject.php(50): Memcached_DataObject::getClassKV('HubSub', 'hashkey', 'a38b9dc516371af...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #5 /var/www/social/plugins/OStatus/classes/HubSub.php(47): Managed_DataObject::getKV('hashkey', 'a38b9dc516371af...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #6 /var/www/social/plugins/OStatus/lib/hubprepqueuehandler.php(68): HubSub::getByHashkey('https://herds.e...', 'https://raki.so...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #7 /var/www/social/plugins/RedisQueue/classes/RedisQueueManager.php(58): HubPrepQueueHandl in /var/www/social/plugins/RedisCache/RedisCachePlugin.php on line 96
Sign in to j
											
										 
											2019-09-26 11:23:02 +01:00
										 |  |  |         if (is_int($ret) || (!is_null($ret) && $ret->getPayload() === "OK")) { | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             $success = true; | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheDelete($key) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         if ($key === null) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |             $ret = $this->client->del($key); | 
					
						
							|  |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         // Let other caches delete stuff if we didn't succeed
 | 
					
						
							| 
									
										
										
										
											2019-08-14 14:53:57 +01:00
										 |  |  |         return isset($ret) && $ret === 1; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function onStartCacheIncrement(&$key, &$step, &$value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $this->_ensureConn(); | 
					
						
							|  |  |  |             $this->client->incrby($key, $step); | 
					
						
							| 
									
										
										
										
											2019-08-13 02:52:35 +01:00
										 |  |  |         } catch(PredisException $e) { | 
					
						
							|  |  |  |             common_log(LOG_ERR, 'RedisCache encountered exception ' . get_class($e) . ': ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 15:03:30 +01:00
										 |  |  |     public function onPluginVersion(array &$versions): bool | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-12-11 02:20:54 +00:00
										 |  |  |         $versions[] = [ | 
					
						
							|  |  |  |             'name' => 'RedisCache', | 
					
						
							|  |  |  |             'version' => self::VERSION, | 
					
						
							|  |  |  |             'author' => 'Stéphane Bérubé (chimo)', | 
					
						
							|  |  |  |             'homepage' => 'https://github.com/chimo/gs-rediscache', | 
					
						
							|  |  |  |             'description' => | 
					
						
							|  |  |  |             // TRANS: Plugin description.
 | 
					
						
							|  |  |  |             _m('Plugin implementing Redis as a backend for GNU social caching') | 
					
						
							|  |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2019-08-13 01:31:05 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |