📜 ⬆️ ⬇️

How I made friends with memcache and propel in symfony

This article is written in the continuation of the post “ ORM - evil or How I tried to cache Propel in symfony ” to help the user remal .

As I wrote in the last article, in order for the cache to work it is necessary to override 4 methods of the pool that are in Peer objects:

public static function addInstanceToPool($obj, $key = null );
public static function removeInstanceFromPool($ value );
public static function getInstanceFromPool($key);
public static function clearInstancePool();

* This source code was highlighted with Source Code Highlighter .


In order not to duplicate the code for each Peer object (according to the user’s remal tip), you can use the Propel code generator. When creating a project, you should create a file config / propel.ini, in which the classes responsible for generation are indicated:
')
propel.builder.peer. class = plugins.sfPropelPlugin.lib.builder.SfPeerBuilder
propel.builder. object . class = plugins.sfPropelPlugin.lib.builder.SfObjectBuilder

* This source code was highlighted with Source Code Highlighter .


In our case, these are the SfPeerBuilder and SfObjectBuilder classes, which are located in the sfPropelPlugin plugin.

When studying these classes, it turned out that they have a set of methods that are called in a certain order. The link to the $ script variable is passed to each of them. These methods are named after the mask add <method_name_in_generated_object>. For example, addAddInstanceToPool (& $ script).

So, we create the SfPeerBuilderMemcache class, where we override the SfPeerBuilder logic

class SfPeerBuilderMemcache extends SfPeerBuilder
{
protected function addGetPropelCacheStorage(&$script){}
protected function addRemoveInstanceFromPool(&$script){}
protected function addClearInstancePool(&$script){}
protected function addGetInstanceFromPool(&$script){}
}

* This source code was highlighted with Source Code Highlighter .


But since we do not need to cache the entire model, we will make it possible to enable and disable the cache in the schema (schema.yml). Example:

user:
_attributes: { phpName: User, cache: on }

* This source code was highlighted with Source Code Highlighter .


And we will add a method to the SfPeerBuilderMemcache class that will check whether the cache is enabled for a particular model.

protected function isPropelCacheEnabled()
{
return (boolean)$ this ->getTable()->getAttribute( "cache" );
}

* This source code was highlighted with Source Code Highlighter .


Further implementation of this class is left to those who need it ... well, or see the source code at the end of the article :)

But that is not all!!! As I wrote in the previous article in the case when join'y is not used when retrieving a connected object, Propel instead of retriveByPk () makes a request to the database, which in our case is not allowed. To solve this situation, you need to override the SfObjectBuilder class, namely the addFKAccessor method, which, if the associated model is cached, will generate the necessary logic:

class SfObjectBuilderMemcache extends SfObjectBuilder
{
protected function addFKAccessor(&$script, ForeignKey $fk)
{
if (!$ this ->getForeignTable($fk)->getAttribute( "cache" ))
{
return parent::addFKAccessor($script, $fk);
}

//-
}
}

* This source code was highlighted with Source Code Highlighter .


Now we have to change the parameters in the config / propel.ini file for something like this:

propel.builder.peer. class = plugins.sfPropelMemcachePlugin.lib.builder.SfPeerBuilderMemcache
propel.builder. object . class = plugins.sfPropelMemcachePlugin.lib.builder.SfObjectBuilderMemcache

* This source code was highlighted with Source Code Highlighter .


Everything! It remains only to rebuild the model.

Who needs more digging into the source .

What happened in my case?
I turned on the cache for the User model. Now, if I call the getUser () method on the Photo object, it will call the UserPeer :: retrieveByPK () method. Which also will take object from a cache or from base, having saved in a cache. By analogy with Photo, all objects associated with User will come.

UPD: Continued
habrahabr.ru/blogs/symfony/76162

Source: https://habr.com/ru/post/74873/


All Articles