Recently, I had a database for a customer that has the usual plethora of several hundred stored procedures, nicely normlized schema, and a gob of indexes and statistics to boot for optimized searching. 

The customer wanted a small change to a stored procedure that would return a new field to the UI. Dutifully, I went about modifying the usual things - UI, Biz Logic Layer, Model updates, stored proc, table alter, etc. Well, after making this and about 30 other small changes in the development environment, we push to the QA server for more testing. After banging away and doing a quick performance check, everyone gives a thumbs up. So, over the weekend,  we do the hotfix push to production.

So, on 8:30AM on Monday, the performance on SQL Server went totally south! Oh the horror! I mean, way south, to the point that the server was completely sluggish.

At this point, I am totally baffled. Did Windows update do something nasty? No. Is there some crazy memory issue on the server? 16GBs, 9 free. Dang. That's not it. Did SQL Server's priority get bumped down accidentally by the Admin? Nope. I'm screwed and will have to back out the build, I think.

Then I look at the process manager and see that SQL Server is just spinning wildly, using all CPU cores. But it's I/O activity shows that it is doing virtually nothing- nada. Wait. Could I have possibly screwed this up by adding just one little dinky field? In short, yes. I suspect that I have a slew of deadlocks or at least a bunch of backed up locks. So, I whip out sp_lock2 (find it here: http://support.microsoft.com/kb/255596 ).

sp_lock2 is an extended version of sp_lock. Essentially, it tells you what the heck Sql Server is doing in terms of traffic for execution requests. Here is a sample output for sp_lock2:

It turns out that the very table I modified got a 120 million row import over the weekend too. Well, that's not really that big a deal, it's basically a write / audit table for details in a complex transaction, computing profit margins, targets, and such. Not rocket science. Except, yours truly didn't realize that the stored proc using this table was being hit concurrently by 100+ users and a new SQL job!

So, the additional stress caused by the long running job surfaced the weaknesses in the stored proc. It turns out that the scan to delete the existing computations and then insert updated ones was causing a gazillion table lock requests. This effectively crippled the server. The problem was solved by adding a statistical index to the new column I added and voila! Problem solved.

Normally, you will only see a few hundred rows or even a couple of thousand requests at a time, even with a busy SQL server instance. Sp_lock2 returned the app's SPID along with a backlog of 10,000 locks in my case! By looking up the object_id(objid) returned by sp_lock, I quickly zeroed in on the offending functionality. It was the stored procedure's attempt to delete based on a missing constraint (causing  a full table scan of 120+ million rows) and the lack of statistics on my secondary join on the new column. Short summary - performance was abysmal.

Without sp_lock2, it would have taken me forever to find the problem. Next time, I'll know what to do right away! This is what I like to see on a SQL Server!

 

 

 

 

 


Posted by: ezekiel.brooks
Posted on: 9/3/2009 at 11:36 PM
Tags:
Categories: Tips And Tricks
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Just a tip. The next time you have a very sluggish ASP.NET application to improve, you can pick up an easy win just by convincing your customer to use a fast rendering web browser. 

I have an older ASP.NET application that I am slowly migrating to Silverlight. There were a couple of terribly slow pages where it has a WYSIWYG render of a large electronic audit for a customer's store(s). For typical audits, there might be as many as 10,000 items grouped by categories and type. This would have been a great job for a disconnected fat client, but not good for the rest of the application. A web based solution was chosen for the usual reasons, like troublesome click-once deployment issues that dog corporate networks, etc. A great fit for Silverlight, but we're not there yet in terms of upfitting the entire portal.

So, the project manager tells me that a few of the pages are horrendous on some of the large store audits. Paging is a big negative because of the users' work flows. Best solution for this scenario, Silverlight, is not for a few months. What do I do?

I decide to give Chrome a shot to see if it can do better than IE7. Shazaam! Page rendering and loading goes from 5 minutes to 60 seconds on a 5,000 item audit report. Unbelievably easy speed improvement. 

Yes, there is some tweaking for frames and layout, but it's an easy win. I don't say this often, but kudos to Google Chrome! Download your copy and buy yourself some time to avoid major refactoring when there isn't time for it!

 

 


Posted by: ezekiel.brooks
Posted on: 8/11/2009 at 8:43 PM
Tags:
Categories: Tips And Tricks
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

I love Silverlight. It is absolutely amazing what Microsoft has been able to pull off with 2.0. What a quantum leap from 1.0.  With 3.0 about to drop this year, it will only get better as a RIA platform. However, I would anticipate that there are some issues that will still be present in Silverlight 3.0 that simply went along for the ride in Silverlight 2.

Recently, as part of a gig with a very large and well known Fortune 50 company, I had an extremely difficult project to pull off with either:

  • ASP.NET w/AJAX
  • InfoPath
  • WinForms
  • WPF
  • Silverlight 2
  • Some combination of all the above

To make a long story short, InfoPath was not up to it, enterprise IT would make any fat client deployment hell on earth, and I just don't like ASP.NET/AJAX all that much for maintainability considerations. I chose Silverlight. It was a roll of the dice, as Silverlight had *just* been released two weeks earlier. I expected huge fits of unforeseen issues, as the RTW was branding spanking new and was not travel tested at all.

Surprisingly, the RTW of Silverlight 2.0 worked astonishingly well. All technical mountains were eventually scaled, but there were a lot of discoveries along the way. Here are the Silverlight lessons learned that I will blog about over the next few weeks:

  1. Silverlight Memory Pressure Management
  2. Synchronous to Asynchronous UI patterns
  3. Dynamic Localization
  4. Silverlight Application Controllers
  5. The Dark Side of MV-VM
  6. Dynamic Object Graph Management
  7. WCF gotchas with Silverlight

Posted by: ezekiel.brooks
Posted on: 6/30/2009 at 9:09 PM
Tags: , ,
Categories: Mentoring
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 
For the next time you feel stressed about a project. Just remember no one will care after it all works!

Whatever you do will be insignificant, but it is very important that you do it.

Mahatma Gandhi
Indian political and spiritual leader (1869 - 1948)

Posted by: ezekiel.brooks
Posted on: 6/18/2009 at 3:42 PM
Tags:
Categories: Thinklets
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

The next time you see a junior developer struggling with a problem, offer to help. Remember, if he hadn't been hired, you might still be the new guy.  Wink

Proverbs 18:19 (The Message)

 19 Do a favor and win a friend forever;
   nothing can untie that bond.


Posted by: ezekiel.brooks
Posted on: 6/18/2009 at 3:15 PM
Categories: Thinklets
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Recommended Patterns

Some things are inevitable in life. The same is true in software development. One of those inevitable things in writing code is a system exception. The basic goal for handling exceptions in any software is to pick from 4 basic good patterns:

  • Handle
  • Wrap
  • Replace
  • Propagate

Whenever your code encounters a system error, it should take one of the above actions. Listed below are some design patterns for how to handle a .NET exception in your application.

Handle Pattern

The Handle pattern shows up most often in network transaction handling code where retries of some sort or another are normal and expected. When using this pattern, you must be diligent in avoiding blocking for long amounts of time.

private List<Widget> GetWidgets()

{

List<Widget> widgets = new List<Widget>();

try

{

//try fetching the widgets from the main server first.

widgets = DataAccess.GetWidgets(servers.Main);

}

catch (WidgetDatabaseUnavailableException offline)

{

//Let’s ‘handle’ this specific exception. In this example, we want to

//redirect to a secondary service or device.

//Make sure that we record the first failure.

Logger.Write(offline);

 

//try again with the alternate server cluster.

//If this attempt fails, then

//we truly have an unresolvable system failure.

//The exception will be raised to the client code.

widgets = DataAccess.GetWidgets(servers.FailOver);

}

//return our list, empty or not.

return widgets;

}

 

Wrap Pattern

The Wrap pattern is most commonly used to provide a more context sensible exception. The general pattern is to embed or ‘wrap’ the root exception, which may be way too verbose or technical, inside of a context specific user exception.

This allows the original exception to be accessed along with stack and trace information if it needs to be accessed. Here is how to define a ‘wrap-able’ user defined exception:

class WidgetDatabaseUnavailableException : Exception

{

public WidgetDatabaseUnavailableException(string msg,Exception x):base(msg,x)

{

}

 

public WidgetDatabaseUnavailableException()

: base()

{

}

}

 

And here is an example of a Wrap exception handling pattern:

private List<Widget> GetWidgetsWrap()

{

List<Widget> widgets = new List<Widget>();

try

{

widgets = DataAccess.GetWidgets(servers.Main);

}

catch (SqlException rootProblem)

{

//Let’s wrap this exception inside of another, more context

//specific exception.

WidgetDatabaseUnavailableException widgetException =

new WidgetDatabaseUnavailableException(

Properties.Resources.UnableToLoadWidgets,rootProblem);

 

//now throw our more specific exception along with detail information about

//the root cause of our problem, the SqlException problem. The complete

//stack trace is available in the inner exception to the UI code or other

//callers.

throw widgetException;

}

//return our list, empty or not.

return widgets;

}

 

