castleproject / Windsor

Castle Windsor is a best of breed, mature Inversion of Control container available for .NET
http://www.castleproject.org
Apache License 2.0
1.51k stars 456 forks source link

Windows Performance Counters not working with scoped lifestyle #527

Open domenmali opened 4 years ago

domenmali commented 4 years ago

Hello guys,

I am using Castle Windsor 5.0.1 in my Asp.NET WebAPI project together with System Web facility to have 'PerWebRequest' lifestyle and for some reason, I'm not seeing anything on the Windows Performance Monitor chart.

In my Application_Start method I have:

var diagnostic = LifecycledComponentsReleasePolicy.GetTrackedComponentsDiagnostic(m_WindsorContainer.Kernel);
var counter = LifecycledComponentsReleasePolicy.GetTrackedComponentsPerformanceCounter(new PerformanceMetricsFactory());
m_WindsorContainer.Kernel.ReleasePolicy = new LifecycledComponentsReleasePolicy(diagnostic, counter);

and I have started the project as an admin. In the Windows Performance Monitor, I see the Castle Windsor category and I'm also able to select the counter, but nothing happens on the chart. image

Did I miss something?

Regards Domen

jonorossi commented 4 years ago

Could you set a breakpoint and have a look at the fields of the LifecycledComponentsReleasePolicy instance, specifically instance2Burden.

domenmali commented 4 years ago

image

jonorossi commented 4 years ago

At the point of that breakpoint are there singleton or scoped (i.e. per web request) components resolved that haven't been released? You can see that instance2Burden is empty, so it isn't tracking anything.

domenmali commented 4 years ago

Hm, I'm not sure. How/where can I see that?

jonorossi commented 4 years ago

Hm, I'm not sure. How/where can I see that?

The instance2Burden field will obviously be empty straight after the container is created (unless using startable facility). You need a breakpoint inside the running of your web application after components are resolved, otherwise it isn't tracking any instances to report via the performance counter.

domenmali commented 4 years ago

I've put the breakpoint after 'ServiceLocator.Current.GetInstance' call. So I think that at least one resolved but an unreleased component should be there.

image

jonorossi commented 4 years ago

Can you show the registration code for IRepository, the release policy won't track transients or singletons unless they are disposable.

Looking at the unit tests for this release policy we don't actually have unit tests for a scoped lifestyle so it is possible we've got a bug since per web request now uses the scoped lifestyle under the hood.

domenmali commented 4 years ago

Sure! here is the installer I'm using:

public class WindsorRepositoryInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IRepository>().ImplementedBy<Repository>().LifestylePerWebRequest());
    }
}

And Repository is disposable.

domenmali commented 4 years ago

FYI It's working if I change the IRepository lifestyle to 'LifestyleTransient'.

image

jonorossi commented 4 years ago

Thanks, indeed looks like a bug.

If you'd like to contribute a fix which would speed up getting a fix out, the first thing to do would be to add a failing unit test to LifecycledComponentsReleasePolicy for scoped lifestyle to determine why it isn't being tracked.

generik0 commented 3 years ago

@domenmali you are also welcome to provide a simple sample solution for replication.