Problem: If the DB is offline when this service is started, this service will not start as it fails inside this line: var container = new BootStrapper().Container;
on start.
private static void Main(string[] args)
{
Logger.Info("Engine Service is bootstrapping...");
AppDomain.CurrentDomain.UnhandledException += UncaughtExceptions.DomainException;
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
var container = new BootStrapper().Container;
var controller = container.Resolve<EngineController>();
ServiceBase.Run(controller.MainView as ServiceBase);
container.Dispose();
}
The reason it fails there is that it runs this code where it adds the nhibernate facility container.AddFacility<NHibernateFacility>();
and fails with a connection timeout.
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var isAutoTxFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is AutoTxFacility);
if (!isAutoTxFacilityRegistered) container.AddFacility<AutoTxFacility>();
container.Register(
Component.For<INHibernateInstaller>().ImplementedBy<CieFluentInstaller>().IsDefault().LifestyleTransient(),
Classes.FromThisAssembly().Pick().WithService.DefaultInterfaces().LifestyleTransient()
);
var isNHibernateFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is NHibernateFacility);
if (!isNHibernateFacilityRegistered) container.AddFacility<NHibernateFacility>();
}
If the windows service start up takes longer than 30 seconds (which it may if updates or backups are being conducted on the DB) the app service fails to start.
I'm using FluentNhibernate, NHibernate, Castle Windsor with NHibernateFacility.
Things I've tried:
Can't do it from the service start event because it fails before it gets to the view or controller. The view and controller have no direct access to the IoC container, only via an injected IoCFactory as per Castle Windsor recommendations.
I've tried to spawn a thread in the main and start it off there with a retry loop but because the service "waits" inside the ServiceBase.Run method, I can't seem to get the correct returns to make it "fake start" while in a retry loop.
Investigated lengthening the service start timeout, but can't access the servicebase/view since it fails before then and a system wide change at hundreds of production sites is not an option.
Question: How can I make it so that the windows service "starts" when DB is offline given the design?
Turned out to be a bug in NHibernate that prevented doing any of the above. Between Nibernate 2.0 and 3.0 you have to add the following to the NHibernate v3.0+ config (or in this case the FluentNHibernate):
cfg.SetProperty("hbm2ddl.keywords", "none");
This allows NHibernate to properly bootstrap itself and get to the controller now without error.