Friday, July 24, 2009

TFS - Stop and Start Server

After some failed attempts at stopping and starting servers through third party tasks, I had quick success using the exec command in the TFSBuild.proj:


<PropertyGroup>
<web-site-id>1</web-site-id>
<server-cmd-prefix>C:\Windows\system32\cscript.exe c:\Inetpub\AdminScripts\adsutil.vbs</server-cmd-prefix>
<stop-server-cmd-line>$(server-cmd-prefix) STOP_SERVER W3SVC/$(web-site-id)</stop-server-cmd-line>
<start-server-cmd-line>$(server-cmd-prefix) START_SERVER W3SVC/$(web-site-id)</start-server-cmd-line>
</PropertyGroup>

<Target Name="StopSite">
<Message Text="stopping site..."/>
<Exec Command="$(stop-server-cmd-line)"/>
</Target>

<Target Name="StartSite">
<Message Text="starting site..."/>
<Exec Command="$(start-server-cmd-line)"/>
</Target>

To find the web-site-id, refer to Scott Forsyth's Blog.

Labels: ,


Monday, July 20, 2009

AES Encryption Wrapper for Ruby

I thought I would share my AES encryption wrapper for Ruby. The attached code utilizes openssl.


require 'openssl'

module AESCrypt
  DEFAULT_CIPHER_TYPE = 'aes-256-cbc'
  CRYPT_STRUCT = Struct.new(:encrypted_data, :key, :iv)

  def AESCrypt.encrypt(plain_text, opts={})
    cipher = OpenSSL::Cipher::Cipher.new(DEFAULT_CIPHER_TYPE)
    cipher.encrypt
    opts.reverse_merge! :key => cipher.random_key, :iv => cipher.random_iv
    cipher.key = random_key = opts[:key]
    cipher.iv = random_iv = opts[:iv]
    encrypted_data = cipher.update(plain_text)
    encrypted_data << cipher.final
    CRYPT_STRUCT.new(encrypted_data, random_key, random_iv)
  end

  def AESCrypt.decrypt(crypt_struct)
    cipher = OpenSSL::Cipher::Cipher.new(DEFAULT_CIPHER_TYPE)
    cipher.decrypt
    cipher.key = crypt_struct.key
    cipher.iv = crypt_struct.iv
    cipher.update(crypt_struct.encrypted_data) + cipher.final
  end
  
end
This code is pretty straightforward. One thing of interest is that we are using a random AES key and initialization vector on lines 10 and 11 respectively. This results in consumers of this API needing to store the key and initialization vector in order to decrypt, which is why a CRYPT_STRUCT is returned on line 14.
The source and test files are available at the my_password_manager github site.

Labels: ,


Monday, July 13, 2009

When is "last"?

One of the extreme programming rules is Optimize Last. The rule is stated as

Do not optimize until the end. Never try to guess what the system's bottle neck will be. Measure it!
Make it work, make it right, then make it fast.

When is "last"? Is it one week before the application goes into production, at the end of an iteration, at the end of the story, or at the end of a pairing session?

Another question: what and how much should be optimized?

Though the answers to these questions may very a little from project to project, in my experience "last" should mean both at the end of the stories and end of iteration and just the bottlenecks should be optimized with the aid of a profiling tool.

Optimization strategy:
  1. Obtain non-functional performance requirements for the system very early in the project. If there is know target, are we not wasting our time optimizing? By the way, "as fast as possible" is not a sufficient requirement.
  2. Set up automated performance tests. You may even want to go as far a having it run as part of your continuous integration build and having the build fail if certain performance thresholds are not met.
  3. Near the end of story completion, profile the new code. I use ANTS Profiler for C# and JProfiler for Java. Obvious bottlenecks with minimal code changes for optimization should be implemented without hesitation. Continue to fix bottlenecks until the application is meeting its performance requirements.
  4. Near the end of the iteration, profile the whole application. Consider having team members rotate through application-wide optimization responsibilities every iteration.




Labels:


Tuesday, July 7, 2009

Selling Agile Development Practices to Your Manager

There have been some comments that some of you developers are very interested in adopting agile development practices, but your manager isn't seeing the benefit.

There are two important points to make to your manager.
  1. Incremental development practices prevent defects and catch them early
  2. The cost of a defect drastically goes up the further along it is in the project life cycle
Incremental development practices are geared around preventing defects and catching them early with comprehensive tests, frequent integration, and knowledge sharing. Take a look at my Incremental Development Presentation for more information.

A simple google search yields a lot of evidence to support the high cost of defects. The cost of defects relative to project life-cycle looks a lot like the image below.



Labels: ,


Monday, July 6, 2009

The Multi-core Problem

If you don't have any experience with functional programming languages, do yourself a favor and take the time to watch this presentation by Joe Armstrong who is the Erlang programming language creator.

One of the main points that Mr. Armstrong makes is that as time goes on sequential programs will get slower because they do not utilize more than one core and current trends are to have more and slower cores to reduce power consumption.

Functional programming languages like Erlang can utilize as many cores as necessary because there is no mutable state, there is no shared memory, and actors are completely isolated.

Labels: ,


FirstMem - a tool for verbatim text memorization

I have recently spent some time learning Ruby and Rails. When I learn a new language I typically write an easy application so that the focus is not on solving a particularly difficult problem, but on learning the new technology. To learn Ruby on Rails, I wrote http://firstmem.hertler.org. The code is hosted at http://code.google.com/p/firstmem/

As I was writing the code I was constantly shocked at how little code it took to perform complex tasks and how easy the Rails framework is to learn. It almost felt like cheating!


Labels: ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]