Skip to content

Commit 5cc4baf

Browse files
Nyholmnicolas-grekas
authored andcommitted
[Cache] TraceableAdapter
1 parent d0e8476 commit 5cc4baf

File tree

2 files changed

+391
-0
lines changed

2 files changed

+391
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Adapter;
13+
14+
use Psr\Cache\CacheItemInterface;
15+
16+
/**
17+
* An adapter that collects data about all cache calls.
18+
*
19+
* @author Aaron Scherer <aequasi@gmail.com>
20+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
21+
* @author Nicolas Grekas <p@tchwork.com>
22+
*/
23+
class TraceableAdapter implements AdapterInterface
24+
{
25+
private $pool;
26+
private $calls = array();
27+
28+
public function __construct(AdapterInterface $pool)
29+
{
30+
$this->pool = $pool;
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function getItem($key)
37+
{
38+
$event = $this->start(__FUNCTION__, $key);
39+
try {
40+
$item = $this->pool->getItem($key);
41+
} finally {
42+
$event->end = microtime(true);
43+
}
44+
if ($item->isHit()) {
45+
++$event->hits;
46+
} else {
47+
++$event->misses;
48+
}
49+
$event->result = $item->get();
50+
51+
return $item;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function hasItem($key)
58+
{
59+
$event = $this->start(__FUNCTION__, $key);
60+
try {
61+
return $event->result = $this->pool->hasItem($key);
62+
} finally {
63+
$event->end = microtime(true);
64+
}
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function deleteItem($key)
71+
{
72+
$event = $this->start(__FUNCTION__, $key);
73+
try {
74+
return $event->result = $this->pool->deleteItem($key);
75+
} finally {
76+
$event->end = microtime(true);
77+
}
78+
}
79+
80+
/**
81+
* {@inheritdoc}
82+
*/
83+
public function save(CacheItemInterface $item)
84+
{
85+
$event = $this->start(__FUNCTION__, $item);
86+
try {
87+
return $event->result = $this->pool->save($item);
88+
} finally {
89+
$event->end = microtime(true);
90+
}
91+
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function saveDeferred(CacheItemInterface $item)
97+
{
98+
$event = $this->start(__FUNCTION__, $item);
99+
try {
100+
return $event->result = $this->pool->saveDeferred($item);
101+
} finally {
102+
$event->end = microtime(true);
103+
}
104+
}
105+
106+
/**
107+
* {@inheritdoc}
108+
*/
109+
public function getItems(array $keys = array())
110+
{
111+
$event = $this->start(__FUNCTION__, $keys);
112+
try {
113+
$result = $this->pool->getItems($keys);
114+
} finally {
115+
$event->end = microtime(true);
116+
}
117+
$f = function () use ($result, $event) {
118+
$event->result = array();
119+
foreach ($result as $key => $item) {
120+
if ($item->isHit()) {
121+
++$event->hits;
122+
} else {
123+
++$event->misses;
124+
}
125+
$event->result[$key] = $item->get();
126+
yield $key => $item;
127+
}
128+
};
129+
130+
return $f();
131+
}
132+
133+
/**
134+
* {@inheritdoc}
135+
*/
136+
public function clear()
137+
{
138+
$event = $this->start(__FUNCTION__);
139+
try {
140+
return $event->result = $this->pool->clear();
141+
} finally {
142+
$event->end = microtime(true);
143+
}
144+
}
145+
146+
/**
147+
* {@inheritdoc}
148+
*/
149+
public function deleteItems(array $keys)
150+
{
151+
$event = $this->start(__FUNCTION__, $keys);
152+
try {
153+
return $event->result = $this->pool->deleteItems($keys);
154+
} finally {
155+
$event->end = microtime(true);
156+
}
157+
}
158+
159+
/**
160+
* {@inheritdoc}
161+
*/
162+
public function commit()
163+
{
164+
$event = $this->start(__FUNCTION__);
165+
try {
166+
return $event->result = $this->pool->commit();
167+
} finally {
168+
$event->end = microtime(true);
169+
}
170+
}
171+
172+
public function getCalls()
173+
{
174+
try {
175+
return $this->calls;
176+
} finally {
177+
$this->calls = array();
178+
}
179+
}
180+
181+
private function start($name, $argument = null)
182+
{
183+
$this->calls[] = $event = new TraceableAdapterEvent();
184+
$event->name = $name;
185+
$event->argument = $argument;
186+
$event->start = microtime(true);
187+
188+
return $event;
189+
}
190+
}
191+
192+
class TraceableAdapterEvent
193+
{
194+
public $name;
195+
public $argument;
196+
public $start;
197+
public $end;
198+
public $result;
199+
public $hits = 0;
200+
public $misses = 0;
201+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Tests\Adapter;
13+
14+
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
15+
use Symfony\Component\Cache\Adapter\TraceableAdapter;
16+
17+
/**
18+
* @group time-sensitive
19+
*/
20+
class TraceableAdapterTest extends AdapterTestCase
21+
{
22+
public function createCachePool($defaultLifetime = 0)
23+
{
24+
return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime));
25+
}
26+
27+
public function testGetItemMiss()
28+
{
29+
$pool = $this->createCachePool();
30+
$pool->getItem('k');
31+
$calls = $pool->getCalls();
32+
$this->assertCount(1, $calls);
33+
34+
$call = $calls[0];
35+
$this->assertEquals('getItem', $call->name);
36+
$this->assertEquals('k', $call->argument);
37+
$this->assertEquals(0, $call->hits);
38+
$this->assertEquals(1, $call->misses);
39+
$this->assertNull($call->result);
40+
$this->assertNotEmpty($call->start);
41+
$this->assertNotEmpty($call->end);
42+
}
43+
44+
public function testGetItemHit()
45+
{
46+
$pool = $this->createCachePool();
47+
$item = $pool->getItem('k')->set('foo');
48+
$pool->save($item);
49+
$pool->getItem('k');
50+
$calls = $pool->getCalls();
51+
$this->assertCount(3, $calls);
52+
53+
$call = $calls[2];
54+
$this->assertEquals(1, $call->hits);
55+
$this->assertEquals(0, $call->misses);
56+
}
57+
58+
public function testGetItemsMiss()
59+
{
60+
$pool = $this->createCachePool();
61+
$arg = array('k0', 'k1');
62+
$items = $pool->getItems($arg);
63+
foreach ($items as $item) {
64+
}
65+
$calls = $pool->getCalls();
66+
$this->assertCount(1, $calls);
67+
68+
$call = $calls[0];
69+
$this->assertEquals('getItems', $call->name);
70+
$this->assertEquals($arg, $call->argument);
71+
$this->assertEquals(2, $call->misses);
72+
$this->assertNotEmpty($call->start);
73+
$this->assertNotEmpty($call->end);
74+
}
75+
76+
public function testHasItemMiss()
77+
{
78+
$pool = $this->createCachePool();
79+
$pool->hasItem('k');
80+
$calls = $pool->getCalls();
81+
$this->assertCount(1, $calls);
82+
83+
$call = $calls[0];
84+
$this->assertEquals('hasItem', $call->name);
85+
$this->assertEquals('k', $call->argument);
86+
$this->assertFalse($call->result);
87+
$this->assertNotEmpty($call->start);
88+
$this->assertNotEmpty($call->end);
89+
}
90+
91+
public function testHasItemHit()
92+
{
93+
$pool = $this->createCachePool();
94+
$item = $pool->getItem('k')->set('foo');
95+
$pool->save($item);
96+
$pool->hasItem('k');
97+
$calls = $pool->getCalls();
98+
$this->assertCount(3, $calls);
99+
100+
$call = $calls[2];
101+
$this->assertEquals('hasItem', $call->name);
102+
$this->assertEquals('k', $call->argument);
103+
$this->assertTrue($call->result);
104+
$this->assertNotEmpty($call->start);
105+
$this->assertNotEmpty($call->end);
106+
}
107+
108+
public function testDeleteItem()
109+
{
110+
$pool = $this->createCachePool();
111+
$pool->deleteItem('k');
112+
$calls = $pool->getCalls();
113+
$this->assertCount(1, $calls);
114+
115+
$call = $calls[0];
116+
$this->assertEquals('deleteItem', $call->name);
117+
$this->assertEquals('k', $call->argument);
118+
$this->assertEquals(0, $call->hits);
119+
$this->assertEquals(0, $call->misses);
120+
$this->assertNotEmpty($call->start);
121+
$this->assertNotEmpty($call->end);
122+
}
123+
124+
public function testDeleteItems()
125+
{
126+
$pool = $this->createCachePool();
127+
$arg = array('k0', 'k1');
128+
$pool->deleteItems($arg);
129+
$calls = $pool->getCalls();
130+
$this->assertCount(1, $calls);
131+
132+
$call = $calls[0];
133+
$this->assertEquals('deleteItems', $call->name);
134+
$this->assertEquals($arg, $call->argument);
135+
$this->assertEquals(0, $call->hits);
136+
$this->assertEquals(0, $call->misses);
137+
$this->assertNotEmpty($call->start);
138+
$this->assertNotEmpty($call->end);
139+
}
140+
141+
public function testSave()
142+
{
143+
$pool = $this->createCachePool();
144+
$item = $pool->getItem('k')->set('foo');
145+
$pool->save($item);
146+
$calls = $pool->getCalls();
147+
$this->assertCount(2, $calls);
148+
149+
$call = $calls[1];
150+
$this->assertEquals('save', $call->name);
151+
$this->assertEquals($item, $call->argument);
152+
$this->assertEquals(0, $call->hits);
153+
$this->assertEquals(0, $call->misses);
154+
$this->assertNotEmpty($call->start);
155+
$this->assertNotEmpty($call->end);
156+
}
157+
158+
public function testSaveDeferred()
159+
{
160+
$pool = $this->createCachePool();
161+
$item = $pool->getItem('k')->set('foo');
162+
$pool->saveDeferred($item);
163+
$calls = $pool->getCalls();
164+
$this->assertCount(2, $calls);
165+
166+
$call = $calls[1];
167+
$this->assertEquals('saveDeferred', $call->name);
168+
$this->assertEquals($item, $call->argument);
169+
$this->assertEquals(0, $call->hits);
170+
$this->assertEquals(0, $call->misses);
171+
$this->assertNotEmpty($call->start);
172+
$this->assertNotEmpty($call->end);
173+
}
174+
175+
public function testCommit()
176+
{
177+
$pool = $this->createCachePool();
178+
$pool->commit();
179+
$calls = $pool->getCalls();
180+
$this->assertCount(1, $calls);
181+
182+
$call = $calls[0];
183+
$this->assertEquals('commit', $call->name);
184+
$this->assertNull(null, $call->argument);
185+
$this->assertEquals(0, $call->hits);
186+
$this->assertEquals(0, $call->misses);
187+
$this->assertNotEmpty($call->start);
188+
$this->assertNotEmpty($call->end);
189+
}
190+
}

0 commit comments

Comments
 (0)