Tuesday, May 8, 2012

TFS - Creating a Branch from Local Source

Well that was frustrating.

The Problem:
Work has been performed on the source Trunk that now needs to be in a separate branch, and not checked into the Trunk.

The Solution:
Create a branch selecting 'current workspace' as the source version
*Ba Bow* - nope, this doesn't do what you think it does, your shiny new branch does not have your local workspace changes.

Create a branch and merge the changes across
*Ba Bow* merges only work on checked in code.

Create a branch, shelve your changes, unshelve to the branch
*ding ding* we are on a winner, only it is a PITA to get it working.

Firstly you need the TFS power tools - here: http://visualstudiogallery.msdn.microsoft.com/c255a1e4-04ba-4f68-8f4e-cd473d6b971f
Next you need to, for some reason, ensure you have no other pending changes in your workspace.  I have no idea why, but even if you have pending changes competely unrelated to the shelve files, you will get warnings and may get errors.  Strange but true.
Next you need to call the "tfpt unshelve" power tool command. But you need to call this from a folder in the workspace you are working with as there is no way to set the workspace/server in the tfpt command.

tfpt unshelve MyShelfsetName /migrate "/source:$/MyPath/My Path with spaces/MyBranch" "/target:$/MyPath/My Path with spaces/MyOtherBranch"
Finally, when you run the command you will need to merge all the shelved files into the new branch, one by one.  You can perform an auto-merge, but this will actually perform a merge on the destination/shelf, when in reality you very likely want to take the shelf version rather than do a merge, which requires you to go through file by file.

The link below is a good source of information on this process.
http://codereferences.blogspot.com.au/2012/02/migrating-shelveset-from-one-branch-to.html

Tuesday, May 1, 2012

Solving Race Conditions



Example

We have 'Tags' that can be applied to a 'Post'. When creating a post, we want to only create new tag entities when the tag does not already exists. A race condition can exist when two posts with the same new tag are created at the same time as the check if the tag exists can be false for both posts.

Solutions

1) Always create a new tag - we don't really care that we have duplicate tags if we always perform operations on the tagName, not the actual instance of a tag - this in ddd would be a 'Value Object'.

Side effects are; a potential drop in performance, and an increased database size

2) Use Database constraints to mark the field as unique, so the second post will attempt to create the tag and fail.

Side effects are; it is difficult to impose unique constraints in ORM, not all underlying providers (object store for example) will support this, and requires 'retry' logic.

3) Use a Transaction to check the existance of the entry before the insert.

Side effects are; a drop in performance from transactional locking and increased solution complexity.

4) Use a messaging service model for processing each post creation as a separate operation so the race conditions wont exist.

Side effects are; an increase in application complexity due to the asynchronous nature of the queue, and reduced performance due to the overhead (albeit with an increased scalability)

Conclusions

Option 1 in this scenario is entirely valid but this is not always the case, often guaranteed uniqueness is important, so using this as a general solution to race conditions is not appropriate.

Options 2 and 3 are very reiliant on the functionality of the underlying data provider.  In most LOB solutions is probably OK, but it is not as flexible and scalable as I would like.

Option 4 seems like a fairly drastic change in application design, but in reality this should not be as large an impact as you would think.