I'm using NServiceBus.Core v6.4.3
and NServiceBus.Heartbeat v2.0.0
I have a console application running as a Scheduled Task, it extracts data and send commands to an endpoint for processing.
The console application is configured as a SendOnly endpoint.
My code is as follows:
Main
// Local NServiceBus Configuration
var endpointConfiguration = EndpointConfiguration();
// Global NServiceBus & Ninject configuration
var conventions = new NServiceBusConventions();
conventions.Customize(endpointConfiguration);
// Create and start endpoint
var endpointInstance = await Endpoint.Start(endpointConfiguration).ConfigureAwait(false);
EndpointConfiguration
private static EndpointConfiguration EndpointConfiguration()
{
var configuration = new EndpointConfiguration("EndpointName");
// To ensure OctopusDeploy doesn't cause ServicePulse to think multiple services have been deployed
// http://docs.particular.net/nservicebus/hosting/override-hostid
configuration.UniquelyIdentifyRunningInstance()
.UsingNames("EndpointName", Environment.MachineName);
configuration.SendOnly();
return configuration;
}
Conventions
public class NServiceBusConventions
{
public IKernel Kernel;
public void Customize(EndpointConfiguration configuration)
{
// Custom Logging Factory implementation
LogManager.UseFactory(new NServiceBusTraceLoggerFactory());
Kernel = NinjectCommon.Start();
configuration.UseContainer<NinjectBuilder>(b => b.ExistingKernel(Kernel));
configuration.UsePersistence<NHibernatePersistence>();
configuration.UseSerialization<JsonSerializer>();
configuration.UseTransport<MsmqTransport>();
var transport = configuration.UseTransport<MsmqTransport>();
// Enabled by default in MsmqTransport, but to ensure we have it
transport.Transactions(TransportTransactionMode.TransactionScope);
configuration.DefineCriticalErrorAction(NServiceBusOnCriticalError.OnCriticalError);
configuration.EnableInstallers();
configuration.Conventions()
.DefiningCommandsAs(t => t.Namespace != null && t.Namespace.Equals("Contracts.Commands"))
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.Equals("Contracts.Interfaces.Events"));
configuration.AuditProcessedMessagesTo(ConfigurationManager.AppSettings["Messaging.NServiceBus.QueueNames.AuditQueue"]);
configuration.SendFailedMessagesTo(ConfigurationManager.AppSettings["Messaging.NServiceBus.QueueNames.ErrorQueue"]);
configuration.SendHeartbeatTo(ConfigurationManager.AppSettings["Messaging.NServiceBus.QueueNames.ServiceControlQueue"]);
var scanner = configuration.AssemblyScanner();
var excludeRegexs = new List<string>
{
@"DevExpress.*\.dll"
};
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
foreach (var fileName in Directory.EnumerateFiles(baseDirectory, "*.dll").Select(Path.GetFileName))
{
foreach (var pattern in excludeRegexs)
{
if (Regex.IsMatch(fileName, pattern, RegexOptions.IgnoreCase))
{
scanner.ExcludeAssemblies(fileName);
break;
}
}
}
}
}
Removing the configuration.SendOnly();
line in EndpointConfiguration
makes the endpoint appear in ServicePulse, but it doesn't appear otherwise.
I knew this was an issue in previous versions, but I thought this had been fixed in NServiceBus V5
.
I don't have to configure the endpoint as Send-Only, but I was just for completeness.
The reason behind the missing heartbeats was:
I have a console application running as a Scheduled Task, it extracts data and send commands to an endpoint for processing.
The process would start fresh each time and the time taken to extract data, process and send the commands was too short for NServiceBus to get the heartbeat messages sent.
Putting an await Task.Delay(10000)
at the end of the application was enough to allow NServiceBus to complete its necessary bootstrapping and didn't impact our SLA.
Thanks to Sean Farmar for his help in diagnosing