2014-04-15 22 views
6

Nancy'nin niçin yaklaşık 1 dakika talep kabul etmediğini görmek için uğraşıyorum. Yaklaşık 60 uç noktaya sahibim ve bunların hepsi çok hızlı bir şekilde başlatılıyor, böylece tüm modüller işleniyor. Bunun genel nedenleri var mıdır? Ya da neler olup bittiğini takip etmenin bir yolu var mı? UygulamanınNancy istekleri kabul etmeye başlamakta yavaş yavaş

DÜZENLEME

Günlüğü

App Start 4/15/2014 11:03:48 AM 
App Start Complete 4/15/2014 11:03:48 AM 
Bootstrap 4/15/2014 11:04:19 AM 
Module 3 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 2 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:37 AM 
Module 1 4/15/2014 11:06:38 AM 
Module 1 4/15/2014 11:06:38 AM 
Module 1 4/15/2014 11:06:38 AM 

olarak orada bootstrap önce bir gecikme olduğunu ve modüller denir da önce zamanlarda görülebilir başlatmak.

DÜZENLEME 2

Benim yapılandırma Web Formlar kullanılarak Nancy (güçlü anahtar kod değişiklikleri ile ihtiyaç vardı kaynağından inşa v0.22.2) ASP.NET 4.5 olduğunu. Visual Studio 2013'ü IDE ile kullanmak

+0

Kurulumunuzu anladığımdan emin değilim - 60 uç noktası ve tüm modüller başlatıldı ancak önyükleyici bunlardan sonra mı çağrılıyor? Ne? :) –

+0

@StevenRobbins Hatalı girişimi ekledikten sonra girişimi güncellemeyle ilgili ayrıntılarımı güncellemeye başlayacağım – Dreamwalker

+0

Yapılandırma ile ilgili sadece – Dreamwalker

cevap

9

Sorunun ne olduğunu buldum. Sorun, Nancy'nin kullandığı TinyIoC kapsayıcısından AutoRegister özelliğiyle ilgilidir.

Temel olarak başlangıçta (ilk istek), AppDomain öğenizin her derlemesini bağımlılıkları kaydettirecek şekilde tarar. Bu süreç çok yavaş: https://github.com/NancyFx/Nancy/wiki/Bootstrapping-nancy

Temelde sadece DefaultNancyAspNetBootstrapper devraldığı sizin ASPNet projede bir sınıf oluşturmak ve ConfigureApplicationContainer yöntemini geçersiz kılmak vardır: Burada belirtildiği gibi https://github.com/NancyFx/Nancy/issues/643

çözümü manuel bağımlılıkları kayıt şudur: Bu yardımcı olur

public class Bootstrapper : DefaultNancyAspNetBootstrapper 
{ 
    protected override void ConfigureApplicationContainer(TinyIoCContainer container) 
    { 
     // Register our app dependency as a normal singleton   

    } 
} 

Umut, Nancy AutoRegister özelliğinin yavaş performansı gösteren

+0

Merhaba geri bildirim için teşekkürler Bu bir – Dreamwalker

+1

deneyin Bu gerçekten büyük bağımlı derlemelerin bir sürü nedeni vardı. Süper duper mutlu yolu o kadar mutlu değildi;) – Dreamwalker

+0

Nancy harika. –

0

temel nedeni büyük montaj miktarı ve işlenen türler. İkinci konu bu dava için en uygun kod değildir. Nancy'nin mevcut kararlı sürümü (1.4.3) aşağıdaki kodlara sahiptir https://github.com/NancyFx/Nancy/blob/1.x-WorkingBranch/src/Nancy/TinyIoc/TinyIoC.cs#L3092-L3094 Sonuç olarak bu linq ifadesi her tür için işlenir ... Bu davranışı değiştirmek için Bootstrapper'ınız için aşağıdaki sınıfı kullanabilirsiniz. Ayrıca bu kodu, 3B parti meclislerinizi AutoRegisterIgnoredAssemblies içinde hariç tutabilirsiniz (koddaki örneğe bakınız).

Sistemimde otomatik kayıt hızını 50 saniyeden 95 saniyeye 521 kat artırmaya yardımcı oluyor.

public class AutoRegistredBootstrapper : DefaultNancyBootstrapper 
{ 
    private readonly object AutoRegisterLock = new object(); 
    private void AutoRegister(TinyIoCContainer container, IEnumerable<Assembly> assemblies) 
    { 
     var ignoreChecks = new List<Func<Type, bool>>() 
     { 
      t => t.FullName.StartsWith("System.", StringComparison.Ordinal), 
      t => t.FullName.StartsWith("Microsoft.", StringComparison.Ordinal), 
      t => t.IsPrimitive(), 
      t => (t.GetConstructors(BindingFlags.Instance | BindingFlags.Public).Length == 0) && !(t.IsInterface() || t.IsAbstract()), 
      t => t.Assembly == typeof(NancyEngine).Assembly 
     }; 


     lock (AutoRegisterLock) 
     { 
      var thisType = this.GetType(); 
      var types = assemblies.SelectMany(a => AssemblyExtensions.SafeGetTypes(a)) 
       .Where(type => (type.DeclaringType != thisType) 
           && !type.IsGenericTypeDefinition()) 
       .Where(t => !ignoreChecks.Any(check => check(t))) 
       .ToList(); 

      var assignebleTypes = 
       types.Where(
         type => 
          type.IsClass() && (type.IsAbstract() == false) && (type != thisType)) 
        .Select(t => 
        { 
         // be careful with side effects in linq 
         container.Register(t); 
         return t; 
        }) 
        .Where(implementationType => implementationType.GetTypeInfo().ImplementedInterfaces.Any() || implementationType.BaseType != typeof(Object)) 
        .ToList(); 

      var abstractInterfaceTypes = types.Where(type => ((type.IsInterface() || type.IsAbstract()))); 

      foreach (var abstractInterfaceType in abstractInterfaceTypes) 
      { 
       var localType = abstractInterfaceType; 
       var implementations = 
        assignebleTypes.Where(implementationType => localType.IsAssignableFrom(implementationType)).ToList(); 

       if (implementations.Count > 1) 
       { 
        if (implementations.Count != implementations.Distinct().Count()) 
        { 
         var fullNamesOfDuplicatedTypes = string.Join(",\n", 
          implementations.GroupBy(i => i).Where(j => j.Count() > 1).Select(j => j.Key.FullName)); 

         throw new ArgumentException($"types: The same implementation type cannot be specified multiple times for {abstractInterfaceType.FullName}\n\n{fullNamesOfDuplicatedTypes}"); 
        } 

        foreach (var implementationType in implementations) 
        { 
         container.Register(abstractInterfaceType, implementationType, implementationType.FullName); 
        } 

       } 

       var firstImplementation = implementations.FirstOrDefault(); 
       if (firstImplementation != null) 
       { 
        container.Register(abstractInterfaceType, firstImplementation); 
       } 
      } 
     } 
    } 

    protected override IEnumerable<Func<Assembly, bool>> AutoRegisterIgnoredAssemblies 
    { 
     get 
     { 
      return DefaultAutoRegisterIgnoredAssemblies.Concat(new Func<Assembly, bool>[] 
      { 
       asm => asm.FullName.StartsWith("ICSharpCode.", StringComparison.Ordinal), 
       asm => asm.FullName.StartsWith("Ionic.", StringComparison.Ordinal), 
       asm => asm.FullName.StartsWith("CommandLine,", StringComparison.Ordinal) 
       // ADD THE REST OF 3D party libs that you don't use as dependencies 
      }); 
     } 
    } 

    protected override void ConfigureApplicationContainer(TinyIoCContainer container) 
    { 
     var currentDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 

     var ignoredAssemblies = this.AutoRegisterIgnoredAssemblies.ToList(); 
     var asmsForProcessing = currentDomainAssemblies.Where(a => !ignoredAssemblies.Any(ia => ia(a))).ToList(); 

     AutoRegister(container, asmsForProcessing); 
    } 

}