Wednesday 28 December 2016

Beyond Compare with TFS

The article describing how to compare various Version Control Systems with BeyondCompare is here.

TEAM FOUNDATION SERVER (TFS)

Diff

  1. In Visual Studio Choose Options from the Tools menu.
  2. Expand Source Control in the treeview.
  3. Click Visual Studio Team Foundation Server in the treeview.
  4. Click the Configure User Tools button.
  5. Click the Add button.
  6. Enter ".*" in the Extension edit.
  7. Choose Compare in the Operation combobox.
  8. Enter the path to BComp.exe in the Command edit.
  9. In the Arguments edit, use:
    %1 %2 /title1=%6 /title2=%7

3-way Merge Pro only

  1. Follow steps 1-6 above.
  2. Choose Merge in the Operation combobox.
  3. Enter the path to BComp.exe in the Command edit.
  4. In the Arguments edit, use:
    %1 %2 %3 %4 /title1=%6 /title2=%7 /title3=%8 /title4=%9

2-way Merge

Use the same steps as the 3-way merge above, but use the command line:
%1 %2 /savetarget=%4 /title1=%6 /title2=%7

Monday 19 December 2016

Device Manager driver update gets stuck at "Searching Online for Software"

https://answers.microsoft.com/en-us/windows/forum/windows_8-update/windows-update-not-updating-stuck-on-checking/da51ddbc-40ff-4ed9-b2a7-9381843728a1

Wednesday 14 December 2016

Event Store - my learnings

I have been evaluating Event Store and thought I'd write my learnings. The context is based upon an Order Processing system, which receives Orders (OrderCreated) and processes them through their lifecycle.

 1. Hard deletes are really hard! If you are testing and creating streams and deleting them, if you do a hard delete you really CANNOT recreate a stream. Of course, this is not a natural thing to do in a real world environment, but beware if playing around. The only way to get around it is to use a new DB. 

2. The browser window does a lot of caching. I (soft) deleted a stream and then went back to the Stream Browser window. It still displayed the stream I deleted and when I clicked through it displayed the events within the stream. This led me to hard delete it which caused other problems. In reality, the browser is caching all the information. Either use Developer Tools to clear the cache or use the API: the stream HAS been deleted.

3. When modifying a projection, reset it. I had errors when I modified a projection and didn't reset it. 

4. Consistency is guaranteed within a stream, not across them. If in pseudocode you write:

for (var i=1; i<6; i++)
{
    CreateStream(i);
}
you will not necessarily see 5,4,3,2,1 in the Most Recently Created Streams and projections upon the Streams will be sequenced accordingly.
This is because the parallelism of the writes means that any that were initiated at almost identical times will be written to the log as each task completes. If you were to add a small sleep in the for loop you would see them being sequenced in the same order as the API calls.

Remember, consistency is guaranteed WITHIN a stream, not ACROSS a stream. Events within a stream will be written in the sequence that they are received.

This consistency guarantee may help you decide how to arrange your streams. If my stream was AllOrderEvents, and it contained all of the events for all of the orders, then this may incur a performance hit as concurrent writers will all be trying to write into one log for all orders and they may get version conflicts. We don't care about the exact sequencing of one order to another, but we do care about the sequencing of events within an order.

Furthermore, remember that in a distributed event-driven system, we should not rely upon Message Ordering. Some message buses may provide ordered messaging, but they will do this at a cost to performance and storage.

Event Store - the fromCategory projection does not work / does not project

I wrote a projection to enumerate all streams beginning "Order" and pull out how many orders were created (by having the event OrderCreated in their stream). This was a simple way of building up a projection of orders in the system.

fromCategory("Order")
    .foreachStream()
   .when({
        $init: function() {
           return { count: 0 }
        },
        "OrderCreated": function(state, event) {
          emit('newOrders', 'order', { 'orderReference' : '1' })
        }
  })


And for love nor money I could not get this to work.

In the end this answer steered me: you have to config EventStore not only to run projections but also to start the standard projections.
EventStore.ClusterNode.exe --run-projections=all --start-standard-projections=true

Saturday 10 December 2016

Unturned: Running a Console Application with arguments as a Windows Service

Unturned requires you to run a console application as a server.
If you want to start this automatically when a Windows Server restarts without any GUI interaction then it is necessary to run it as a Windows Service.

