elliotritchie / NES

.NET Event Sourcing
http://getnes.net
Other
129 stars 32 forks source link

Running NService bus host when having un-dispatched commits raise error (Object reference not set to an instance of an object) #20

Closed nour-s closed 10 years ago

nour-s commented 10 years ago

Hello, I'm getting (Object reference not set to an instance of an object). exception when there are un-dispatched commits in database, The error is because _eventPublisherFactory() failed to resolve the (IEventPublisher) interface, which I believe is because the start-up process is not yet completed and the interface is not registered yet,

Here is the stack trace:

NES.NEventStore.dll!NES.NEventStore.MessageDispatcher.Dispatch(NEventStore.Commit commit) Line 19   
    NEventStore.dll!NEventStore.Dispatcher.SynchronousDispatchScheduler.DispatchImmediately(NEventStore.Commit commit) Line 65  
    NEventStore.dll!NEventStore.Dispatcher.SynchronousDispatchScheduler.ScheduleDispatch(NEventStore.Commit commit) Line 32 
    NEventStore.dll!NEventStore.Dispatcher.SynchronousDispatchScheduler.Start() Line 54 
    NEventStore.dll!NEventStore.Dispatcher.SynchronousDispatchScheduler.SynchronousDispatchScheduler(NEventStore.Dispatcher.IDispatchCommits dispatcher, NEventStore.Persistence.IPersistStreams persistence) Line 21   
    NES.NEventStore.dll!NES.NEventStore.NESWireup..ctor.AnonymousMethod__1(NEventStore.NanoContainer c) Line 30 
    NEventStore.dll!NEventStore.NanoContainer.Register<NEventStore.Dispatcher.IScheduleDispatches>.AnonymousMethod__0(NEventStore.NanoContainer c) Line 18  
    NEventStore.dll!NEventStore.ContainerRegistration.Resolve(NEventStore.NanoContainer container) Line 99  
    NEventStore.dll!NEventStore.NanoContainer.Resolve<NEventStore.Dispatcher.IScheduleDispatches>() Line 48 
    NEventStore.dll!NEventStore.Wireup.BuildEventStore(NEventStore.NanoContainer context) Line 74   
    NEventStore.dll!NEventStore.NanoContainer.Register<NEventStore.IStoreEvents>.AnonymousMethod__0(NEventStore.NanoContainer c) Line 18    
    NEventStore.dll!NEventStore.ContainerRegistration.Resolve(NEventStore.NanoContainer container) Line 99  
    NEventStore.dll!NEventStore.NanoContainer.Resolve<NEventStore.IStoreEvents>() Line 48   
    NEventStore.dll!NEventStore.Wireup.Build() Line 67  
    NEventStore.dll!NEventStore.Wireup.Build() Line 64  
    NEventStore.dll!NEventStore.PersistenceWireup.Build() Line 78   
    NEventStore.dll!NEventStore.Wireup.Build() Line 64  
    NES.NEventStore.dll!NES.NEventStore.NESWireup.Build() Line 63   
    NEventStore.dll!NEventStore.Wireup.Build() Line 64  
    eClaim.NES.Host.dll!eClaim.NES.Host.EndpointConfig.Init() Line 39   
    NServiceBus.Core.dll!NServiceBus.Hosting.GenericHost.PerformConfiguration() Line 154    
    NServiceBus.Core.dll!NServiceBus.Hosting.GenericHost.Start() Line 69    
    NServiceBus.Host.exe!NServiceBus.Hosting.Windows.WindowsHost.Start() Line 53    
    NServiceBus.Host.exe!NServiceBus.Hosting.Windows.Program.Main.AnonymousMethod__5(NServiceBus.Hosting.Windows.WindowsHost service) Line 81   
    NServiceBus.Host.exe!Topshelf.Internal.ControllerDelegates<NServiceBus.Hosting.Windows.WindowsHost>.StartActionObject(object obj) Line 18   
    NServiceBus.Host.exe!Topshelf.Internal.IsolatedServiceControllerWrapper<NServiceBus.Hosting.Windows.WindowsHost>.set_StartAction.AnonymousMethod__1(NServiceBus.Hosting.Windows.WindowsHost service) Line 65    
    NServiceBus.Host.exe!Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>..cctor.AnonymousMethod__1(Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost> sc) Line 35    
    NServiceBus.Host.exe!Magnum.StateMachine.LambdaAction<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>>.Execute(Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost> instance, Magnum.StateMachine.Event event, object parameter)   Unknown
    NServiceBus.Host.exe!Magnum.StateMachine.EventActionList<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>>.Execute(Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost> stateMachine, Magnum.StateMachine.Event event, object parameter)    Unknown
    NServiceBus.Host.exe!Magnum.StateMachine.EventActionBase<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>>.Execute(Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost> instance, Magnum.StateMachine.Event event, object parameter)    Unknown
    NServiceBus.Host.exe!Magnum.StateMachine.State<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>>.RaiseEvent(Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost> instance, Magnum.StateMachine.BasicEvent<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>> eevent, object value)   Unknown
    NServiceBus.Host.exe!Magnum.StateMachine.StateMachine<Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>>.RaiseEvent(Magnum.StateMachine.Event raised)    Unknown
    NServiceBus.Host.exe!Topshelf.Internal.ServiceController<NServiceBus.Hosting.Windows.WindowsHost>.Start() Line 77   
    NServiceBus.Host.exe!Topshelf.Internal.IsolatedServiceControllerWrapper<NServiceBus.Hosting.Windows.WindowsHost>.Start() Line 40    
    NServiceBus.Host.exe!Topshelf.Internal.ServiceControllerProxy.Start() Line 47   
    [AppDomain (NServiceBus.Host.exe, #1) -> AppDomain (NServiceBus.Hosting.Windows.WindowsHost, NServiceBus.Host, Version=4.4.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c, #2)]  
    NServiceBus.Host.exe!Topshelf.Internal.FacadeToIsolatedServiceController<NServiceBus.Hosting.Windows.WindowsHost>.Start() Line 62   
    NServiceBus.Host.exe!Topshelf.Internal.ServiceCoordinator.Start() Line 48   
    NServiceBus.Host.exe!Topshelf.Internal.Hosts.ConsoleHost.Run() Line 53  Unknown
    NServiceBus.Host.exe!Topshelf.Internal.Actions.RunAsConsoleAction.Do(Topshelf.Configuration.IRunConfiguration configuration) Line 33    
    NServiceBus.Host.exe!Topshelf.Runner.Host(Topshelf.Configuration.IRunConfiguration configuration, string[] args) Line 70    
    NServiceBus.Host.exe!NServiceBus.Hosting.Windows.Program.Main(string[] args) Line 144   
elliotritchie commented 10 years ago

Hi Nour

That sounds correct. Do you have the NServiceBus configuration hook in place? e.g.

Configure.With()
  .Log4Net()
  .DefaultBuilder()
  .JsonSerializer()
  .NES(); // This line

Also if this is happening too late you can configure NServiceBus before you configure NEventStore.

nour-s commented 10 years ago

Hi, Actually my NServiceBus configuration is a bit different:

Configure.Transactions.Advanced(t => t.DefaultTimeout(new TimeSpan(0, 5, 0)));
Configure.Serialization.Json();
Configure.With()
                .Log4Net()
                .UnityBuilder(container)
                .UseTransport<Msmq>()
                .UnicastBus()
                .LoadMessageHandlers()
                .NES();

And this is my NES configuration:

Wireup.Init()
            .UsingSqlPersistence("EventStoreDB")
            .WithDialect(new MsSqlDialect())
            .InitializeStorageEngine()
            .NES()
            .UsingJsonSerialization()
            .Build();

However, I tried to configure NServiceBus before NES, but same error with the same stack trace occurred. Is it a bug? or I'm missing something?

elliotritchie commented 10 years ago

Thanks Nour, it sounds like a bug. Configuration of the commit dispatcher needs to be delayed until the bus has been started for un-dispatched events. I'll let you know asap when there's a fix.

nour-s commented 10 years ago

It is my pleasure, Is there a quick work-around? or at least a clue?

elliotritchie commented 10 years ago

Yeah this should work -

public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization, IWantToRunWhenBusStartsAndStops
{
    public void Init()
    {
        Configure.Transactions.Advanced(t => t.DefaultTimeout(new TimeSpan(0, 5, 0)));
        Configure.Serialization.Json();
        Configure.With()
            .Log4Net()
            .UnityBuilder(container)
            .UseTransport<Msmq>()
            .UnicastBus()
            .LoadMessageHandlers()
            .NES();
    }

    public void Start()
    {
        Wireup.Init()
            .UsingSqlPersistence("EventStoreDB")
            .WithDialect(new MsSqlDialect())
            .InitializeStorageEngine()
            .NES()
            .UsingJsonSerialization()
            .Build();
    }

    public void Stop()
    {
    }
}
elliotritchie commented 10 years ago

After looking through the latest NServiceBus source the above workaround actually looks like the recommended way of configuring services that depend on the bus. I'll also update the NES sample project with the same approach.

charlessolar commented 10 years ago

Doh! I spent the last few hours trying to figure out why NEventStore was throwing a null reference error! Moving Wireup to Start() fixed it right away

nour-s commented 10 years ago

@elliotritchie The approach you mentioned works fine for me, shall we close the issue?