2016-12-28 17:44:10 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Cache\Adapter ;
use Psr\Cache\CacheItemInterface ;
2018-04-15 01:21:41 +01:00
use Symfony\Component\Cache\CacheItem ;
2017-09-15 21:03:33 +01:00
use Symfony\Component\Cache\PruneableInterface ;
use Symfony\Component\Cache\ResettableInterface ;
2018-08-01 09:02:13 +01:00
use Symfony\Contracts\Cache\CacheInterface ;
2018-07-13 18:06:58 +01:00
use Symfony\Contracts\Service\ResetInterface ;
2016-12-28 17:44:10 +00:00
/**
* An adapter that collects data about all cache calls .
*
* @ author Aaron Scherer < aequasi @ gmail . com >
* @ author Tobias Nyholm < tobias . nyholm @ gmail . com >
* @ author Nicolas Grekas < p @ tchwork . com >
*/
2018-04-15 01:21:41 +01:00
class TraceableAdapter implements AdapterInterface , CacheInterface , PruneableInterface , ResettableInterface
2016-12-28 17:44:10 +00:00
{
2017-05-30 13:30:58 +01:00
protected $pool ;
2016-12-28 17:44:10 +00:00
private $calls = array ();
public function __construct ( AdapterInterface $pool )
{
$this -> pool = $pool ;
}
2018-04-15 01:21:41 +01:00
/**
* { @ inheritdoc }
*/
2018-11-24 09:35:08 +00:00
public function get ( string $key , callable $callback , float $beta = null , array & $metadata = null )
2018-04-15 01:21:41 +01:00
{
if ( ! $this -> pool instanceof CacheInterface ) {
2018-07-26 09:59:12 +01:00
throw new \BadMethodCallException ( sprintf ( 'Cannot call "%s::get()": this class doesn\'t implement "%s".' , \get_class ( $this -> pool ), CacheInterface :: class ));
2018-04-15 01:21:41 +01:00
}
$isHit = true ;
$callback = function ( CacheItem $item ) use ( $callback , & $isHit ) {
$isHit = $item -> isHit ();
return $callback ( $item );
};
$event = $this -> start ( __FUNCTION__ );
try {
2018-11-24 09:35:08 +00:00
$value = $this -> pool -> get ( $key , $callback , $beta , $metadata );
2018-07-26 09:59:12 +01:00
$event -> result [ $key ] = \is_object ( $value ) ? \get_class ( $value ) : \gettype ( $value );
2018-04-15 01:21:41 +01:00
} finally {
$event -> end = microtime ( true );
}
if ( $isHit ) {
++ $event -> hits ;
} else {
++ $event -> misses ;
}
return $value ;
}
2016-12-28 17:44:10 +00:00
/**
* { @ inheritdoc }
*/
public function getItem ( $key )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
$item = $this -> pool -> getItem ( $key );
} finally {
$event -> end = microtime ( true );
}
2017-04-18 21:37:41 +01:00
if ( $event -> result [ $key ] = $item -> isHit ()) {
2016-12-28 17:44:10 +00:00
++ $event -> hits ;
} else {
++ $event -> misses ;
}
return $item ;
}
/**
* { @ inheritdoc }
*/
public function hasItem ( $key )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
2017-04-18 21:37:41 +01:00
return $event -> result [ $key ] = $this -> pool -> hasItem ( $key );
2016-12-28 17:44:10 +00:00
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function deleteItem ( $key )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
2017-04-18 21:37:41 +01:00
return $event -> result [ $key ] = $this -> pool -> deleteItem ( $key );
2016-12-28 17:44:10 +00:00
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function save ( CacheItemInterface $item )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
2017-04-18 21:37:41 +01:00
return $event -> result [ $item -> getKey ()] = $this -> pool -> save ( $item );
2016-12-28 17:44:10 +00:00
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function saveDeferred ( CacheItemInterface $item )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
2017-04-18 21:37:41 +01:00
return $event -> result [ $item -> getKey ()] = $this -> pool -> saveDeferred ( $item );
2016-12-28 17:44:10 +00:00
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function getItems ( array $keys = array ())
{
2017-05-31 12:48:12 +01:00
$event = $this -> start ( __FUNCTION__ );
2016-12-28 17:44:10 +00:00
try {
$result = $this -> pool -> getItems ( $keys );
} finally {
$event -> end = microtime ( true );
}
$f = function () use ( $result , $event ) {
$event -> result = array ();
foreach ( $result as $key => $item ) {
2017-04-18 21:37:41 +01:00
if ( $event -> result [ $key ] = $item -> isHit ()) {
2016-12-28 17:44:10 +00:00
++ $event -> hits ;
} else {
++ $event -> misses ;
}
yield $key => $item ;
}
};
return $f ();
}
/**
* { @ inheritdoc }
*/
public function clear ()
{
$event = $this -> start ( __FUNCTION__ );
try {
return $event -> result = $this -> pool -> clear ();
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function deleteItems ( array $keys )
{
2017-04-18 21:37:41 +01:00
$event = $this -> start ( __FUNCTION__ );
$event -> result [ 'keys' ] = $keys ;
2016-12-28 17:44:10 +00:00
try {
2017-04-18 21:37:41 +01:00
return $event -> result [ 'result' ] = $this -> pool -> deleteItems ( $keys );
2016-12-28 17:44:10 +00:00
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function commit ()
{
$event = $this -> start ( __FUNCTION__ );
try {
return $event -> result = $this -> pool -> commit ();
} finally {
$event -> end = microtime ( true );
}
}
2017-09-15 21:03:33 +01:00
/**
* { @ inheritdoc }
*/
public function prune ()
{
if ( ! $this -> pool instanceof PruneableInterface ) {
return false ;
}
$event = $this -> start ( __FUNCTION__ );
try {
return $event -> result = $this -> pool -> prune ();
} finally {
$event -> end = microtime ( true );
}
}
/**
* { @ inheritdoc }
*/
public function reset ()
{
2018-04-29 15:58:54 +01:00
if ( ! $this -> pool instanceof ResetInterface ) {
2017-09-15 21:03:33 +01:00
return ;
}
$event = $this -> start ( __FUNCTION__ );
try {
$this -> pool -> reset ();
} finally {
$event -> end = microtime ( true );
}
}
2018-10-03 21:46:29 +01:00
/**
* { @ inheritdoc }
*/
public function delete ( string $key ) : bool
{
$event = $this -> start ( __FUNCTION__ );
try {
return $event -> result [ $key ] = $this -> pool -> deleteItem ( $key );
} finally {
$event -> end = microtime ( true );
}
}
2016-12-28 17:44:10 +00:00
public function getCalls ()
{
2018-02-07 19:03:36 +00:00
return $this -> calls ;
}
public function clearCalls ()
{
$this -> calls = array ();
2016-12-28 17:44:10 +00:00
}
2017-05-30 13:30:58 +01:00
protected function start ( $name )
2016-12-28 17:44:10 +00:00
{
$this -> calls [] = $event = new TraceableAdapterEvent ();
$event -> name = $name ;
$event -> start = microtime ( true );
return $event ;
}
}
class TraceableAdapterEvent
{
public $name ;
public $start ;
public $end ;
public $result ;
public $hits = 0 ;
public $misses = 0 ;
}