Friday, 30 September 2016

Options for exchanging information between domains

There are various approaches for exchanging information between domains in a system.

1. Fat Command, Subordinate System.
The system that holds the information commands a subordinate to do some work. In the command it provides all the information that it needs.
For example an Order Processing System may send a SendCustomerEmail command to a Notification system and that command holds all of the data deemed necessary to populate an email.
The recipient acts immediately upon the receipt of the command.

2. Fat Command, Thin Events
A system sends a command to a second system. That command contains all of the public information that is necessary for the execution of an action, for example SavePaymentCardDetails.
At some point in the future that system, or an unrelated system issues an event that triggers the execution of an action.
An example may be a front end Web application may preload a payment system with SavePaymentCardDetails. The payments domain saves the card details to it's domain repository. Later on the Fraud check system issues a FraudCheckPassed and the Payment domain then bills the credit card.

3. Thin Event, We'll Call You
In this scenario an event is published and the receiving system calls the Web API of the sender (or other systems) to get the information required to perform the action. For example, an Order Despatch system publishes the OrderDispatched event and the subscribing Customer Notification system calls the Order API to get the details of the order so it can send an email to the customer.

4. Fat events
In this scenario an event is published which contains the public information shareable with other domains. For example the OrderCreated event is published which contains the Line Items, Delivery Address, Billing Address etc.
There are cons to this approach:

  • You may be encouraged to publish information that want to hide (addresses)
  • You may not be able to restrict access to that information
  • An implicit coupling may be developed. You may get a whole number of subscribers to your events, some of whom you have no knowledge about, who become heavily dependent upon your events. You then struggle to upgrade or deprecate older versions of the message.

References
http://andreasohlund.net/2012/02/21/talk-putting-your-events-on-a-diet/
http://stackoverflow.com/questions/34545336/event-driven-architecture-and-structure-of-events



Tuesday, 20 September 2016

Changing a password on nested Remote Desktop Sessions

To change a password on a nested remote desktop session:

Start > Run > osk

Hold down the CTRL and ALT keys on the physical keyboard.

Click on the DEL button on the virtual keyboard.

Monday, 12 September 2016

MSMQ Utilities

List all of the private queues:
Get-MsmqQueue –QueueType Private | select QueueName

NServiceBus, "Failed to enlist in a transaction" and MSMQ overload.

We've had several problems, where after a serious fault in our infrastructure, NServiceBus on MSMQ has failed to start up gracefully. On many occasions, it would error for a period of anything up to several hours, before eventually unblocking itself and processing as normal.

The context of this is a very popular ecommerce site and NServiceBus is trying to process anything up to 40,000 queued messages after a period of downtime.

For background context - on two occasions this was total power failure in a commercial data centre, and the other one was due to a SAN disk failing, bringing down total throughput.

Our NServiceBus is on-premise and uses MSMQ as the underlying transport. Some endpoints use MSDTC and enlisted transactions. (As an aside, this is something you should be able to design out. Transactions are not particularly friendly to very distributed messaging systems. With a combination of idempotency, built-in MSMQ transactions and retries you can avoid the need for them).

One of the errors seen was "Cannot enlist the transaction". It is believed that the startup contention for MSMQ causes this. You can turn on MSDTC logging, and this requires the use of the TraceFmt.exe tool to format the logs for human consumption.

You can also turn on System.Transaction tracing.

Once we turned this on we could see repeated errors whereby a transaction was started and 2 minutes later it was aborted. This was happening continuously and causing NServiceBus to fail to startup. After a long period of time (an hour or more) one transaction managed to succesfully complete and this started to allow other messages to follow through.

Our team originally tried to solve this by increasing the MSDTC timeout duration. However this is not enough, underlying this is the System.Transactions timeout. This also needs to be changed.

<system.transactions>
  <defaultSettings timeout="00:05:00"/>
</system.transactions>

The solution is to perform one or more of the following:

  • wait
  • increase the transaction timeout
  • reduce the queue length if it is too big on startup by using a temporary queue and copying messages manually
  • remove the need for MSDTC
  • or fix the underlying performance problem that is hampering MSMQ.

Sunday, 4 September 2016

Publish a local SQL Server database to Azure

In SSMS 2014, select the database and click Tasks > Export Data-Tier Application.
You need to specify a storage account and the key for the account.
It will upload the bacpac to the storage account.

Then in the Azure Portal you can click on Import Database. Select the subscription and the storage account, find the bacpac and then complete the blade to recreate the database.

Visual Studio 2013 - publishing to a different Azure account

I have a work Azure account and a personal Azure account. When using the work Visual Studio 2013 if I try and publish a Web site to my personal Azure account the publish profile dialog shows my work account.

The Sign Out button doesn't work.

However there is a workaround. Go to Server Explorer and "Connect to Azure Subscription".
Enter the personal Azure account details and it will now connect to that.
From now on the publish dialog will use the personal credentials.