Replace Pattern

The Replace pattern is often used to avoid exposing sensitive information, like credit card numbers and social security. It is a common pattern to replace the exception that contains sensitive information with one that has number masks or similar methods to protect customer or entity identity information from being displayed in user interfaces.

private void ChargeVisa(Charge customerCard)

{

try

{

//we are attempting to charge a customer's credit

//card. Because of Sarbanes-Oxley, we cannot display

//the customer's credit card number. If an exception

//occurs, then we will log the true exception, but

//pass a sanitized exception back to the UI.

BillingCenter.Charge(customerCard);

}

catch (CreditCardExpiredException expired)

{

//The customer's credit card did not work.

//Log the root cause of the problem (with specifics)

//to the system database.

Logger.Write(expired);

 

//Replace the original exception and pass a replacement

// back to the User Interface or other client code.

//The application can choose to retry the transaction and

//display sanitized customer card information to the user.

throw new BillingCenterException(customerCard.CardHolder,

customerCard.MaskedCardNumber, customerCard.Expiration, customerCard.Amount);

}

}

 

Propagate or ‘Bubble’

The propagate pattern targets one or more exceptions which are unconditionally thrown to the caller. However, the Propagate pattern may also be constructed to process any remaining exceptions with alternate courses of action. In the following example, we are going to retry fetching the widgets a second time as long as the database did not report ‘offline’.

private List<Widget> GetWidgetsPropagate()

{

List<Widget> widgets = new List<Widget>();

try

{

widgets = DataAccess.GetWidgets(servers.Main);

}

catch (WidgetDatabaseUnavailableException offline)

{

//Let’s ‘handle’ this specific exception. In this example,

//the widget database is offline. If the database is

//offline, there is no point in retrying. PROPOGATE this

//exception immediately upward to the caller.

throw;

}

catch (Exception allOtherExceptions)

{

//Let’s attempt to handle all other exceptions by retrying.

widgets = DataAccess.GetWidgets(servers.FailOver);

}

 

//return our list, empty or not.

return widgets;

}

 

 

Exception Handling Anti-patterns

In most cases, exception handling is relatively well defined. However, there are some anti-patterns that will cause red flags in code reviews. The most common errors are:

1.      Suppressing Exceptions

2.      Losing stack traces

3.      Failure to log exceptions correctly

4.      Wrapping and replacing exceptions out of context

5.       

Here are some examples of each anti-pattern and a couple of good patterns

Anti-pattern: Suppress

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50/zero;

}

catch (Exception exception)

{

//Very bad!!! I didn't do anything with the exception. The application has no

//idea that this caused a problem!

}

 

 

Anti-pattern: Suppress and Log

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50/zero;

}

catch (Exception exception)

{

//Very bad!!!. The client code has no

//idea that this caused a problem! To make it even worse, I

//will log the exception, but the application may exhibit

//strange behaviors as the exceptions pile up during runtime

Logger.Write(exception);

}

 

 

Anti-pattern: Suppress and Return false, 0, or null

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50/zero;

}

catch (Exception exception)

{

//don't do anything with the exception. The application has no

//idea that this caused a problem!

return false;

}

Anti-pattern: Losing Stack Trace

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50 / zero;

}

catch(Exception exception)

{

//uh oh! We don't know what really happened. We will lose

//all stack trace information in this case.

throw new Exception("My custom exception");

}

 

 

Anti-pattern: Log and Throw

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50 / zero;

}

catch(Exception exception)

{

//ok. We are going to log this error, but the problem is

//that the call may do the same thing – resulting in

//multiple error messages in the log of the same thing!

Logger.Write(exception);

throw ;

}

 

 

Anti-pattern: Wrap and Lose Stack

try

{

int x;

int zero = 0;

//this will cause a DivideByZeroException

x = 50 / zero;

}

catch(Exception exception)

{

//This is also quite bad. We lost the stack trace!

MyCustomException mine = new MyCustomException(“I had a bad attempt”, exception.Message);

throw mine;

}

 

 

 


Posted by: ezekiel.brooks
Posted on: 6/18/2009 at 2:54 PM
Tags:
Categories: C# | Mentoring
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

I was talking with one of my clients tonight and we were discussing putting together a team in 2010 to build a large Silverlight application to replace a legacy system. We were going over the project cost, team size, and likely delivery milestones. Because my client is the CEO,  I saw it as an opportunity to get rare insight about how business people feel about working with software professionals. 

Of course, it is also to my advantage as a private consultant to understand the psyche of people who are the key decision makers - especially those who give go/no-go to software project funding. The context here is that I am replacing another consulting group that simply didn't deliver what this company needed. Project hit the wall, the technical staff was frustrated, the app didn't work. The business owner flushed the consulting group. So I bravely asked. "What happened with the previous vendor?".

"Well, that is a loaded question, Zeke" He said to me. "Look. We're simple people trying to run a business here. We need software. I know I can't grow my business without it. I have tried to instill respect and honesty as best I can in everything we do...". I could tell that he was very still very upset about the previous vendor. 

I waited to let him develop his thoughts. He continued. "Boy, where do I start? First of all, they acted like they were smarter than everybody else - a bunch of jackasses, in my opinion. I have a multimillion dollar business here - they don't. I turn a profit equal to their salaries every week. It grates on me that they acted like we're a bunch of idiots. We don't know how to write software, but we know how to make money. I know that this doesn't sound very nice, but my staff hated the lead guy. They never understood anything he was talking about and he got frustrated when asked to explain things to them in detail. Worse than that, he could never give a straight answer about anything and the crap they delivered didn't work - cost me a year of progress on this end in building my business".

Wow. I was stunned. Then I realized that, as software professionals in general, our technical skills have gotten infinitely better over the last 10 years. OOAD, OOD, Business Domains, IoC, DI, MVVM, Cloud Computing. The list goes on and on. However, I am of the opinion that many of us may have gone completely backwards in interpersonal and communications skills.

I can't count the number of times that I've interviewed folks over the years and get asked by the decision makers "How are their communications skills". I mean, I've seen some seriously skilled folks come through and they weren't hired because, quite frankly, they suck at expressing themselves, or seem to be somewhat arrogant or insensitive. 

On the bright side, we can always get better. But we have to work at it. Our discipline is bigger than the latest coding tricks or paradigms. Check out some of these articles. It never hurts to get better Wink

http://blogs.techrepublic.com.com/programming-and-development/?p=36

http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci347660,00.html

http://stackoverflow.com/questions/96879/advice-to-improve-programmer-communication-skills

 


Posted by: ezekiel.brooks
Posted on: 6/18/2009 at 1:50 PM
Tags:
Categories: Mentoring
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Well, it's been a few days since I blogged. I've been bogged down with finishing up a Silverlight project for a soon to be former employer. Back into private practice. Woohoo!

Something that's been on mind lately has been the issue of self esteem among software professionals. I have a really close buddy of mine, who is relatively new in the world of high powered programming enclaves. He was so intimidated by his co-workers 'great knowledge' that he was effectively unable to do his job well without fear, trepidation, and generally low self esteem.

After an extended session of talking about the spiritual and philosophical issues at the root of his current dilemma, he concluded that maybe 'he wasn't cut out for this [software development]'. "But, you're a fine programmer" I countered. After much pep talk, he felt better, but his lack of joy at the time actually convinced me to address this issue in Meta { ! } Think.

For the record, everyone can do something well. Software organizations, like any other, require a wide swatch of skills and abilities to be truly healthy. As an example, take Microsoft. They have their prime time players who are the face of the organization. Great visionaries who steer the technical direction of the company. Great computer scientists who write and blog about all kinds of arcane subjects and are the center of attention at every software conference. 'Gee', you think. 'I wish that was me'.

Infamous Microsoft Example

Well, remember that these folks have the job of strategic thinking. They are truly looking at the whole, or a big chunk, and not the specifics. These are the folks who think strategically and drive Microsoft's long term goals. Think Bill Gates. Think Microsoft Research. Think about any Microsoft superstar.

Now, can Mr. Gates do functional testing for Server 2008 subsystems? Maybe, but I wouldn't want him on my Server Test team. I'll take the person who has successfully and consistently found hidden defects that even unit testing failed to find. A loss of sales due to product defects that my team finds, even with Mr. Gates on the team, is a failure. So, who's more valuable?

Ah, you say. Bad comparison, Zeke. Bill Gates - hands down. At least we could start another company with him and get rich. Lol. Maybe. But in the focus of this hypothetical, let's think about this. Do this search on Google: http://www.google.com/search?hl=en&q=bill+gates+windows+crash&aq=1&oq=Bill+Gates+windows&aqi=g10 Now, I ask you. Who is more valuable to the organization?

Look at all of the damage caused to Microsoft by this now infamous event. Notice Apple gleefully pounding Microsoft on this issue. Heck, a new series of Mac vs. PC commercials was born out of this type of incident. This was not the first time Windows has embarrassed Microsoft because of something that escaped failed functional testing efforts.  Now I ask you - who's more valuable?

Advice

Well, it depends on the situation. And that is my point. Figure out what you do best and put yourself into the right situation that needs you! If you are best with competencies that require skills a foot wide and 20 miles deep, like targeted development niches or functional testing, then focus on that. That is your fit in the IT Ecosystem. Be proud of it and feel good. Heck, you could have even saved Microsoft a lot of pain.

Consider this advice I found in "The Message", by Eugene Peterson:

Galatians 5:26 (The Message)

 

 25-26Since this is the kind of life we have chosen, the life of the Spirit, let us make sure that we do not just hold it as an idea in our heads or a sentiment in our hearts, but work out its implications in every detail of our lives. That means we will not compare ourselves with each other as if one of us were better and another worse. We have far more interesting things to do with our lives. Each of us is an original.

Amen to that. ;-)

 


Posted by: ezekiel.brooks
Posted on: 6/15/2009 at 4:59 PM
Tags:
Categories: Mentoring
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Ok. So, after looking at C# 4.0, it has a lot of really cool features. But here, cool is not necessarily good. Am I hating on C# 4.0? Lol. Not at all. I love C#. It is a wonderful, strongly typed, 4th Generation OOPL. But around here, balance is the key. History is important unless you just have a burning desire to repeat past mistakes.

So, in the spirit of Meta { ! } Think, I want you to consider this possibility. Could it be that despite all of the really brilliant constructs in C# 4.0, we are actually creating more problems than solutions? Or is C# 4.0 really the best thing since sliced bread? Let's go back in time a bit for some perspective before we pass judgement.

And Before C#...

Way back when in the late nineties, Visual C++ was all the rage. We had been delivered from plain old C along with the millions of linearly constructed applications that went with it. We had OO concepts - classes, dynamic callbacks and such with C++. Yay!

However, C++ eventually became known as the 'Chainsaw' where I worked. Why? Quick and massive damage - just like with a real chainsaw. One mistake and you could lose a limb (or at least kill an entire app or system). C++ pretty much fit this profile - one small mistake with a pointer, casting, Interop, or COM would create a mushroom cloud in your app.

We had conditioned ourselves to expect fatal exceptions at any time. Testing cycles were very, very, long for C++ apps. God forbid if you were talking to COM or DCOM objects as well. This was early dynamic programming at its worst. 

Dynamic Programming in C#

So. here it is years later. C# has pretty much eliminated these sorts of heinous practices of old. It's object oriented, precise, and strongly typed all over the place. Sweet. But, the language has evolved with C# 4.0. The really bright people who write extensions to C# ( http://code.msdn.microsoft.com/csharpfuture)  have come up with Dynamic Lookup capabilities to allow integration with

  1. Ruby, Python and other dynamic languages
  2. COM IDispatch objects,
  3. Reflection-based dynamic programming,
  4. HTML DOM.

Sweet - if you *have* to talk to these sorts of objects in your systems.  But, if you don't have to, I wouldn't. I certainly wouldn't do it for the cool factor. I saw enough of 'Programmers Gone Wild' with C++ back in the day.  Before using the dynamic features of C# 4.0 without restraint, remember that the more external non-native modules (e.g. COM) that you couple into a solution, the more complex and unstable it tends to be.

We used to call C++/COM amalgams 'Frankenapps'. This is, of course, a play on words to bring to mind Frankenstein - you get the picture. Unfortunately, I see the potential to open that Pandora's box of issues up all over again with C# Dynamic Programming. I would advise anyone to ask the following questions of themselves before rushing to consume dynamic objects from other paradigms:

  • Can I solve this problem without exposing my statically typed C# application to a wild universe of variances, permutations, and dependencies in dynamic objects?
  • Will dynamic programming make this application more or less stable?.
  • Could I use SOA or other messaging techniques to communicate with the targeted dynamic objects or systems? 
  • Do I believe that binding to these dynamic objects will simplify or complicate my solution unnecessarily? 

 

This is easy in C# 4.0, but is it a good idea?

var xl = new Excel.Application();
xl.Cells[1, 1].Value2 = "Process Name";
xl.Cells[1, 2].Value2 = "Memory Usage";

Remember Frankenstein. Wink
 

 

 

 


Posted by: ezekiel.brooks
Posted on: 6/7/2009 at 7:21 PM
Tags:
Categories: C#
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Ok. So, you're doing SCRUM. Everything is hunky dory. You've got the standups happening; you're meeting with the customer; requirements are under control; your boss is impressed. But you're about to encounter the infamous Cowboy Coder.

The  Cowboy Rides Into Town

You're in week two of four. You're having a great standup meeting and then it happens. Your ScrumMaster, Eric,  asks Dave [the hottest developer on the planet] to give status. Dave, with a scowl on his face says "Geez. I told you Friday what my status is". Eric, as all well trained ScrumMasters do, gently replies to Dave that his tasks' seem to be way underestimated and that he is now 2 days late on delivery.

Silence hits the room. You, as Product Owner, turn white, dreading what this will do to team chemistry. You also know that Dave is very gifted as a software developer, but he's a bull in the China shop otherwise. No one likes working with Dave. He doesn't want to collaborate on problems, nor does he appreciate anyone 'peer reviewing' his code. Yikes. The Cowboy has finally shown up. His attitude tells everyone that he's the man and not to be questioned. 

'I Challenge You To A Duel'

Eric, again, quite politely says "Dave, your tasks have a lot of other dependencies, as you can see here in our Sprint backlog. Other members of the team are now blocked with their dependent tasks because you didn't give us accurate status. We could have avoided this task sequencing problem with a little communication".

Dave goes ballistic - "I can do this whole project by myself if I had to". Dave is fuming - he wants to get the last word in on the matter. "This whole SCRUM thing sucks. I liked it better the old way without all of this touchy feely crap. As a matter of fact, you all suck." Horrors, you think. You have visions of all kinds of squabbles, confusion, and ill will breaking out within the Team.

Susan, another developer on the team, says "Let's just table this for now and let everyone else give their status". Surprisingly, the team dutifully goes about giving their status while Dave sulks and scowls. Wow, this can't be good, you think - calm before the storm.

Shootout in the SCRUM Bullpen

Right before lunch, Susan sends out a meeting request for the Developers only. You rush over to Eric and say "This can't be good, Eric. What's going on?". Eric replies that the developers wanted a techie meeting only and asked him if he would mediate. You want to attend but heed Eric's advice to let things play out and not to panic. You'll stay out of the way and let the Team try and work things out.

The next day, you have butterflies, thinking that all hell has broken loose and it's going to be a bad day for the Team. You're shocked. Everyone is there, including Dave - and SCRUM goes well. After you corner Eric, you ask him how can this be after the meltdown yesterday? Eric explains. "The rest of the developers let Dave have it in the technical team meeting that Susan requested. I didn't have to say anything. They basically read Dave the riot act.

They told him, in no uncertain terms, that he was reponsible to the *team*. They also told him that they all had to work 4 hours overtime to compensate for him not completing his tasks. In so many words, they told him that he needed to knock it off and to be fair. Otherwise, they were willing to go on without him. After that, Dave apologized, they all shook hands and said that they wouldn't let each other down. So, it's gonna be ok."

Moral of the Story

Scrum teams, when well trained, are self correcting. Scrum emphasizes personal empowerment, transparency, accountability, and teamwork. As a result, when a member of the team violates the Scrum culture, the others will tend to push them back into alignment. This is especially true where routine standup meetings are the norm and it is clear that a teammate is violating the group trust and causing problems for everyone. Sometimes the ScrumMaster has to wield a heavy hand, but typically, the group will correct itself.

In summary, don't overreact to the typical conflicts that occur within a Scrum team. If you have trained your Team based on Ken Schwaber's work about Scrum (http://www.controlchaos.com/ ), most issues get no further than the ScrumMaster, if that far. Don't overreact to Cowboys, no matter how gifted they are. Much of their power is found in speaking quickly, repeatedly, and loudly. Trust the ScrumMaster and the team to eventually challenge the Cowboy. I thought it quite profound that this scripture speaks to this problem:

17 The first to present his case seems right, till another comes forward and questions him. - Proverbs 18:17 NIV


Posted by: ezekiel.brooks
Posted on: 6/7/2009 at 2:48 AM
Tags: ,
Categories: SCRUM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed