Giter Club home page Giter Club logo

nservicebus.host's Introduction

NServiceBus.Host

The NServiceBus Host takes an opinionated approach to hosting. Endpoints using NServiceBus Host can run as windows services or console application (e.g. during development).

Documentation

Full documentation is available at the following location:

Source code prior to 6.0.0

This repository contains the source code for the NServiceBus.Host since version 6.0.0, versions prior to that aligned with the NServiceBus releases. Source code for versions prior to 6.0.0 is available in the https://github.com/Particular/NServiceBus repository.

Prior versions available in NServiceBus repository:

nservicebus.host's People

Contributors

adamralph avatar andreasohlund avatar awright18 avatar bording avatar colin-higgins avatar danielmarbach avatar davidboike avatar dbelcham avatar dependabot-preview[bot] avatar dependabot[bot] avatar heskandari avatar indualagarsamy avatar internalautomation[bot] avatar janovesk avatar johnsimons avatar jpalac avatar kbaley avatar kentdr avatar mauroservienti avatar mikeminutillo avatar particularbot avatar ramonsmits avatar seanfarmar avatar seanfeldman avatar simoncropp avatar soujay avatar szymonpobiega avatar timbussmann avatar williambza avatar wojcikmike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nservicebus.host's Issues

"Critical Time" and "SLA violation countdown" performance counters should be optional

Performance counters are now opt-in to avoid issues with setting them up preventing users from getting their endpoints to run in production

Breaking change

Previous versions enabled the performance counters Critical Time and SLA violation countdown by default. To get the same behavior with the 6.0 host you need to either:

  1. Use the profile NServiceBus.PerformanceCounters - More on profiles here
  2. Explicitly enable the counters in code using:
config.EnableCriticalTimePerformanceCounter();
config.EnableSLAPerformanceCounter();   

Problem

In v5.0 the default production profile enables by default "Critical Time" and "SLA violation countdown" performance counters.
Users cannot turn this off easily.

Make profiles more explicit in the arguments for validation

Profiles are currently supplied as arguments without any indication that they are actually profiles. Due to this reason we cannot verify if the given profile actually exists.

By changing the way profiles are specified we can verify that the profile actually exists.

Example:

NServiceBus.Host.exe /profile:NServiceBus.MSMQDistributor

NServiceBus.Host.exe /profile:NServiceBus.MSMQDistributor,NServiceBus.Lite

NServiceBus.Host.exe /profile:NServiceBus.MSMQDistributor /profile:NServiceBus.Lite

Make Host Process Testable

We should have the ability to end to end test the host.

It would be good to have some of the acceptance tests from core run within the host process.

SLAMonitoring crashes during initialization if more than one IConfigureThisEndpoint implementation is found

Issue by jjanuszkiewicz 12/10/2015 3:37:15 PM +00:00 Originally opened as Particular/NServiceBus#3197


In NServiceBus 5.2.11 my endpoint fails to start with the following error:

2015-12-10 10:58:36,175 [4] FATAL NServiceBus.GenericHost - Exception when starting endpoint.
System.InvalidOperationException: Sequence contains more than one matching element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at NServiceBus.Features.SLAMonitoring.TryGetSlaFromAttribute(FeatureConfigurationContext config, TimeSpan& sla) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Monitoring\SLA\SLAMonitoring.cs:line 56
   at NServiceBus.Features.SLAMonitoring.TryGetSLA(FeatureConfigurationContext context, TimeSpan& endpointSla) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Monitoring\SLA\SLAMonitoring.cs:line 46
   at NServiceBus.Features.SLAMonitoring.Setup(FeatureConfigurationContext context) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Monitoring\SLA\SLAMonitoring.cs:line 28
   at NServiceBus.Features.FeatureActivator.ActivateFeature(FeatureState featureState, IEnumerable`1 featuresToActivate, FeatureConfigurationContext context) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Features\FeatureActivator.cs:line 235
   at NServiceBus.Features.FeatureActivator.SetupFeatures(FeatureConfigurationContext context) in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Features\FeatureActivator.cs:line 116
   at NServiceBus.Configure.Initialize() in C:\BuildAgent\work\3206e2123f54fce4\src\NServiceBus.Core\Configure.cs:line 115
   at NServiceBus.GenericHost.PerformConfiguration(Action`1 moreConfiguration) in c:\BuildAgent\work\a3de8759ee491634\src\NServiceBus.Hosting.Windows\GenericHost.cs:line 119
   at NServiceBus.GenericHost.Start() in c:\BuildAgent\work\a3de8759ee491634\src\NServiceBus.Hosting.Windows\GenericHost.cs:line 58

The SLAMonitoring.cs:line 56 has this:

var configType = config.Settings
    .GetAvailableTypes()
    .SingleOrDefault(t => typeof(IConfigureThisEndpoint).IsAssignableFrom(t) && !t.IsInterface);

My endpoint has a IConfigureThisEndpoint implementation which inherits from a base (abstract) endpoint configuration class shared with other endpoints. It also has another (unused in this endpoint) IConfigureThisEndpoint implementation in one of the scanned assemblies, so there are in fact multiple IConfigureThisEndpoints in the scanned types, but only one is actually used (I use the NSB host and specify the correct EndpointConfigurationType in its config file).

I think this is a bug in NSB 5.2 and SLAMonitoring should not attempt to locate IConfigureThisEndpoint itself, rather it should use the one actually used in the endpoint. No other feature crashes due to the presence of multiple IConfigureThisEndpoints. Also, previous NSB version (4.6) did not crash like this, so this is a regression.

NServiceBus.Host32 assembly name

Raised by @mitch2014
Migrated from by Particular/NServiceBus#1917

It would be nice for 32-bit NServiceBus host assemlby ("NServiceBus.Host32") to have the same assembly name as the AnyCpu build ("NserviceBus.Host"). This makes it easier to use the same endpoint assemblies in both 32-bit and 64-bit processes. The output file name could remain "NServiceBus.Host32.exe" just as long as the assembly name of the x86 build is the same as the AnyCpu build.

Timebox the shutdown to prevent the windows service from hanging

At the moment we call "bus.Stop" syncronously. Since bus.Stop can hang indefinitely this means that we can't guarantee that the windows service will stop at all times. This behavior prevents service recovery to kick in and also confuses users that might belive that the service is running while its in a half stopped state.

I propose that we time box the shutdown and give up after lets say 30 seconds to allows the service to go down and be restarted.

There is a global flag that can be set (@gbiellem please add link) to tell the OS to always kill the service after a given time but since that is not on by default we should be safe and timebox instead. We should still add doco to highlight and recommend this flag.

The scannedassemblies cmd line arg should use file paths not assembly names

Raised by @johnsimons
Migrated from by Particular/NServiceBus#449

To supply the assemblies to scan via cmd line args, like this:

NServicebus.host.exe /installinfrastructure /scannedassemblies:"NServiceBus.dll;NServiceBus.Core.dll;NServiceBus.Host.exe" 

Instead of:

NServicebus.host.exe /installinfrastructure /scannedassemblies:"
NServiceBus, Version=3.2.0.0,Culture=neutral, PublicKeyToken=9fc386479f8a226c;
NServiceBus.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c;
NServiceBus.Host, Version=3.2.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c"

Obsolete IConfigureLogging in favour of IConfigureThisEndpoint constructor

As pointed out in #30, the best place to customise logging when using NServiceBus.Host is the constructor of the class that implements IConfigureThisEndpoint.
IConfigureLogging is called too late and does not provide a good hook to customise logging early enough.

Because of this, IConfigureLogging is now obsolete

Log the profile used for debugging purposes

This was raised by a user in the mailing list https://groups.google.com/d/msg/particularsoftware/zR1UVze5DSU/1nw6UC5xgYYJ

Original text:

I noticed recently that the log file generated for an NServiceBus host does not contain the profile used when starting that endpoint. It used to be at the top of the log file, just after it put the log file location.

I've tried switching my logging level all the different values but can't seem to get it to show up anymore.

This is especially important when running an endpoint with multiple profiles and doing debugging when you spelled a profile wrong and it doesn't start the endpoint with a profile you think is activated.

When debugging a NServiceBus.Host project it executes a main method from other project

Who's affected

  • Everyone using NServiceBus.Host and another project using TopShelf to host Windows Services.

Symptoms

When debugging a NServiceBus.Host project in VS2013 it looks for one static void Main(string[] args) and executes the first it finds, even in other projects (for instance the ones in Topshelf projects). The funny thing is that those other projects are not in the bin folder.

Steps to reproduce

  1. Debug TopShelf only hosted project
  2. Close the executable and stop the debugging session
  3. Debug the endpointlibrary hosted by NServiceBus.Host
  4. TopShelf hosted project gets debugged first before the endpoint library

As soon as you start debugging for example the Program.cs of the NServiceBus.Host the effect disappears.

Because when using the NServiceBus.Host there is no Program.cs but the endpoint is hosted in a console application, Visual Studio tries to search for another Program.cs in the same solution and starts the first found. This is clearly a Visual Studio bug which comes to play in combination with the NServiceBus.Host.

Workaround

This workaround applies to users of older versions of the Host.

  1. Rename your TopShelf Program.cs to Program2.cs or anything other than Program.cs

Decisions

  • Will not be back ported to older versions of the Host. Users using an older version can use the Workaround

Symbols for the host.exe can't be pushed to symbol source

Raised by @andreasohlund
Migrated from by Particular/NServiceBus#1646

Seems like we need to include the source for our ilmerge's as well :(

@johnsimons thoughts?

[push] Pushing NServiceBus.Host 4.1.0-Unstable0486 to 'https://nuget.symbolsource.org/MyGet/particular-unstable'...
[18:39:26][push] Failed to process request. 'Package submission failed: Source file c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ActivationException.cs not found in package. Source file is declared in NServiceBus.Host.pdb. . See http://www.symbolsource.org/Public/Home/Help for possible reasons. Fiddler may help diagnosing this error if your client discards attached detailed information.'.
[18:39:26][push] The remote server returned an error: (506) Package submission failed: Source file c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ActivationException.cs not found in package. Source file is declared in NServiceBus.Host.pdb. . See http://www.symbolsource.org/Public/Home/Help for possible reasons. Fiddler may help diagnosing this error if your client discards attached detailed information...
[18:39:26][push] Process exited with code 1

Expose information to the code, specially the windows service name

Hello,

In our project we are doing a custom messaging routing configuration that takes all the routing from database.
https://github.com/pablocastilla/NServiceBus-RoutingInDataBase

I would like to have public properties that would give me all the host information, specially the windows service name. That way I would be able to filter from service name instead from queue name. Some static class would be fantastic.

Maybe it already exists, but I have not been able to find it.

Thanks in advance.

Profiles what are they, how do we get there

Raised by @johnsimons
Migrated from by Particular/NServiceBus#1463

About a week ago I posted a simple question on the discussion list:

Profiles, does anyone uses them?

see original here

And the answers started coming ๐ŸŽ‚

Why did I raise this?

Mostly because I see profiles as just code that gets executed if present.
What I mean is that profiles can be replaced with drop-in assemblies, and as we know by default NServiceBus will scan all assemblies and execute the code.
So we could just have a LiteProfile.dll that is added to the bin folder in development, eg:

public class LiteProfile : INeedInitialization
{
    public void Init()
    {
        InMemoryPersistence.UseAsDefault();

        Configure.Instance.AsMasterNode();
        Configure.Instance.InMemoryFaultManagement();

        WindowsInstallerRunner.RunInstallers = true;
    }
}

The benefits I see with this approach:

  • More discoverable (they just files);
  • You can quickly see what "profiles" are being used (look at the file system) vs having to look in windows service properties:
    image
  • It also works for self hosting ๐Ÿ˜‰

Obviously this solution still has drawbacks

  • Order is unpredictable, so very hard to override a profile with another profile.
    This has actually been fixed in v4 so now, if you execute NServiceBus.Host.exe MyProfileA MyProfileB MyProfileC, the profile handlers are executed in order, MyProfileAHandler then MyProfileBHandler and finally MyProfileCHandler
  • You don't know what it does unless you look at the code (or name your files with a very long and descriptive name!)

Annoyances with profiles

If you ever decide to write your own profile, eg:

public class MyProfileA : IProfile
{

}

public class MyProfileAHandler : IHandleProfile<MyProfileA>
{
    public void ProfileActivated()
    {
        Console.Out.WriteLine("MyProfileA");
    }
}

This code will fail with the following exception:

System.Exception was unhandled by user code
  HResult=-2146233088
  Message=Could not find a class which implements 'IConfigureLogging'. If you've specified your own profile, try implementing 'IConfigureLoggingForProfile<T>' for your profile.
  Source=NServiceBus.Core
  StackTrace:
       at NServiceBus.Hosting.Profiles.ProfileManager.GetImplementor[T](Type openGenericType) in c:\Projects\NServiceBus\src\NServiceBus.Core\Hosting\Profiles\ProfileManager.cs:line 90
       at NServiceBus.Hosting.Profiles.ProfileManager.GetLoggingConfigurer() in c:\Projects\NServiceBus\src\NServiceBus.Core\Hosting\Profiles\ProfileManager.cs:line 63
       at NServiceBus.Hosting.GenericHost.PerformConfiguration() in c:\Projects\NServiceBus\src\NServiceBus.Core\Hosting\GenericHost.cs:line 72
       at NServiceBus.Hosting.GenericHost.Start() in c:\Projects\NServiceBus\src\NServiceBus.Core\Hosting\GenericHost.cs:line 27
       at NServiceBus.Hosting.Windows.WindowsHost.Start() in c:\Projects\NServiceBus\src\hosting\NServiceBus.Hosting.Windows\WindowsHost.cs:line 55
       at NServiceBus.Hosting.Windows.Program.<>c__DisplayClassd.<Main>b__5(WindowsHost service) in c:\Projects\NServiceBus\src\hosting\NServiceBus.Hosting.Windows\Program.cs:line 76
       at Topshelf.Internal.ControllerDelegates`1.StartActionObject(Object obj) in c:\Projects\TopShelfForNSB\src\Topshelf\Internal\ControllerDelegates.cs:line 18
       at Topshelf.Internal.IsolatedServiceControllerWrapper`1.<>c__DisplayClass2.<set_StartAction>b__1(TService service) in c:\Projects\TopShelfForNSB\src\Topshelf\Internal\IsolatedServiceControllerWrapper.cs:line 65
       at Topshelf.Internal.ServiceController`1.<.cctor>b__1(ServiceController`1 sc) in c:\Projects\TopShelfForNSB\src\Topshelf\Internal\ServiceController.cs:line 35
       at Magnum.StateMachine.LambdaAction`1.Execute(T instance, Event event, Object parameter) in :line 0
       at Magnum.StateMachine.EventActionList`1.Execute(T stateMachine, Event event, Object parameter) in :line 0
  InnerException: 

Why do I also need to implement IConfigureLoggingForProfile<MyProfileA> ?
It feels strange and unnecessary if I'm happy with the defaults.

Obsolete UsingTransport<T>()

Raised by @andreasohlund
Migrated from by Particular/NServiceBus#2272

In order to provide a single configuration api regardless of hosting model we should obsolete the UsingTransport<T> host specific config api and guide users to:

class MyEndpoint: IConfigureThisEndpoint
{
    public void Init(ConfigurationBuilder builder)
    {
        builder.UseTransport<RabbitMQ>();
    }
}

Old api:


class MyEndpoint: IConfigureThisEndpoint, UsingTransport<RabbitMQ>
{
    public void Init(ConfigurationBuilder builder)
    {

    }
}

Scannable Assembly Exclusions

Raised by @ianbattersby
Migrated from by Particular/NServiceBus#1256

I might be missing something here but when the Host.exe fires up it calls GetScannableAssemblies which doesn't take any notice of the default exclusions (in Configure.cs). I can appreciate that custom exclusions via AllAssemblies.Except won't be relevant at this point in the execution order but still the defaults would be nice.

Furthermore when GetScannableAssemblies is called and gets a BadImageFormatException the error message indicates this can be resolved by adding custom exclusions, which as said above I don't think will work, in this particular scenario/execution-order.

It would seem the general assembly scanning that goes on from the point you run the Host.exe seems over exhaustive and sub-optimal, especially when you are unfortunate enough to have unmanaged DLLs in the mix.

What happens in case of an unhandled exception?

https://groups.google.com/forum/#!topic/particularsoftware/cd9ulZ7SNo4

Product: NServiceBus.Host 6.0.0.0

The host failed unexpectedly while being idle, there are no errors in the log. There is user code that logs AppDomain.CurrentDomain.UnhandledException .

Last two messages on the text log:

2016-02-09 23:10:28.6412 DEBUG Polling for timeouts at 09/02/2016 23:10:28.
2016-02-09 23:10:29.1566 DEBUG Polling next retrieval is at 09/02/2016 23:11:29.

Event log:

Faulting application name: NServiceBus.Host.exe, version: 6.0.0.0, time stamp: 0x54734af4
Faulting module name: clr.dll, version: 4.6.81.0, time stamp: 0x5584e818
Exception code: 0xc00000fd
Fault offset: 0x0000000000068ad7
Faulting process id: 0x1be8
Faulting application start time: 0x01d160039f52621d
Faulting application path: E:\Applications\TradeIdeaManager\IdeaProcessor\NServiceBus.Host.exe
Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Report Id: 658a3307-cf82-11e5-80db-005056bba086
Faulting package full name:
Faulting package-relative application ID:

Is this because of TopShelf design or it's unrelated?

Topshelf/Topshelf#150
Topshelf/Topshelf#212

Thanks.

Initializing package on network share aborts execution

While writing a quick example I used the default location for the first time, which is on a network share. Initializing the package while the project is located on a network share throws an error on line 92 of the install.ps1 file
$writer = [System.Xml.XmlWriter]::Create($projectFilePath, $writerSettings)
My example location was:
\\abc.defg\private\home\username\visual studio 2013\Projects

IWantToRunWhenEndpointStartsAndStops Instance Scanning Discrimination

Depends on #64

Connects To: Particular/NServiceBus#3342

IWantToRunWhenEndpointStartsAndStops is being ported from Core to Host

There is currently no discrimination in the assembly scanning for instances registered through the EndpointConfiguration. This is existing behavior in core v5.

This means that there will be duplicates picked up after assembly scanning runs unless the user excludes those explicit types from assembly scanning.

Proposed fix:

            var startableStoppableInstances =
                context.Settings.GetOrDefault<List<IWantToRunWhenEndpointStartsAndStops>>()
                ?? new List<IWantToRunWhenEndpointStartsAndStops>();

            var typesToExclude = new HashSet<Type>(startableStoppableInstances.Select(i => i.GetType()));

            context.Settings.GetAvailableTypes()
                .Where(IsConcrete)
                .Where(IsIWantToRunWhenEndpointStartsAndStops)
                .Where(t => !typesToExclude.Contains(t))
                .ToList()
                .ForEach(t => context.Container.ConfigureComponent(t, DependencyLifecycle.InstancePerCall));

Installing the package fails due to missing powershell cmdlets

Taskforce: @andreasohlund, @weralabaj @bording @SeanFeldman

POA

  • Merge the pull
  • Update to latest core to get samples working (#75)
  • Merge #76 to prevent silent overwriting of an existing EndpointConfig.cs when upgrading
  • Smoke test an upgrade + a fresh install
  • Get confirmation from docs maintainers that no other doco needs to be changed

Doco & samples:

Exception

I tried to upgrade a Host based project from CoreV5 to CoreV6 using packages from MyGet, the Host upgrade (using 7.0.0-unstable0068) fails with the following error:

Executing script file 'C:\Repos\mauroservienti\NServiceBus.Samples\v6\packages\NServiceBus.Host.7.0.0-unstable0068\tools\install.ps1'...


IsDirty              : False
FileCount            : 1
Name                 : EndpointConfig.cs
Collection           : System.__ComObject
Properties           : System.__ComObject
DTE                  : System.__ComObject
Kind                 : {6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}
ProjectItems         : System.__ComObject
Object               : System.__ComObject
ExtenderNames        : {}
ExtenderCATID        : {610D4615-D0D5-11D2-8599-006097C68E81}
Saved                : True
ConfigurationManager : 
FileCodeModel        : System.__ComObject
Document             : 
SubProject           : 
ContainingProject    : System.__ComObject

Add-NServiceBusMessageForwardingInCaseOfFaultConfig : The term 'Add-NServiceBusMessageForwardingInCaseOfFaultConfig' 
is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, 
or if a path was included, verify that the path is correct and try again.
At C:\Repos\mauroservienti\NServiceBus.Samples\v6\packages\NServiceBus.Host.7.0.0-unstable0068\tools\install.ps1:99 
char:2
+     Add-NServiceBusMessageForwardingInCaseOfFaultConfig $project.Name
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   + CategoryInfo          : ObjectNotFound: (Add-NServiceBus...seOfFaultConfig:String) [], CommandNotFoundException
   + FullyQualifiedErrorId : CommandNotFoundException

Add-NServiceBusUnicastBusConfig : The term 'Add-NServiceBusUnicastBusConfig' is not recognized as the name of a 
cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify 
that the path is correct and try again.
At C:\Repos\mauroservienti\NServiceBus.Samples\v6\packages\NServiceBus.Host.7.0.0-unstable0068\tools\install.ps1:100 
char:2
+     Add-NServiceBusUnicastBusConfig $project.Name
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   + CategoryInfo          : ObjectNotFound: (Add-NServiceBusUnicastBusConfig:String) [], CommandNotFoundException
   + FullyQualifiedErrorId : CommandNotFoundException

To complicate things the error causes the EndpointConfig.cs file to be empty, deleting all my previous configurations.

Unhandled exceptions from other threads should be logged

While running NServiceBus.Host.exe version 4.2 I received the following entry in the event log:

Application: NServiceBus.Host.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: NHibernate.ADOException
Stack:
   at NHibernate.Connection.ConnectionProvider.CloseConnection(System.Data.IDbConnection)
   at NHibernate.Connection.DriverConnectionProvider.CloseConnection(System.Data.IDbConnection)
   at NHibernate.AdoNet.ConnectionManager.CloseConnection()
   at NHibernate.AdoNet.ConnectionManager.AfterTransaction()
   at NHibernate.Impl.SessionImpl.AfterTransactionCompletion(Boolean, NHibernate.ITransaction)
   at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory+DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Rollback(System.Transactions.Enlistment)
   at System.Transactions.Oletx.OletxVolatileEnlistment.Rollback()
   at System.Transactions.Oletx.OletxPhase0VolatileEnlistmentContainer.Aborted()
   at System.Transactions.Oletx.OutcomeEnlistment.InvokeOutcomeFunction(System.Transactions.TransactionStatus)
   at System.Transactions.Oletx.OletxTransactionManager.ShimNotificationCallback(System.Object, Boolean)
   at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)

Unfortunately this exception wasn't logged in host log so I don't know what was the message in exception. For now I have added the following code to log all unhandled exceptions - it would be nice if something similar was added to host:

public static Configure LogAppDomainUnhandledException(this Configure config)
{
    AppDomain.CurrentDomain.UnhandledException += ConfigurationExtensions.OnUnhandledException;

    return config;
}

private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    LogManager.GetLogger(typeof(AppDomain)).Fatal("Unhandled exception", e.ExceptionObject as Exception);
}

When adding more than one package with nuget it is very easy to "corrupt" the VS project

Raised by @mauroservienti
Migrated from by Particular/NServiceBus#2371

Steps to repoduce:

  • create an empty class library project;
  • add, via nuget, a reference to "NServiceBus.Host";
  • do not close the nuget dialog;
  • search for another package, whatever, e.g. "Radical", add a reference to it:
  • close the nuget dialog;

the following warning is shown by VS:

image

All the choices lead to a currupted VS project, the issue is, at least seems:

1 our powershell cmdlet modifies the project file to add the "Start external project" command to execute the Host;
2 the second reference modifies the the project file adding a new reference;

conflict. I suppose we should "save" the project after step 1.

Endpoint fails because of exceptions thrown when host scanning assemblies

Who's affected

  • Anyone that uses NServiceBus host and assembly redirects needed for essential assemblies

Symptoms

  • Self-hosted code stops to work when hosted with NServiceBus host.

Additional information

NServiceBus host is using EndpointTypeDeterminer to scan assemblies in order to find endpoint configuration. When it's doing so, AssemblyScanner can throw exception on assembly loading. When that happens, assembly is not included in scanned assemblies result. The list of scanned assemblies is passed later into endpoint`s appdomain for loading and the list will not contain any assemblies that failed loading during host startup. This can cause Endpoint to fail if excluded assembly was essential for endpoint.

Example: an assembly required a binding redirect that is added to endpoints app.config. When NSB host is scanning this assembly, it will not have the binding redirect innservicebus.host.exe.configand assembly will fail loading, therefore not passed into endpoints appdomain for loading. This will result in exception and failure to execute endpoint.

When failing, very difficult to trace why this is happening since exception is not logged anywhere in the host.

Related GH issue with details: https://github.com/Particular/NServiceBus.AzureBlobStorageDataBus/issues/6

Additional affected repos

https://github.com/Particular/NServiceBus.Host.AzureCloudService

Potential fix

Do not pass a list of scanned assemblies to the endpoint if exception were thrown. Similar to what's already done when running NSB host via command line

NServiceBus.Hosting.Profiles.IConfigureLogging not a proper alternative for the obsolete IWantCustomLogging

Problem

The interface NServiceBus.Hosting.Profiles.IConfigureLogging is not a proper alternative for the obsolete IWantCustomLogging interface. Implementing it does not work as its method is not called.

The 'solution' would be to use IConfigureLoggingForProfile<Production> but then you need to define a logging profile for each profile in use or use a alternative like explicitly mentioning a custom profile:

public class CustomLogging : IProfile {}

Also, using this still is not enough to initialize custom logging before logging is initialized by the host. The log file is created even though the custom logging profile is executed!

Solution / workaround

The current solution / workaround is using the constructor of the endpoint implementation of IConfigureThisEndpoint as it is executed earlier then IConfigureLoggingForProfile<Production> and calling NServiceBus.Logging.LogManager.Use<LoggingFactoryDefinition>(). Using this makes sure custom logging is initialized before the internal logging is started.

The current obsolete error message on IWantCustomLogging refers to a marker interface which does not result in a solution.

NServiceBus.IWantCustomLogging' is obsolete: 'Use the NServiceBus.Hosting.Profiles.IConfigureLogging interface which is contained with in the NServiceBus.Host nuget. Will be removed in version 6.0.0.'

Suggestions:

  • Add an Obsolete attribute to NServiceBus.Hosting.Profiles.IConfigureLogging that mentions to not use the interface.
  • Add the ability to setup logging before the host internal logging is executed althought the current endpoint constructor is 'early' enough but this could be a problem in the future if the host bootstrapping logic is changed.
  • Document that those interface should be implemented on seperated classes and not implemented on the endpoint class.

Refactor function TryGetEndpointConfigurationTypeFromScannedAssemblies

Raised by @indualagarsamy
Migrated from by Particular/NServiceBus#1786

Relates to #1785

This is the function from EndpointTypeDeterminer.cs

bool TryGetEndpointConfigurationTypeFromScannedAssemblies(out Type type)
{
    var endpoints = ScanAssembliesForEndpoints().ToList();
    if (!endpoints.Any())
    {
        Console.Out.WriteLine(assemblyScannerResults.FormattedErrors());
        type = null;
        return false;
    }

    AssertThatNotMoreThanOneEndpointIsDefined(endpoints);
    type = endpoints.First();
    return true;
}

As @SimonCropp puts it, this code is dodgy!

  1. In the case where we dont find an endpoint, all the errors are written out without any context. Before writing out the exceptions, there needs to be some context on what action was being performed.
  2. They are written to Console.Out instead of to the log!!!

Async all the way to the top

Currently GenericHost synchronously executes the async calls of NSB with GetAwaiter().GetResult() inside Start and Stop which are void methods. We should favour a design where we are async all the way to the top level of the call stack and only synchronise on the top level.

The host doesn't seem to honor config.AssembliesToScan if there are failures

Raised by @andreasohlund
Migrated from by Particular/NServiceBus#2383

When there are assemblies that fail to scan we blow up here because the scanner is set to throw:

https://github.com/Particular/NServiceBus/blob/master/src/NServiceBus.Core/Hosting/GenericHost.cs#L46

this means that even if the user excluded those failed asms

https://github.com/Particular/NServiceBus/blob/master/src/NServiceBus.Core/Hosting/GenericHost.cs#L181

the host won't start.

Misleading additional information for exception displayed in Visual Studio

Raised by @indualagarsamy
Migrated from by Particular/NServiceBus#1636

When an NServiceBus.Host project is started, and if it has a reference to a Messages dll, which uses a older version of NServiceBus, while the console displays correct information, the exception displayed in Visual Studio is misleading.

Steps to reproduce:

  1. Use any 4.x sample that has messages project which uses IMessage, ICommand or IEvent.
  2. Convert Server to use 4.1.0 and leave messages dll to be compiled usign 4.0.x.
  3. Start the Server

When starting the host, notice the VS exception additional info and the console host.

image

Shutdown enhancements

Branched off from #51
Intended for NServiceBus 6.x and NServiceBus.Host 7.x, not for milestone NSBv6

The purpose of this feature is not to influence the actual termination of the process, but more to educate developers what is happening and how to properly take actions.


On shutdown/reboot of the system there's a set amount of time a Windows Service has to gracefully shut down. Not much to do about it.

When shutting down manually with the MMC services snapin however, we have 125 seconds to shut down. After that, the service is marked is hanging and will likely never stop. We can influence this by requesting more time. More documentation can be found on MSDN.

Logging
We should provide better logging on what is happening. We need to log that we are trying to properly shut down and when we need more time of Windows. Perhaps x-amount of times before (we think) the service will actually be terminated by Windows.

When host is killed by Windows, non-transactional transports & persistence can loose messages and we should notify users that this might have happened.

When operations needs to kill the process, it's convenient when the process-id is in the log messages as well. We can inform inside the log this is the process to kill, if needed.

Requesting more time
We should decide if requesting more time is necessary or if it is better that the system notifies operations of a 'hanging' Windows Service. That way operations can be notified by monitoring systems and look at the logfiles what is actually happening.

The idea is that users are able to dump the process to disk and send it to us for debugging purposes. If a service is actually never gracefully shutting down, we might be on the a bug somewhere else and would very much like the information. It's also possible to include additional packages to log to Raygun, for example.

Registry access
We can read the amount of time we have from the registry in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control and the WaitToKillServiceTimeout value. We can set the GenericHost to a default amount of time and the WindowsHost is be able to modify this, according to registry setting. The available amount of time on system shutdown differs in different Windows versions. The reason for reading registry in WindowsHost is because we want to be able to support .NET Core in the future.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.