Releases: Particular/NServiceBus
4.4.1
This release consist of these issues that were achieved through these commits.
Bugs
#1964 Failure to configure bus from command line application
I have a simple console application that configures a bus (MSMQ) and sends a single message. Between version 4.3.4 and 4.4.0 the application has stopped working with the exception in the stack trace below.
Note that this only happens when running from a command window. It does not happen when running from visual studio (using host process or not). In both cases I am running in a non-elevated context.
In case it is down to user error, here is the guts of the bus configuration code that is failing:
Configure.Serialization.Xml();
bus = Configure.With()
.Log4Net()
.DefaultBuilder()
Content trimmed. See full issue
Where to get it
You can download this release from:
4.4.0
This release consist of these issues that were achieved through these commits.
Before applying this release it is recommended that your read the release notes for 4.3.4 to check if the issue #1925 applies to you. #1925 When using NServiceBus version 4.3.x and an event is sent through a Distributor it is incorrectly received by multiple workers instead of just one.
Improvements
#1905 Add OriginatingHostId
and ProcessingHostId
headers that represent the current "host"
We currently have the ProcessingMachine
and OriginatingMachine
headers. These do not accurately reflect all concepts of a "Host". For example when hosting in Azure.
So the headers OriginatingHostId
, HostId
and HostDisplayName
have been added to be environment agnostic where "machine" does not make sense.
The headers ProcessingMachine
and OriginatingMachine
have been marked as obsolete and will be removed in 5.0.
#1872 Raise a critical exception if IWantToRunWhenBusStartsAndStops
Start
or Stop
throws an exception
Currently if the IWantToRunWhenBusStartsAndStops
methods Start
or Stop
throw an exception the endpoint still starts.
This can hides critical issues from the user.
We now raise a critical exception that will shutdown the bus.
#1627 Prefer TryGetValue instead of ContainsKey + Item lookups
So a ContainsKey
+ Item lookup takes approx twice as long as a TryGetValue
While this is a micro-optimization the correct approach, that uses TryGetValue
, is actually just as readable.
Bugs
#1902 A Stop
and Start
of the Bus causes a NullReferenceException
inside event subscriptions
#1889 Timeout messages can incorrectly end up in error queue after Bus restart
When the bus is restarted using Bus.Start()
, Bus.Shutdown()
then Bus.Start()
timeout messages can throw an exception and end up in the error queue.
If a saga message handler requests any timeouts, the message being handled is rolled back and always ends up in error queue.
#1888 Manual manipulating the Gateway Ack to be false
will result in a true
Ack
If a false
is passed in the Ack header AutoAck
will still be set to true
#1885 When self hosting messages are lost after IStartableBus.Shutdown()
followed with IStartableBus.Start()
When self hosting, all messages are lost after restarting the bus (ie calling Shutdown
followed by Start
on IStartableBus
.
Messages are removed from the queue but no handlers are called.
#1871 InMemory.Raise throws when using CastleWindsorBuilder
Due to the pipeline not wrapping InMemory.Raise
in a child container an exception can be thrown
InvalidOperationException: Scope was not available. Did you forget to call container.BeginScope()?
#1478 Remove hard coded 20 sec limit on IWantToRunWhenBusStartsAndStops.Stop
In v4 IWantToRunWhenBusStartsAndStops.Stop
is only allowed to run for a maximum of 20 seconds.
This limitation may not allow tasks to be completed successfully before shutting down the Windows service.
As such this timeout has been removed.
Where to get it
You can download this release from:
4.3.4
This release consist of these issues that were achieved through these commits.
Bugs
#1925 When using NServiceBus version 4.3.x and an event is sent through a Distributor it is incorrectly received by multiple workers instead of just one.
When using the distributor in version 4.3.x
, and the workers are subscribing to an event, having the message mapping for the event in the app.config of the worker causes each worker to handle the event, instead of just one worker.
If you are affected by this bug:
- Update your distributor/worker endpoints to the the 4.3.4 hotfix release.
- Inspect the current subscription entries for the publisher. Remove any extra subscription entries that are already registered for the workers for the event.
- Restart your endpoint.
How to delete your subscription entries when using RavenDB persistence:
1 Open the Raven Management Studio
Browse to your RavenDB url. if RavenDB is installed using the default ports the url is either http://servername:8080 or http://servername:8081, otherwise use the appropriate port number.
2 Find the correct database
Identify the database of the publisher endpoint (the database name matches the endpoint name) and double click to open the database.
3 Identify the subscription
You will see the subscriptions list. If there are multiple subscription documents, Identify the subscription document based on the event type. For example, Example.Messages.Events.MyEvent
as specified in the MessageType
column.
4 Delete the erroneous subscribers
Double click on the document to open the subscription list. Select the worker nodes that have been erroneously subscribed to the event and press delete.
Once the entries are removed, click on Save to save the document.
How to delete your subscription entries when using NHibernate persistence:
1 Find your Database in SQL Management Studio
Using Microsoft SQL Management Studio, connect to the appropriate persistence database specified in the NServiceBus/Persistence
connection string in the app.config of the endpoint
<connectionStrings>
<add name="NServiceBus/Persistence" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=NSERVICEBUS;Integrated Security=True" />
</connectionStrings>
2 Delete the erroneous subscribers
Find out the erroneous subscribers by running
select *
FROM [NServiceBus].[dbo].[Subscription]
where TypeName='Example.Messages.Events.MyEvent'
To clear out the subscriptions for the event Example.Messages.Events.MyEvent
, delete the subscription entries for the workers. For example:
delete
FROM [NServiceBus].[dbo].[Subscription]
where TypeName='Example.Messages.Events.MyEvent'
and SubscriberEndpoint in ('Example.NServiceBus.Worker@machine1', 'Example.NServiceBus.Worker@machine2')
Where to get it
You can download this release from:
4.3.3
This release consist of these issues that were achieved through these commits.
Bugs
#1910 V4.3 subscribers fail to subscribe to V3.X publishers
Version 4.3.0 introduced a bug where the NServiceBus.Version header didn't get populated for the control messages containing the subscribe/unsubscribe requests. This meant that our mutators didn't mutate them correctly causing the requests to be misinterpreted.
Affected transports: Msmq, SqlServer
Repro
- Clone this https://github.com/gbiellem/PubSubRepro
- Set as startup MyPublisher (3.3.8), Subscriber1 (4.3) and Subscriber2 (4.3)
- Start
- Press Enter in the publisher
- Message not received by subscribers
Content trimmed. See full issue
Where to get it
You can download this release from:
4.3.2
This release consist of these issues that were achieved through these commits.
Bugs
#1861 When using Azure ServiceBus, not passing in the endpoint address for subscriptions causes a null reference exception.
When we fixed issue #1837 in version 4.3.1
, a check was added to ignore the address count and call the SubscriptionManager.Subscribe
passing in null as the endpoint address for brokered transports with centralized pub sub support. While it works for ActiveMQ and RabbitMQ, the azure transport expects an address. Passing in null causes a NRE.
#1852 Read license from a version agnostic location, so that existing licenses need not be re-installed for newer releases
Our current way of handling licenses in the registry is wrong since it looks for a subkey containing the {major}.{minor}. This means that users that have installed a 4.2/4.3 license will have to reinstall it again for 4.4 even though the license it self is valid for 4.4
#1851 Bus failing to publish interface-defined event when messageConstructor not defined
When publishing using interface-defined events and when the messageConstructor not defined, an exception is thrown and the event is not published.
#1845 Remove Get-NServiceBusVersion commandlet
Get-NServiceBusVersion commandlet reported the version of NServiceBus.Powershell.dll
and not the version of the NSB within the solution. NServiceBus.Powershell dll has been separated from the core in order that it could be released independantly of the core if need be. This commandlet does not make sense, as we can have multiple endpoints referencing different versions of NServiceBus on the same machine.
Where to get it
You can download this release from:
4.3.1
This release consist of these issues that were achieved through these commits.
Hot fix release for 4.3.1
Bugs
#1841 Fix typo in the license dialog
The trial expiration dialog has a typo in the explanation text.
#1840 Trial expiry window no longer popping up when running in the emulator
In NSB 4.3 the trial expiry window is no longer popping up when running in the emulator, making the process hang and not allowing you to select a license either.
#1837 Invalid operation exception, when trying to auto subscribe to events when using Brokered transports
When using brokered transports that offer support for centralized pub/sub like RabbitMQ
and ActiveMQ
, the EndpointMappings
to specify event subscriptions are not needed. However, without it, an InvalidOperation exception was being thrown.
#1832 Saga is not started, when using a base class event to start the saga
When you specify a base event in the IAmStartedByMessages<T>
and a derived event is being published the saga does not start.
Where to get it
You can download this release from:
4.3.0
This release consist of these issues that were achieved through these commits.
Features
#1732 Support disconnecting workers from a running distributor
Add the ability to send a control message to the distributor telling it to disconnect a given worker. When a worker is disconnected no work will be sent to it and ready messages for that worker will be ignored until it reconnects with a new "worker-session-id".
Improvements
#1767 Obsolete UnicastBus.SkipDeserialization
Users should be writing satellites instead.
#1748 Exception rethrow reset stacktrace causing debugging difficulty
Exception patching is required before rethrowing
#1746 Schedule Reflection/ExtensionMethods for removal
To avoid polluting CLR types with our own convenience extension methods.
#1720 Simplify the license validation
To make it easier for users we should skip checking binary versions and instead do:
- Add release date into the binaries as an assmbly attribute
- Modify the check to:
if UpgradeProtectionExpiryDate>= Now OR UpgradeProtectionExpiryDate >= ReleaseDateOfBinaries => ok
#1709 Upgrade to Autofac 3.1.5
#1630 EncryptionMessageMutator is slow due to reflection
Bugs
#1822 ExpiryChecker.IsExpired doesn't work well with royalty free licenses
Royalty free license has an expiry date of 31/12/9999 12:00:00 AM
After adding the one day grace period, an OutOfRangeException
is thrown by ExpiryChecker.IsExpired
#1821 Request Response between sites is not finding the registered callback
Due to message CorrelationId
not being sent
#1820 Bus.Defer does not work when passed a date time with DateTime.Now.AddSeconds
Due to the use of local time instead of universal time.
#1819 When using unobtrusive mode, saga timeouts are triggered, it does not find the TimeoutHandlers and instead SagaNotFound handlers are invoked
Due to the static ExtensionMethods.CurrentMessageBeingHandled
not being correctly handled int he pipeline
#1818 NullReferenceException after enabling gateway without gatewayconfig in app.config
Due to a missing null check on GatewayConfig
#1813 Incorrectly shutting down of the pipeline
Causing ObjectDisposedException
#1810 Installing host throws exception
Due to incorrect Dispose order
#1801 Broke disabling and enabling message handling in UnicastBus.DisableMessageHandling
#1788 Bus.InMemory events now expect either unobtrusive conventions or IEvent interface markers
#1787 Headers not taken from correct location when doing an Bus.InMemory.Raise
#1759 Ilmerge not correctly updating pdbs
Caused difficulty debugging and stepping through NServicebus assemblies
#1752 Control Messages causing deserialization exception
Due to incorrectly attempting to deserialization them.
Will now skip deserialization and continue the pipeline.
#1737 MessageMapper.Initialize NullReferenceException due to incorrect treatment of generic types
If in the domain the following abstract class is defined, the bus will during the startup cause a NullReferenceException
#1690 Powershell Test-NServiceBusDTCInstallation incorrectly reports true on Windows 2003
Due to incorrect registry entry being checked
#1678 Stack corruption due to exception in 3rd party exception class
If a message handler throws an Exception
whose Message
property throws an Exception
then NServiceBus.Host.exe crashes with a corrupted stack. This causes the endpoint to crash.
#1652 Unable to subscribe for a base event from multiple publishers.
#978 Worker restarts can cause extra ready messages in the distributor storage
Where to get it
You can download this release from:
4.2.0
To see the full list of issues see Milestone 4.2.0.
To see the full list of commits see this compare.
Improvements
#1431 Better pipeline for the handler execution
Partially inspired by the Fubu Russian doll model the internal execution of handlers now takes a nested execution approach.
We refer to this nested approach referred to as a Chain
. Each step in this Chain
is referred to as a Behavior
.
So part of the chain would be
Start chain
invokes ApplyIncomingMessageMutatorsBehavior
invokes CallbackInvocationBehavior
invokes LoadHandlersBehavior
invokes SagaPersistenceBehavior
invokes InvokeHandlersBehavior
This allows each behavior to have control of
- What is executed before the nested behavior
- Optionally not invoke the nested behavior
- Handle exceptions that occur during the nested execution
- Optionally wrap the nested action in a transaction
- What is executed after the nested behavior
- Manipulate the data passed into and received from the nested behavior
Bugs
#1717 If persistence is disabled in the fluent configuration but persistence key is present in the config file, persistence is enabled
The logic should be disabled and give a warning that configs are not consistent.
Related to #1716
#1714 Lack of 32-bit host in NServiceBus.Host32 package
The NServiceBus.Host32
package 4.1.1 does not contain NServiceBus.Host32.exe
, but NServiceBus.Host.exe
The output from CorFlags
illustrates the issue
CLR Header: 2.5
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1
#1713 SagaPipeline - Saga is not started, when an event is published
#1712 Remove dependency T4
T4 Scaffolding are not adding much value. Also there are compatibility issues with Visual Studio 2013
#1708 Autofac 3.0.0 leaks memory
When child containers is used. Fix is to upgrade Autofac to 3.0.1
Rollback of Issue 397 (Nested lifetime scopes aren't disposed when the parent is disposed) due to memory leak.
#1699 Messages processed by the Gateway satellite are being forwarded to the audit queue causing duplicates in the audit queue.
#1687 Windows Server 2012 installing MSMQ using Powershell Cmdlet fails
Fails with the error
Error: 0x800f080c
Feature name MSMQ-Container is unknown.
A Windows feature name was not recognized.
Change to use the /all
option in DISM
on Server 2012
#1685 Powershell error when installing NServiceBus nuget package regarding registry key
Add a check to see if the key exists
#1642 Remove impersonation feature
Historically ImpersonateSender
was renamed to RunHandlersUnderIncomingPrincipal
as part of #1104.
However the new API adds little clarity.
Dissecting RunHandlersUnderIncomingPrincipal
gives the impression that "Handlers will be run under the principal of the user who sent the message"
When in reality all this API is about is "telling the handler who made the call" not anything to do with security or impersonation. It does this by setting Thread.CurrentPrincipal
to a fake principal containing the username of the user who sent the message. It extracts this username from the message headers. The handler code is free use use Thread.CurrentPrincipal
or to ignore. Either way all handler code will be run under the account the process is running as.
This API will be removed. If people want to access the sending user they can do so by using the message headers like they do for any other message metadata.
#1640 ReturnToSource does not recognize the Id in the message headers and does not return the message.
Fix so that ReturnToSource is backwards compatible with earlier versions
#1629 TimeToBeReceivedAttribute.TimeToBeReceived should not be optional
TimeToBeReceivedAttribute
has an empty constructor and hence TimeToBeReceived
is optional. This should not be the case. The empty constructor should be obsoleted and then removed.
#1337 upgrade to Castle Windsor 3.2.1 to fix scoping lifetimes when used in Azure
From the Castle Windsor Release Notes
It fixes a problem some users encountered, when CallContext scoped lifestyle is used in certain cross-AppDomain contexts. It specifically affected users of some testing framework or NServiceBus when deployed to Azure. The bug would manifest itself with the following exception:
SerializationException — Type is not resolved for member
“Castle.MicroKernel.Lifestyle.Scoped.CallContextLifetimeScope+SerializationReference,
Castle.Windsor, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc”
Where to get it
You can download this release from:
4.1.1
To see the full list of commits for this release click here.
This release is fully backwards with previous v4 releases.
This affects only users that do not have .NET v4.5 installed.
Most critical bug fixes in this release
- [#1693] NServiceBus v4.1.0 throws "Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib'", when .NET v4.5 is not installed, see http://stackoverflow.com/questions/13748055/could-not-load-type-system-runtime-compilerservices-extensionattribute-from-as
Where to get it
You can download this release from:
4.1.0
To see the full list of commits for this release click here.
This release is fully backwards with previous v4 releases.
If you are affected by any of the issues listed below we recommend you upgrade.
Known issues
- [#1687] Windows Server 2012 installing MSMQ using Powershell Cmdlet fails.
When using the Install-NServiceBusMSMQ
on Windows Server 2012 the command will fail with the error Feature name MSMQ-Container is unknown.
. The workaround is to run the following command manually
dism /Online /NoRestart /English /Enable-Feature /all /FeatureName:MSMQ-Server
The fix for this issue is scheduled for the 4.2 release.
New Features Overview
-
[#1362] @SimonCropp did major work to ensure we are disposing of everything that needs to be disposed, we using the awesome Janitor to helps us out 👍
-
[#718, #1230, #1392] The Gateway received quite a few improvements courtesy of @chrisbednarski, here is an overview:
The need for ACK calls has been removed altogether.
In 4.0 each message requires at least 2 HTTP calls, message body + ACK (the ACKs are required in case Databus properties are transferred after the message body).
In 4.1 the Databus properties are sent before the message body, so the need for ACKs has been removed.Since there is no need for ACKs, the persistence doesn't have to temporarily store the entire message + headers
In 4.0 the message body is retrieved from the persistence store during the ACK.
In 4.1 the only thing that gets stored in the deduplication store is the stable message id + datetime received.To enable this new features
Set
LegacyMode="false"
in app.config, example:<GatewayConfig> <Sites> <Site Key="SiteA" Address="http://localhost:25899/SiteA/" ChannelType="Http" /> <!-- Legacy mode means that messages sent to SiteB as well as any replies from SiteB back to Headquarter will use the new forwarder (IForwardMessagesToSites), legacy mode is enabled by default so we are compatible with endpoints prior to v4.1 --> <Site Key="SiteB" Address="http://localhost:25899/SiteB/" ChannelType="Http" LegacyMode="false"/> </Sites> <Channels> <Channel Address="http://localhost:25899/Headquarter/" ChannelType="Http" /> <!-- The default channel is the channel that will be set as return address. This means that any replies will come back on this channel--> <Channel Address="http://localhost:25899/Headquarter2/" ChannelType="Http" Default="true"/> </Channels> </GatewayConfig>
-
[#1308] NServiceBus.Powershell.dll is now in nuget 😄, thanks @chrisbednarski;
-
[#1036] Allow specifying handlers order without using
First<T>
, you can now specify handlers order in a much cleaner way 😄, here is an example:class MyOrder : ISpecifyMessageHandlerOrdering { public void SpecifyOrder(Order order) { order.Specify(new[] { typeof(FirstHandler), typeof(SecondHandler) }); } }
Thanks @nbarnwell for the PR
-
[#1476] New overload for Configure.Component, thanks @chrisbednarski for the PR
-
[#1309] Introduce a way to disable audit.
In v4 we made Audit On by default, and there was no way to disable it (or at least no easy way!).
To disable Audit, add the following to your EndpointConfig file:Configure.Features.Disable<Audit>();
-
[#1339] Auditing is now a first level concept.
Prior to this release a way to enable auditing of messages was to configure forwarding of messages viaForwardReceivedMessagesTo
attribute, eg:<UnicastBusConfig ForwardReceivedMessagesTo="audit"/>
Now in this release we introduce a new configuration section:<AuditConfig QueueName="The address to which messages received will be forwarded." OverrideTimeToBeReceived="The time to be received set on forwarded messages, specified as a timespan see http://msdn.microsoft.com/en-us/library/vstudio/se73z7b9.aspx" />
And if you want to quickly update your config files to use the new way use the following cmdlet:
PM> Add-NServiceBusAuditConfig
-
[#1342] Introducing a way to control lock modes when using the NHibernate saga persister.
This change makes the defaultLockMode
UpdateLock
and allows to be specified as part of the Saga data class, here is an example:[LockMode(LockModes.UpgradeNoWait)] public class SagaData : ContainSagaData { [Unique] public virtual int Number { get; set; } public virtual int NumCalls { get; set; } }
-
[#1524] Improvements in the assembly scanner, @mookid8000 (our new family member) has done major work in the assembly scanner;
-
[#1599] Performance improvement in MSMQ transport message receiving;
Most critical bug fixes in this release
- [#1405] Combination of Costura and Aspose can cause infinite loop, thanks @thirkcircus for reporting and helping us testing the fix;
- [#1492] Unit Tests fail with ConfigurationErrorsException, thanks @chrisbednarski for PR;
- [#1481] When using DataBus with multiple subscribers that share the same storage causes exception;
- [#1384] Use Configure.GetConfigSection for Gateway like other IProvideConfig. thanks @michaelnoonan for the PR;
- [#1470] NSB checks RavenDB version for testing, thanks @agross for reporting this issue;
- [#1549] Not supporting generic message handlers, thanks @tkristiansen for reporting this issue;
- [#1483] If a Satellite fails to start shouldn't the whole endpoint be considered as failed to start, thanks @michaelnoonan for reporting this issue;
- [#652] Username command line argument not used when assigning queue permissions;
- [#1512] Deadlocks occur on timeout table and index on endpoint incomplete, thanks @ramonsmits for reporting and providing us with a PR;
- [#1640] ReturnToSource does not recognize the Id in the message headers and does not return the message;
Obsoleted APIs in this release
-
[#1334] RecoverableAttribute has been obsoleted as recoverable is now the default;
-
[#1402] The
IBus
batch messaging APIs have been obsoleted.
This includes the following:ICallback SendLocal(params object[] messages); void Publish<T>(params T[] messages); ICallback Send(params object[] messages); ICallback Send(string destination, params object[] messages); ICallback Send(Address address, params object[] messages); ICallback Send(string destination, string correlationId, params object[] messages); ICallback Send(Address address, string correlationId, params object[] messages); ICallback SendToSites(IEnumerable<string> siteKeys, params object[] messages); ICallback Defer(TimeSpan delay, params object[] messages); ICallback Defer(DateTime processAt, params object[] messages); void Reply(params object[] messages); ICallback SendToSites(IEnumerable<string> siteKeys, params object[] messages);
They will be removed in a version 5.0 of NServiceBus.
Reasons
There are several reasons for this change.
Confusing API
The general perception of these APIs that it was "a way to send multiple messages to a specified destination". Where the behaviour is actually "send all the specified message in a single payload and within a single transaction". This may seem like a semantic difference but it actually a significant difference in behaviour. The reason is that if it was just a simple "send multiple messages" then each message would be handled individually, including message failure. But the "single transaction" behaviour means if the a message fails then all messages will be considered failed an rolled back.
Message Headers
Several features within NServiceBus rely on the usage of message headers. It is also a valuable extensibility point for adding features to NServiceBus. Unfortunately the concept of message headers is incompatible with a batch approach to sending messages. Significant complexity is currently in place to work around most of this incompatibility but is is not a viable approach moving forward.
Still want to send multiple messages
Many people may have actually been using this API as a simple "way to send multiple messages to a specified destination" and have suffered no problems with the "single transaction" behaviour. If you want to continue using this API for convenience but have messages handled in separate transactions you can write some simple extension methods for
IBus
to enable this. For example:public static class BusExtensions { public static void MultiSend(this IBus bus, Address address, params object[] messages) { foreach (var message in messages) { bus.Send(address, message); } } }
Where to get it
You can download this release from: