Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd4e109b

Browse files
[Cache] Add DSN, createClient & better error reporting to MemcachedAdapter
1 parent61a67ec commitd4e109b

File tree

10 files changed

+198
-17
lines changed

10 files changed

+198
-17
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespaceSymfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
1313

14-
useSymfony\Component\Cache\Adapter\RedisAdapter;
14+
useSymfony\Component\Cache\Adapter\AbstractAdapter;
1515
useSymfony\Component\DependencyInjection\ChildDefinition;
1616
useSymfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1717
useSymfony\Component\DependencyInjection\ContainerBuilder;
@@ -108,13 +108,13 @@ public static function getServiceProvider(ContainerBuilder $container, $name)
108108
{
109109
$container->resolveEnvPlaceholders($name,null,$usedEnvs);
110110

111-
if (0 ===strpos($name,'redis://') ||$usedEnvs) {
111+
if ($usedEnvs ||preg_match('#^[a-z]++://#',$name)) {
112112
$dsn =$name;
113113

114114
if (!$container->hasDefinition($name =md5($dsn))) {
115-
$definition =newDefinition(\Redis::class);
115+
$definition =newDefinition('_');
116116
$definition->setPublic(false);
117-
$definition->setFactory(array(RedisAdapter::class,'createConnection'));
117+
$definition->setFactory(array(AbstractAdapter::class,'createConnection'));
118118
$definition->setArguments(array($dsn));
119119
$container->setDefinition($name,$definition);
120120
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ private function addCacheSection(ArrayNodeDefinition $rootNode)
706706
->scalarNode('default_doctrine_provider')->end()
707707
->scalarNode('default_psr6_provider')->end()
708708
->scalarNode('default_redis_provider')->defaultValue('redis://localhost')->end()
709+
->scalarNode('default_memcached_provider')->defaultValue('memcached://localhost')->end()
709710
->arrayNode('pools')
710711
->useAttributeAsKey('name')
711712
->prototype('array')

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
12561256
// Inline any env vars referenced in the parameter
12571257
$container->setParameter('cache.prefix.seed',$container->resolveEnvPlaceholders($container->getParameter('cache.prefix.seed'),true));
12581258
}
1259-
foreach (array('doctrine','psr6','redis')as$name) {
1259+
foreach (array('doctrine','psr6','redis','memcached')as$name) {
12601260
if (isset($config[$name ='default_'.$name.'_provider'])) {
12611261
$container->setAlias('cache.'.$name,newAlias(Compiler\CachePoolPass::getServiceProvider($container,$config[$name]),false));
12621262
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@
9393
</call>
9494
</service>
9595

96+
<serviceid="cache.adapter.memcached"class="Symfony\Component\Cache\Adapter\MemcachedAdapter"abstract="true">
97+
<tagname="cache.pool"provider="cache.default_memcached_provider"clearer="cache.default_clearer" />
98+
<tagname="monolog.logger"channel="cache" />
99+
<argument /><!-- Memcached connection service-->
100+
<argument /><!-- namespace-->
101+
<argument>0</argument><!-- default lifetime-->
102+
<callmethod="setLogger">
103+
<argumenttype="service"id="logger"on-invalid="ignore" />
104+
</call>
105+
</service>
106+
96107
<serviceid="cache.default_clearer"class="Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer">
97108
<tagname="kernel.cache_clearer" />
98109
</service>

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
<xsd:elementname="default-doctrine-provider"type="xsd:string"minOccurs="0"maxOccurs="1" />
216216
<xsd:elementname="default-psr6-provider"type="xsd:string"minOccurs="0"maxOccurs="1" />
217217
<xsd:elementname="default-redis-provider"type="xsd:string"minOccurs="0"maxOccurs="1" />
218+
<xsd:elementname="default-memcached-provider"type="xsd:string"minOccurs="0"maxOccurs="1" />
218219
<xsd:elementname="pool"type="cache_pool"minOccurs="0"maxOccurs="unbounded" />
219220
</xsd:sequence>
220221
</xsd:complexType>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ protected static function getBundleDefaultConfig()
272272
'system' =>'cache.adapter.system',
273273
'directory' =>'%kernel.cache_dir%/pools',
274274
'default_redis_provider' =>'redis://localhost',
275+
'default_memcached_provider' =>'memcached://localhost',
275276
),
276277
'workflows' =>array(),
277278
'php_errors' =>array(

‎src/Symfony/Bundle/FrameworkBundle/composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"require": {
1919
"php":">=5.5.9",
20-
"symfony/cache":"~3.2",
20+
"symfony/cache":"~3.3",
2121
"symfony/class-loader":"~3.2",
2222
"symfony/dependency-injection":"~3.3",
2323
"symfony/config":"~2.8|~3.0",

‎src/Symfony/Bundle/FrameworkBundle/phpunit.xml.dist‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<php>
1010
<ininame="error_reporting"value="-1" />
1111
<envname="REDIS_HOST"value="localhost" />
12+
<envname="MEMCACHED_HOST"value="localhost" />
1213
</php>
1314

1415
<testsuites>

‎src/Symfony/Component/Cache/Adapter/AbstractAdapter.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ public static function createSystemCache($namespace, $defaultLifetime, $version,
115115
returnnewChainAdapter(array($apcu,$fs));
116116
}
117117

118+
publicstaticfunctioncreateConnection($dsn,array$options =array())
119+
{
120+
if (!is_string($dsn)) {
121+
thrownewInvalidArgumentException(sprintf('The %s() method expect argument #1 to be string, %s given.',__METHOD__,gettype($dsn)));
122+
}
123+
if (0 ===strpos($dsn,'redis://')) {
124+
return RedisAdapter::createConnection($dsn,$options);
125+
}
126+
if (0 ===strpos($dsn,'memcached://')) {
127+
return MemcachedAdapter::createConnection($dsn,$options);
128+
}
129+
130+
thrownewInvalidArgumentException(sprintf('Unsupported DSN: %s.',$dsn));
131+
}
132+
118133
/**
119134
* Fetches several cache items.
120135
*

‎src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php‎

Lines changed: 162 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,68 +11,219 @@
1111

1212
namespaceSymfony\Component\Cache\Adapter;
1313

14+
useSymfony\Component\Cache\Exception\CacheException;
15+
useSymfony\Component\Cache\Exception\InvalidArgumentException;
16+
1417
/**
1518
* @author Rob Frawley 2nd <rmf@src.run>
19+
* @author Nicolas Grekas <p@tchwork.com>
1620
*/
1721
class MemcachedAdapterextends AbstractAdapter
1822
{
23+
privatestatic$defaultClientOptions =array(
24+
'persistent_id' =>null,
25+
'username' =>null,
26+
'password' =>null,
27+
);
28+
29+
protected$maxIdLength =250;
30+
1931
private$client;
2032

33+
publicstaticfunctionisSupported()
34+
{
35+
returnextension_loaded('memcached') &&version_compare(phpversion('memcached'),'2.2.0','>=');
36+
}
37+
2138
publicfunction__construct(\Memcached$client,$namespace ='',$defaultLifetime =0)
2239
{
40+
if (!static::isSupported()) {
41+
thrownewCacheException('Memcached >= 2.2.0 is required');
42+
}
43+
$opt =$client->getOption(\Memcached::OPT_SERIALIZER);
44+
if (\Memcached::SERIALIZER_PHP !==$opt && \Memcached::SERIALIZER_IGBINARY !==$opt) {
45+
thrownewCacheException('MemcachedAdapter: serializer must be PHP or IGBINARY.');
46+
}
47+
if (!$client->getOption(\Memcached::OPT_BINARY_PROTOCOL)) {
48+
thrownewCacheException('MemcachedAdapter: OPT_BINARY_PROTOCOL must be used.');
49+
}
50+
$this->maxIdLength -=strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
51+
2352
parent::__construct($namespace,$defaultLifetime);
2453
$this->client =$client;
2554
}
2655

27-
publicstaticfunctionisSupported()
56+
/**
57+
* @return \Memcached
58+
*
59+
* @throws \ErrorEception When invalid options or servers are provided.
60+
*/
61+
publicstaticfunctioncreateConnection($servers,array$options =array())
2862
{
29-
returnextension_loaded('memcached') &&version_compare(phpversion('memcached'),'2.2.0','>=');
63+
if (is_string($servers)) {
64+
$servers =array($servers);
65+
}elseif (!is_array($servers)) {
66+
thrownewInvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, %s given.',get_type($servers)));
67+
}
68+
set_error_handler(function ($type,$msg,$file,$line) {thrownew \ErrorException($msg,0,$type,$file,$line); });
69+
try {
70+
$options +=static::$defaultClientOptions;
71+
$client =new \Memcached($options['persistent_id']);
72+
$username =$options['username'];
73+
$password =$options['password'];
74+
unset($options['persistent_id'],$options['username'],$options['password']);
75+
$options =array_change_key_case($options,CASE_UPPER);
76+
77+
// set client's options
78+
$client->setOption(\Memcached::OPT_BINARY_PROTOCOL,true);
79+
if (!array_key_exists('LIBKETAMA_COMPATIBLE',$options) && !!array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE,$options)) {
80+
$client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE,true);
81+
}
82+
foreach ($optionsas$name =>$value) {
83+
if (is_int($name)) {
84+
continue;
85+
}
86+
if ('HASH' ===$name ||'SERIALIZER' ===$name ||'DISTRIBUTION' ===$name) {
87+
$value =constant('Memcached::'.$name.'_'.strtoupper($value));
88+
}
89+
$opt =constant('Memcached::OPT_'.$name);
90+
91+
unset($options[$name]);
92+
$options[$opt] =$value;
93+
}
94+
$client->setOptions($options);
95+
96+
// parse any DSN in $servers
97+
foreach ($serversas$i =>$dsn) {
98+
if (is_array($dsn)) {
99+
continue;
100+
}
101+
if (0 !==strpos($dsn,'memcached://')) {
102+
thrownewInvalidArgumentException(sprintf('Invalid Memcached DSN: %s does not start with "memcached://"',$dsn));
103+
}
104+
$params =preg_replace_callback('#^memcached://(?:([^@]*+)@)?#',function ($m)use (&$username, &$password) {
105+
if (!empty($m[1])) {
106+
list($username,$password) =explode(':',$m[1],2) +array(1 =>null);
107+
}
108+
109+
return'file://';
110+
},$dsn);
111+
if (false ===$params =parse_url($params)) {
112+
thrownewInvalidArgumentException(sprintf('Invalid Memcached DSN: %s',$dsn));
113+
}
114+
if (!isset($params['host']) && !isset($params['path'])) {
115+
thrownewInvalidArgumentException(sprintf('Invalid Memcached DSN: %s',$dsn));
116+
}
117+
if (isset($params['path']) &&preg_match('#/(\d+)$#',$params['path'],$m)) {
118+
$params['weight'] =$m[1];
119+
$params['path'] =substr($params['path'],0, -strlen($m[0]));
120+
}
121+
$params +=array(
122+
'host' =>isset($params['host']) ?$params['host'] :$params['path'],
123+
'port' =>isset($params['host']) ?11211 :null,
124+
'weight' =>0,
125+
);
126+
if (isset($params['query'])) {
127+
parse_str($params['query'],$query);
128+
$params +=$query;
129+
}
130+
131+
$servers[$i] =array($params['host'],$params['port'],$params['weight']);
132+
}
133+
134+
// set client's servers, taking care of persistent connections
135+
if (!$client->isPristine()) {
136+
$oldServers =array();
137+
foreach ($client->getServerList()as$server) {
138+
$oldServers[] =array($server['host'],$server['port']);
139+
}
140+
141+
$newServers =array();
142+
foreach ($serversas$server) {
143+
if (1 <count($server)) {
144+
$server =array_values($server);
145+
unset($server[2]);
146+
$server[1] = (int)$server[1];
147+
}
148+
$newServers[] =$server;
149+
}
150+
151+
if ($oldServers !==$newServers) {
152+
// before resetting, ensure $servers is valid
153+
$client->addServers($servers);
154+
$client->resetServerList();
155+
}
156+
}
157+
$client->addServers($servers);
158+
159+
if (null !==$username ||null !==$password) {
160+
if (!method_exists($client,'setSaslAuthData')) {
161+
trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.');
162+
}
163+
$client->setSaslAuthData($username,$password);
164+
}
165+
166+
return$client;
167+
}finally {
168+
restore_error_handler();
169+
}
30170
}
31171

32172
/**
33173
* {@inheritdoc}
34174
*/
35175
protectedfunctiondoSave(array$values,$lifetime)
36176
{
37-
return$this->client->setMulti($values,$lifetime) &&$this->client->getResultCode() === \Memcached::RES_SUCCESS;
177+
return$this->checkResultCode($this->client->setMulti($values,$lifetime));
38178
}
39179

40180
/**
41181
* {@inheritdoc}
42182
*/
43183
protectedfunctiondoFetch(array$ids)
44184
{
45-
return$this->client->getMulti($ids);
185+
return$this->checkResultCode($this->client->getMulti($ids));
46186
}
47187

48188
/**
49189
* {@inheritdoc}
50190
*/
51191
protectedfunctiondoHave($id)
52192
{
53-
return$this->client->get($id)!==false||$this->client->getResultCode() ===\Memcached::RES_SUCCESS;
193+
returnfalse !==$this->client->get($id) ||$this->checkResultCode(\Memcached::RES_SUCCESS ===$this->client->getResultCode());
54194
}
55195

56196
/**
57197
* {@inheritdoc}
58198
*/
59199
protectedfunctiondoDelete(array$ids)
60200
{
61-
$toDelete =count($ids);
62-
foreach ($this->client->deleteMulti($ids)as$result) {
63-
if (\Memcached::RES_SUCCESS===$result|| \Memcached::RES_NOTFOUND===$result) {
64-
--$toDelete;
201+
$ok =true;
202+
foreach ($this->checkResultCode($this->client->deleteMulti($ids))as$result) {
203+
if (\Memcached::RES_SUCCESS!==$result&& \Memcached::RES_NOTFOUND!==$result) {
204+
$ok =false;
65205
}
66206
}
67207

68-
return0 ===$toDelete;
208+
return$ok;
69209
}
70210

71211
/**
72212
* {@inheritdoc}
73213
*/
74214
protectedfunctiondoClear($namespace)
75215
{
76-
return$this->client->flush();
216+
return$this->checkResultCode($this->client->flush());
217+
}
218+
219+
privatefunctioncheckResultCode($result)
220+
{
221+
$code =$this->client->getResultCode();
222+
223+
if (\Memcached::RES_SUCCESS ===$code || \Memcached::RES_NOTFOUND ===$code) {
224+
return$result;
225+
}
226+
227+
thrownewCacheException(sprintf('MemcachedAdapter client error: %s.',strtolower($this->client->getResultMessage())));
77228
}
78229
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp