Hi everyone. First, we are loving what MassTransit is providing for us on top of RabbitMQ. However, I am having an issue getting ServiceBusFactory.New()to complete when being hosted as a Windows Service. A bit of detail. We are using Autofac. MassTransit is loaded in as an Autofac Module as soon as Main() is executed and then everything is run within a single Autofac LifetimeScope. We are creating a single instance of IServiceBus with simple configurations from code. Here is our loading and the logging is purely to help track down the issue of where things are hanging. Development is Win7, production is 2008R2.builder.Register(c =>{var logger = c.Resolve<ILog>();logger.Info("MassModule: Load() ServiceBusFactory.New() starting.");var s = ServiceBusFactory.New(sb => this.ConfigureServiceBus(c, sb)); this call does not return every other time; it hangs and times out Windows SCM.logger.Info("MassModule: Load() ServiceBusFactory.New() done.");return s;}).As<IServiceBus>().SingleInstance();The call to this.ConfigureServiceBus() runs:private void ConfigureServiceBus([NotNull] IComponentContext context, [NotNull] ServiceBusConfigurator configurator){CodeContracts.VerifyNotNull(context, "context");CodeContracts.VerifyNotNull(configurator, "configurator");var logger = context.Resolve<ILog>();logger.Info(i => i("Service Bus: Starting service bus configuration at: {0}.", AppDomain.CurrentDomain.BaseDirectory));var massModuleSettings = context.Resolve<IAppSettings>().ToTyped<MassModuleSettings>();configurator.UseRabbitMq();configurator.SetPurgeOnStartup(massModuleSettings.PurgeOnStartup);// set application queue name.configurator.ReceiveFrom(massModuleSettings.ReceiveFrom);switch (massModuleSettings.MessageSerializer){case "binary":configurator.UseBinarySerializer();break;case "bson":configurator.UseBsonSerializer();break;case "json":configurator.UseJsonSerializer();break;case "xml":default:configurator.UseXmlSerializer();break;}logger.Info(string.Format("Service Bus: [{0}] receiving from [{1}] using [{2}] serialization. PurgeOnStartup: {3}",massModuleSettings.ServiceBusNetwork,massModuleSettings.ReceiveFrom,massModuleSettings.MessageSerializer,massModuleSettings.PurgeOnStartup));foreach (var setupServiceBus in context.Resolve<IEnumerable<ISetupServiceBus>>()){setupServiceBus.Setup(configurator);}logger.Info("Service Bus: Starting service bus configuration complete.");}When our host process starts, the Console application that is using TopShelf, the very first thing that happens is our Autofac container is built and the TopShelf service is configured. I have a single custom command line argument that dictates how the service starts. This must be extracted from the command line before TopShelf takes over and passed to the Container for proper setup and configuration. The parsing of the command line ahead of TopShelf is a little janky, I know.static void Main(string[] args){// AppDomain.CurrentDomain.FirstChanceException +=// (sender, eventArgs) => Console.WriteLine(eventArgs.Exception.ToString());// manually extract the supplied 'server' argument so it can be passed to GlobalContainer.var commandLineServerType = int.Parse(args.First().Split(new[] { '=' })[1]);using (var container = new GlobalContainer(commandLineServerType).Build()) Autofac Module for MassTransit is registered here creating IServiceBus{var settings = container.Resolve<SocketServerSettings>();HostFactory.Run(cfg =>{// register the custom command line option that dictates runtime server type.// this registration also prevents TopShelf from rejecting the argument and stopping.cfg.AddCommandLineDefinition("type", x => { /* do nothing */ });cfg.ApplyCommandLine();// configure the service class.cfg.Service<ServiceControl>(svc =>{svc.ConstructUsing(container.Resolve<ServiceControl>);svc.WhenStarted((service, hostControl) => service.Start(hostControl));svc.WhenStopped((service, hostControl) => service.Stop(hostControl));});// used for Windows Service installation.cfg.SetDescription(settings.Description);cfg.SetDisplayName(string.Format("Blah-{0}", settings.ServerName));cfg.SetServiceName(string.Format("Blah-{0}", settings.ServerName));// wait until the server is pretty much done starting before starting services.cfg.DependsOn("LanmanWorkstation");// initially configure the Windows Services to install using Local System account.// this should and will be changed post-deploy using a script.cfg.RunAsLocalSystem();});}}Within the Start() method of the ServiceControl class being used to host our TopShelf service:public bool Start(HostControl hostControl){hostControl.RequestAdditionalTime(TimeSpan.FromSeconds(15));this.SocketServer = this.LifetimeScope.Resolve<ISocketServer>();this.SocketServer.BindToIP = this.SocketServerSettings.IPAddress;this.SocketServer.BindToPort = this.SocketServerSettings.Port;this.SocketServer.Type = this.SocketServerSettings.Type;this.SocketServer.ServerName = this.SocketServerSettings.ServerName;new Task<bool>(this.SocketServer.Run).Start();return true;}There are no issues whatsoever when running as Console. Everything loads and starts within a second or so. When running as Windows Service, MassTransit has issues for some reason. This is really only occurring every other start of the service. Either it works or fails the first time and then it's every other start that works. I'm running the Windows Service as an administrator with full access to all local and network resources. Our RabbitMQ instances are hosted on Ubuntu server.I am using Octopus deploy for production and staging deployments. The only solution at the moment for my Powershell install scripts is to check for start failure and try again, which I really prefer not to have to do because that may be hiding a larger issue that needs dealing with. I have also verified my current directory is correct when the Windows Service loads. TopShelf is setting that properly.Any assistance would be greatly appreciated and I can provide more code and details if needed.Thanks!
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/Vctn242rJs0J.--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/oLjb9xdABWgJ.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsubscribe...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/Vctn242rJs0J.
--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/cAi3l9B3Dw8J.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/oLjb9xdABWgJ.
--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/98U65jTgqkoJ.
Oh, wow, I can't believe I missed this!All of the container setup, etc. should be done ENTIRELY in the ConstructUsing() method of the service, and not outside the Topshelf configuration. Otherwise, you can't be certain the service is actually ready to start doing things yet! You also won't get proper exception handling in the event of a broken container configuration or anything else.Yes, I realize some people may be "getting lucky" doing things before the service is constructed/started, but there are many command line options that do not actually create and/or start the service, so please defer that initialization until code that's actually inside the service configuration.
On Mon, Apr 1, 2013 at 1:12 PM, Anders Ljusberg <and...@gmail.com> wrote:
Sorry for jumping in a bit late but we had this very problem as well. Interesting to see that it's related to performance counters.Anyway, we found a work-around for it. If we delay creating the bus until the Start method, it all starts up nice every time./Anders
--
On Friday, March 22, 2013 10:42:22 PM UTC+1, Jesse Beard wrote:Github issue:Thanks!
Jesse
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
Oh, wow, I can't believe I missed this!All of the container setup, etc. should be done ENTIRELY in the ConstructUsing() method of the service, and not outside the Topshelf configuration. Otherwise, you can't be certain the service is actually ready to start doing things yet! You also won't get proper exception handling in the event of a broken container configuration or anything else.
public class ServiceStub : ServiceControl
{
private Thread _thread;
private IRealService _realServiceInstance;
public bool Start(HostControl hostControl)
{
_thread = new Thread(InternalStart);
_thread.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
_thread.Join();
_realServiceInstance.Stop();
// Other cleanup
return true;
}
private void InternalStart()
{
// Create IoC container and configure it.
// Use IoC container to resolve instance of IRealService and call its Start() method.
}
}
HostFactory.Run(x =>
{
x.Service<ServiceStub>();
// Any other TopShelf config here
});
Cheers,
Mehdi
Hi everyone. First, we are loving what MassTransit is providing for us on top of RabbitMQ. However, I am having an issue getting ServiceBusFactory.New()to complete when being hosted as a Windows Service. A bit of detail. We are using Autofac. MassTransit is loaded in as an Autofac Module as soon as Main() is executed and then everything is run within a single Autofac LifetimeScope. We are creating a single instance of IServiceBus with simple configurations from code. Here is our loading and the logging is purely to help track down the issue of where things are hanging. Development is Win7, production is 2008R2.
builder.Register(c =>{var logger = c.Resolve<ILog>();
logger.Info("MassModule: Load() ServiceBusFactory.New() starting.");var s = ServiceBusFactory.New(sb => this.ConfigureServiceBus(c, sb)); this call does not return every other time; it hangs and times out Windows SCM.
logger.Info("MassModule: Load() ServiceBusFactory.New() done.");
return s;}).As<IServiceBus>().SingleInstance();