I tried a couple of tools and found that nssm.exe worked best. It allows you to specify a Console.exe and include startup parameters.
Other tools such as RunAsService could not handle the fact that the service did not respond in a timely fashion to the Service Control Manager.

Wednesday 7 December 2016

Fat vs thin events

StackOverflow has a good article discussing the pros and cons of fat vs thin events. I thought I'd repeat it here.

The question raised was:

"When raising an event, which pattern is the most suited:
  1. Name the event "CustomerUpdate" and include all information (updated or not) about the customer
  2. Name the event "CustomerUpdate" and include only information that have really been updated
  3. Name the event "CustomerUpdate" and include minimum information (Identifier) and/or a URI to let the consumer retrieves information about this Customer.
I ask the question because some of our events could be heavy and frequent."
And the response was:
Name the event "CustomerUpdate"
First let's start with your event name. The purpose of an event is to describe something which has already happened. This is different from a command, which is to issue an instruction for something yet to happen.
Your event name "CustomerUpdate" sounds ambiguous in this respect, as it could be describing something in the past or something in the future.
CustomerUpdated would be better, but even then, Updated is another ambiguous term and is nonspecific in a business context. Why was the customer updated in this instance? Was it because they changed their payment details? Moved home? Were they upgraded from silver to gold status? Events can be made as specific as needed.
This may seem at first to be overthinking, but event naming becomes especially relevant as you remove data and context from the event payload, moving more toward skinny events (the "option 3" from your question, which I discuss below).
That is not to suggest that it is always appropriate to define events at this level of granularity, only that it is an avenue which is open to you early on in the project which may pay dividends later on (or may swamp you with thousands of event types).
Going back to your actual question, let's take each of your options in turn:
Name the event "CustomerUpdate" and include all information (updated or not) about the customer
Let's call this "pattern" the Fat message.
Fat messages represent the state of the described entity at a given point in time with all the event context present in the payload. They are interesting because the message itself represents the contract between service and consumer. They can be used for communicating changes of state between business domains, where it may be preferred that all event context be present during message processing by the consumer.
Advantages:
  • Self-consistent - can be consumed entirely without knowledge of other systems.
  • Simple to consume (upsert).
Disadvantages:
  • Brittle - the contract between service and consumer is coupled to the message itself.
  • Easy to overwrite current data with old data if messages arrive in the wrong order.
  • Large.
Name the event "CustomerUpdate" and include only information that have really been updated
Let's call this pattern the Delta message.
Deltas are similar to fat messages in many ways, though they are generally more complex to generate and consume. Because they are only a partial description of the event entity, deltas also come with a built-in "assumption" that the consumer knows something about the event being described. For this reason, they may be less suitable for sending outside a business domain, where the event entity may not be well known.
Advantages:
  • Smaller than Fat messages
Disadvantages:
  • Brittle - similar to the Fat message, the contract is embedded in the message.
  • Easy to overwrite current data with old data.
  • Complex to generate and consume
Name the event "CustomerUpdate" and include minimum information (Identifier) and/or a URI to let the consumer retrieves information about this Customer.
Let's call this the Skinny message.
Skinny messages are different from the other message patterns you have defined, in that the service/consumer contract is no longer explicit in the message, but implied in that at some later time the consumer will retrieve the event context. This decouples the contract and the message exchange, which is a good thing.
This may or may not lend itself well to cross-business domain communication of events, depending on how your enterprise is set up. Because the event payload is so small (usually just an ID), there is no context other than the name of the event on which the consumer can base processing decisions; therefore it becomes more important to make sure the event is named appropriately, especially if there are multiple ways a consumer could respond to a CustomerUpdated message.
Additionally it may not be good practice to include an actual resource address in the event data - because events are things which have already happened, event messages are generally immutable and therefore any information in the event should be true forever in case the events need to be replayed. In this instance a resource address could easily become obsolete and events would not be re-playable.
Advantages:
  • Decouples service contract from message.
  • Information about the event contained in the event name.
  • Naturally idempotent (with time-stamp).
  • Generally tiny.
  • Simple to generate and consume.
Disadvantages:
  • Consumer must make additional call to retrieve event context - requires explicit knowledge of other systems.
  • Event context may have become obsolete at the point where the consumer retrieves it, making this approach generally unsuitable for some real-time applications.
When raising an event, which pattern is the most suited?
I hope you have by now realised that the answer to this is it depends. I will stop here - yours is a great question because you could probably write a book while answering it, but I hope you found this answer helpful.