Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
Added cache data collector and profiler page#21065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
| $loaders =array_map(function ($loader) {returnnewReference($loader); },$config['loaders']); | ||
| $loaders =array_map(function ($loader) { | ||
| returnnewReference($loader); | ||
| },$config['loaders']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This change was from fabbot.io
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
you should revert them, fabbot is broken these days
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Okey, thank you
| $container->setParameter('templating.engines',$config['engines']); | ||
| $engines =array_map(function ($engine) {returnnewReference('templating.engine.'.$engine); },$config['engines']); | ||
| $engines =array_map(function ($engine) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This change was from fabbot.io
javiereguiluz commentedDec 27, 2016
@Nyholm thanks for this PR. Don't worry about the logo because the SensioLabs designer will take care of that. And same thing about the design, don't worry because we can iterate it later. Let's focus on the contents and the information provided. Thanks! |
Nyholm commentedDec 27, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
That is great. Then Im done with this PR =) ("Done" = "Waiting for community feedback") |
Koc commentedDec 27, 2016
It would be very useful collect this information also from production env and analyze it later. Can anybody idea how to make it possible without enabling whole profiler? |
Nyholm commentedDec 27, 2016
With the current implementation you should only load |
| * | ||
| * @return string | ||
| */ | ||
| privatefunctiongetValueRepresentation($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@Nyholm I'm not sure, but can't we use the VarDumper component here to print the value ? (BTW thanks a lot for this first collector, it's really nice!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Oh. That is a good idea. I'll see what I can do. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
the representation should be handled by the data collector, using the cloneVar method of the base DataCollector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I cannot use theDataCollector::cloneVar in this context. TheRecordingAdapter is not a data collector. However, I use thecloneVar once the data is moved to theCacheDataCollector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@Renrhaf I've updated the PR using your suggestion. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@Nyholm seems good to me ;) thank you !
| * | ||
| * @return object | ||
| */ | ||
| privatefunctiontimeCall($name,array$arguments =array()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
what about using a stopwatch instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Sure!
| * | ||
| * @param $call | ||
| */ | ||
| privatefunctionaddCall($call) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this function wrapper for a oneliner could be removed
| /** | ||
| * @author Tobias Nyholm <tobias.nyholm@gmail.com> | ||
| */ | ||
| interface RecordingAdapterInterface |
nicolas-grekasDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'd remove this interface entirely: we don't want a contract here, we need only a behavior (an implem)
| foreach ($callsas$call) { | ||
| $statistics[$name]['calls'] +=1; | ||
| $statistics[$name]['time'] +=$call->time; | ||
| if ($call->name ==='getItem') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
what about getItems?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thank you. If one do getItems(['a', 'b', 'c']). I will count that as 1 call and 3 reads.
| $result =$call->result; | ||
| $hits =0; | ||
| $items =array(); | ||
| foreach ($resultas$item) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
In the case of a generator, I see two issues here:
- this is consuming the generator. Since these are not rewindable,
return $result;returns a non usable generator. - this is couting hits, but maybe the app didn't consume the generator on its side.
This means I think we should have two code paths here: one for array (doing the same as the current code),
and one for Traversable, which should wrap this in a generator-closure, and do things lazily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I've wrapped the result in a generator closure as you suggested. I fail to understand we need a code path for arrays. I know that getItems will return something that you can do foreach with. Why can't I just always wrap it in a generator-closure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
no strong reason, good also via a generator
| * @author Aaron Scherer <aequasi@gmail.com> | ||
| * @author Tobias Nyholm <tobias.nyholm@gmail.com> | ||
| */ | ||
| finalclass RecordingAdapterimplements AdapterInterface |
nicolas-grekasDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Oh, I guess this should be named TraceableAdapter for consistency with the code base (eg TraceableUrlMatcher, etc.)
| * | ||
| * @return string | ||
| */ | ||
| privatefunctiongetValueRepresentation($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think we don't need this logic, let's just use$value directly.
The clone may fail (implem can throw in__clone), and is fragile (not recursive).
and for other types of data, we don't care (resources cannot come up from a cache pool)
removing also will make the layer slimmer, which is also a nice target
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Will do. Thank you.
| namespaceSymfony\Component\Cache\Adapter; | ||
| usePsr\Cache\CacheItemInterface; | ||
| usePsr\Cache\CacheItemPoolInterface; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
not used anymore (mybad)
| <?php | ||
| /* | ||
| * This file is part of php-cache\cache-bundle package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this is wrong
| /* | ||
| * This file is part of php-cache\cache-bundle package. | ||
| * | ||
| * (c) 2015-2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyholm <tobias.nyholm@gmail.com> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Symfony code must use the Symfony copyright
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Sorry, Copy/paste issue.. An my IDE does not show file headers. I will fix these
| {%blockhead %} | ||
| {{parent() }} | ||
| <style> | ||
| .color-red { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
would be better to include necessary styles in the CSS, to be usable for all collectors
| {{include('@WebProfiler/Icon/cache.svg') }} | ||
| </span> | ||
| <strong>Cache</strong> | ||
| <spanclass="count"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I don't think we should have the time here anymore, for consistency with other panels
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Do you want me to remove it?
| {%blockpanel %} | ||
| <h2>Cache</h2> | ||
| {%forname,callsincollector.calls %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It would be great to have the aggregated stats first as big numbers (as done in other panels), before having the detail for each pool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
no it is not done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
| $container->register($id.'.recorder', TraceableAdapter::class) | ||
| ->setDecoratedService($id) | ||
| ->addArgument(newReference($id.'.recorder.inner')) | ||
| ->addArgument(newReference('debug.stopwatch')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The implementation does not use Stopwatch
Nyholm commentedDec 28, 2016
xabbuh commentedDec 28, 2016
Just by looking at the screenshot I was not able to easily recognise what "ratio" refers to. Does it mean hits/reads? |
Nyholm commentedDec 28, 2016
Sorry about that. Yes, the ratio is the hits/reads ratio. See new screenshot: FYI: I created aseparate PR with the adapters. I added some tests and fixed some bugs in it. I will rebase this PR when/if#21082 gets merged. |
xabbuh commentedDec 28, 2016
I think I would change the label from "ratio" to "hits/reads" then. |
xabbuh commentedDec 28, 2016
And what about providing aggregated data across all pools? |
Nyholm commentedDec 28, 2016
I will.
That is only in the toolbar atm. |
ro0NL commentedDec 29, 2016
Nice :) What about a tab per pool? That should organize things right? The table with calls looks rather technical, so maybe we can improve that UX-wise.
👍 |
This PR was squashed before being merged into the 3.3-dev branch (closes#21082).Discussion----------[Cache] TraceableAdapter| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | Related to#21065| License | MIT| Doc PR | n/aI moved the TraceableAdapter to a separate PR and added some tests. I found a small bug which was fixed.Commits-------5cc4baf [Cache] TraceableAdapter
3e5b858 to7341375CompareNyholm commentedDec 29, 2016
Thank you@ro0NL. I agree with your comments that this could be improved and I really like your suggestions. I think this is "good enough" and I will let other PRs improve this. Does it sound reasonable? I've rebased this PR on master. |
| $statistics[$name]['misses'] +=$count -$call->misses; | ||
| }elseif ($call->name ==='hasItem') { | ||
| $statistics[$name]['reads'] +=1; | ||
| if ($call->result->getRawData()[0][0] ===false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This looks a bit ugly.
$call->result is aSymfony\Component\VarDumper\Cloner\Data. I know thathasItem will always return a boolean thanks to PSR-6. So I believe this is safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
No better way for now, I may work on something better soon but this is the way to go for now.
stof commentedJan 2, 2017
That's unfortunate, as it means that the main info displayed in the toolbar is not available anymore when looking at details. |
Nyholm commentedJan 3, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Ping@stof |
xabbuh commentedJan 3, 2017
@Nyholm Any reason not to aggregate missed and deletes? I would also change the order to be consistent with how it is for the cache pools. |
Nyholm commentedJan 3, 2017
rvanlaak commentedJan 3, 2017
We chain a From DX perspective it also would be great to have some kind of (javascript?) filtering in the panel, as that would allow you to instantly see the behavior path of a specific cache item. |
Nyholm commentedJan 12, 2017
Is there anything else I can do to help getting this PR merged? |
fabpot commentedJan 12, 2017
@Nyholm If you can rebase on current master, I can merge it :) |
nicolas-grekas commentedJan 12, 2017
👍 from me |
b9114b8 tod09bcf3CompareNyholm commentedJan 14, 2017
Thank you. The PR is rebased and tests are all green. |
fabpot commentedJan 18, 2017
Thank you@Nyholm. |
This PR was squashed before being merged into the 3.3-dev branch (closes#21065).Discussion----------Added cache data collector and profiler page| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#19297| License | MIT| Doc PR | n/aAdding a first version of cache profiler page. Most things are taken from PHP-cache.FYI:@aequasi### What is included?A collector, recording adapter and a profiler page.### What is not included?* A good logo* Nice design on the profiler pageThis PR aims to pass as the minimum requirement for a cache page. Im happy to do fancy extra features but those should be a different PR.Commits-------7497f1c Added cache data collector and profiler page
Nyholm commentedJan 18, 2017
Thank you for merging |
Renrhaf commentedJan 18, 2017
Many thanks@Nyholm :) |






Adding a first version of cache profiler page. Most things are taken from PHP-cache.
FYI:@aequasi
What is included?
A collector, recording adapter and a profiler page.
What is not included?
This PR aims to pass as the minimum requirement for a cache page. Im happy to do fancy extra features but those should be a different PR.