August 2004 Blog Posts

We're Having A Doggie!

Italian GreyhoundSo after much deliberation and research, we've decided that we're going to provide a home for a dog. In particular, we hope to adopt an Italian Greyhound from a rescue center. A rescue center is basically a foster home for dogs rescued from the dog pound. A rescue typically specializes in finding homes for a specific breed. For example, there is a Labrador Rescue, a Poodle Rescue, etc...

While paging through pictures and bios of dogs in need of a home, my wife grew really sad and wanted to rescue all of them. But we have a small Condo and can only really provide a good home to one dog.

If you're looking to adopt a pet, try checking out your local animal shelter. For those of you in Los Angeles, check out the LA County Animal Care & Control. Oh, and as Bob Barker always says, "have your pets spayed or neutered".

Statement Graph Reflector Add-In Makes Pretty Flowcharts.

Peli has a post about a new Reflector Add-In he will release soon. It generates a statement graph from the body of a method. It's a nice way to produce a flowchart and visualize the "flow" of execution within a method. See an example below:

Flowchart

Get Your GMail Invites Here... (UPDATE: All out)

I have a few GMail invites to give away. If you don't mind having a profit driven corporation scanning the contents of your emails in order to target you with ads, then post a funny comment with your email address. Or just post a bland comment. I don't really care.

In return, you'll get a free web-based email account with 1000 MB of storage and the power of the Google search engine for searching your emails.

Sorry. I'm all out.

Be A Real Political Geek, Buy The </bush> T-Shirt

In the comments section of the post about the geekiest protest sign, Clara points out that tshirthell.com sells a t-shirt with the end Bush tag (seen below).

End Bush T-Shirt

Tell them Haacked sent ya (not that I know those people).

As to the question whether this is XHTML, HTML, XML, SGML compliant? Who really gives a flying fuck? I mean c'mon people, get a freakin' life! The real question is why choose a serif font over a sans-serif? ;)

For you real geeks: 0x3c 0x2F 0x62 0x75 0x73 0x68 0x3E

UPDATE: Oh, and this shirt is an XHTML compliant end tag (unlike the protest sign) assuming it is preceded by a start tag. According to Section 4.2 of the W3C recommendation, Element and attribute names must all be in lowercase.

PHOTO: When Nerds Protest The RNC.

Kyle sent me this classic photo from a friend of his, Brad Kagawa, who was at the RNC protest in New York. Brad scrambled across the march to take a picture of the geekiest protest sign he's ever seen.


Will the W3C support this addition to HTML?

Whoever this person is with the sign, I <SALUTE/> you.

Thanks to Brad and Kyle for sending me this.

UPDATE: BoingBoing.net has a great entry about the mixture of tech, art and protest at the RNC. What makes the blog entry really great is that it includes a link to this post. ;)

UPDATE #2: And what makes this post great are the ensuing comments about HTML correctness that inevitably follow when geeks get political. My I think I'll start posting everything as HTML.

UPDATE #3: So we may have identified the mysterious sign holder. Her name is Shalott. Of course, I have no way of confirming, but like Mulder, I believe! She got the idea from her friend Tzikeh who saw it online on a t-shirt.

Burning Man 2004 Starts Today!

So today, loads of clean people will be driving through the small town of Gerlach into the temporary city of Black Rock City. Trust me, they won't stay clean for long, and will definitely bring home a souvenir of a nice coating of Playa dust over everything.

They are there to begin a week long festival known as Burning Man. This year's theme is "Vault Of Heaven". I believe my friends Ed and Michael (not Krimm) are going to be out there getting into all sorts of trouble.

I hope you all have a good time out there and be safe. Especially watch out for the sharks!

The author auditions for Jaws 5.  (Notice the temple in the distance to the right)
The Black Rock legal team approaches...

Technorati Tags:

Congratulations Kyle and Cara!

We just got back from their wedding reception in San Francisco and we had a great time. I can see that you two will be very happy and I was honored to take part in the reception. Also, many thanks for the iPod, an overly generous gift, but one I will make good use of. I now finally have an iPod. Wohoo!

Custom Source Control In CruiseControl.NET?

I'm in the unlucky position that CruiseControl.NET doesn't support the source control provider (Seapine Surround SCM) we use here at work. Briefly looking at the source code for CCNET, I noticed that I could create support for Surround SCM by implementing the ISourceControl interface via inheriting the ProcessSourceControl.cs class. However, before I go down that road, does anyone know if I can add a custome source control provider as a plug-in?

For example, if you want to use a build tool other than NAnt or Devenv.exe, you can create a builder plug-in by following these instructions. Will that work for creating a custom source control plugin? (Of course I'd be replacing IBuilder with ISourceControl or ProcessSourceControl.cs).

I'd prefer not to compile my update into the main code branch as I don't want to maintain a variant of CruiseControl.NET. Likewise, I don't want to write this plug-in if someone else already has one out there. It might be a better use of my time to convince my dept to switch SCM tools. ;)

World Officials Ask Hamm to Give Up Gold

Riiight. You know kid, you did nothing wrong, but we'd like you to give back that gold medal anyways. We mistakenly gave it to you and we'd love it if you corrected that mistake for us. While you're at it, I also had an accident in the bathroom we'd like you to clean up. Thanks, now there's a good kid.

AP - World gymnastics officials were looking for a way out of the Paul Hamm medal mess. All they did was make more people mad. The president of the International Gymnastics Federation asked Hamm to give up his all-around gold medal as the ultimate show of good will, but the U.S. Olympic Committee told him to take responsibility for the problem and refused even to deliver the request.
[Via Yahoo! News - Most Emailed]

Joke Of The Day: Kenny the Rooster

RoosterThis farmer has about 500 hens, but no rooster, and he wants chicks. So, he goes down the road to the next farmer and asks if he has a rooster that he would sell. The other farmer says, "Yep, I've got this great rooster, named Kenny. He'll service every chicken you got, no problem."

Well, Kenny the rooster costs $3,000, a lot of money, but the farmer decides he'd be worth it. So, he buys Kenny. The farmer takes Kenny home and sets him down in the barnyard, but first he gave the rooster a pep talk. "I want you to pace yourself now. You've got a lot of chickens to service here, and you cost me a lot of money. Consequently, I'll need you to do a good job.! So, take your time and have some fun," the farmer said, with a chuckle.!

Kenny seems to understand, so the farmer points toward the hen house and Kenny takes off like a shot. WHAM! Kenny nails every hen in the hen house - three or four times, and the farmer is really shocked.

After that, the farmer hears a commotion in the duck pen and, sure enough, Kenny is in there. Later, the farmer sees Kenny after a flock of geese down by the lake. Once again - WHAM! He gets all the geese. By sunset he sees Kenny out in the fields chasing quail and pheasants.

The farmer is distraught and worried that his expensive rooster won't even last 24 hours. Sure enough, the farmer goes to bed and wakes up the next morning to find Kenny on his back out in the middle of the yard, mouth open, tongue hanging out and both feet sticking straight up in the air. Buzzards are circling overhead.

The farmer, saddened by the loss of such a colorful and expensive animal, shakes his head and says, "Oh, Kenny, I told you to pace yourself. I tried to get you to slow down, now look what you've done to yourself."

Kenny opens one eye, nods toward the buzzards circling in the sky and says, "Shhhh .. they're getting closer."

Corporate Sponsored Pornography?

I thought that would get your attention. I recently realized that my old blog on blogspot is still up and running. When I was working at a large ethnic television network (that will remain unnamed), I received the following internal email:

Due to performance issues with one of the email filters, I have been forced turn all but the most essential portions off. As a result of this change, there may be an increase in the amount of pornographic email that reaches you.

I suppose there will be a correlated drop in productivity.

Creating A Sane Build Process

I’m not proud of it (well maybe just a little), but I once created an insane build process once. If Pat (who maintained the build after me) posts in my comments, he’ll tell you about it. Take a stew of a proprietary microcomputer flavor of Fortran written in the 70s by a programmer most assuredly clad in polyester, churn it through a Visual Basic 6.0 preprocessor that spits out Fortran 90 code, all the while correcting memory bound issues, mix it together by compiling it with a custom NAnt fortran compiler task, and voila!, 20 or so compiled Win32 fortran dlls. At this point, the process compiled and sprinkled in some C# code.

I’m not sure that build process will ever run on another machine other than the one it runs on.

To create a sane build process, you need a sane development environment. I’m sure there are many important principles of a sound build process, but I have just one big one to impart for now.

The build must be location independent!

I can’t stress enough how important this principle is. I should be able to walk into your office (assuming you’d let me) and perform the following steps to get a fully working build on my machine.

  • Set up my computer
  • Hook it up to your source control system
  • Set the working folder to any old directory, say J:\IBetThisFolderIsNotOnYourMachine\NorThisOne
  • Get latest on a solution and open it up in VS.NET (or whichever IDE)
  • Compile it

If that doesn’t work because you have hard coded file paths, then FOO on you! But let’s not stop there, I should then be able to run your unit tests (what? You don’t have unit tests? A hex and octal on your code!) and they should all pass on my machine (assuming they pass on any machine).

But wait, I’m not done mucking around your office. Next, I should be able to head to your build server, copy the folder that serves as the root of your build process (or better yet, your CruiseControl.NET root) to any folder on my machine, and run your NAnt (or MSBuild) script, and have the system compile correctly and pass all unit tests.

How do you do it?

At first, it takes a bit of practice to get to this point. For example, there should not be a single hard-coded path in your code, nor in your build scripts. Find every way to get them out of there. Here’s a few tips for tricky situations you may run into.

NUnit/MbUnit configuration file

UPDATE: This section was rewritten due to changes in Visual Studio.NET 2005

In VisualStudio.NET 2005, you can include an App.config file in the root of any class library project. Compiling the project will automatically copy and rename the file appropriately (AssemblyName.dll.config) into the output directory. NUnit and MbUnit will use the settings in this file to run the tests. Make good use of this.

Testing With External Resource Files

Suppose your unit tests rely on some external files for testing (like an xml or html file to parse). If you store these files with the code, you can’t be guaranteed that your unit test will find them when running on a build server (since the directory structure may be quite different). You also don’t want to put these files within bin/debug for the reasons mentioned above.

Instead, follow Patrick Cauldwell’s lead and embed the files as resources. Now, your unit test can just unpack the file it needs into a known relative location when it runs, achieving location independence.

Limitations

Of course, there are limitations to location independence. You’re allowed a few assumptions. For example, in the scenario above where I stomp into your office and take your source code, you can assume that I’m running on the same platform you are and have a source control client and IDE installed. Try to reduce these assumptions as much as possible, but we have to agree on some basic axioms.

I’m working on a new build process right now, and I hope to make this one a sane one. Maybe I’ll post examples later when I get done. We’ll see.

Could This Be My Next Digital Camera?

[Via Boing Boing]
Cory Doctorow: Casio's Exilim cameras are the best digital cameras I've ever used, period. Great form-factor, great size, great -- fantastic -- UI, and great-looking piccies. Now Casio has announced a new whisker-thin credit-card-sized three megapixel Exilim with an optical zoom built in. I'm using the non-zooming 3MP and I've nearly beaten it to death (the Exilim is the first camera I've used that's small enough for me to carry 24/7): now I know what my next camera will be. Link (Thanks, Fred!)

10 Unwritten Rules for a Consultant to Live By

Now I've never been a consultant myself, but I have friends who have been consultants. Namely Kyle. What do you think of these rules?

[Via DonXML Demsak's Grok This]
  1. You work for the client, not the consulting firm.  No matter who cuts the payroll check, the client is the one paying for your services.  Do the right thing for the client, not the consulting firm (or anyone else).
  2. Your network of consultants is your most important asset.
  3. Consultants should keep a blacklist of firms and other consultants that should be avoided, and why.  Share this list with your network of consultants but not to the general public.
  4. Do not make negative comments about another consultant within ear shot of an employee of a client, and especially around the sales and marketing people of a consulting firm.  Negative comments are fine between consultants, but, keep it “in the family”.  But, never break rule # 1.  When dealing with non-consultants, do like your mom always told you, “if you don’t have anything nice to say about someone, don’t say anything at all”.
  5. When your consulting firm takes you out to lunch, remember, you are really the one buying lunch.  It is coming out of the consulting firm’s cut out of your rate, so just pretend you are picking up the check.  Would you really want to pay to have lunch with this person?  The same thing holds true for all events and gifts you may get from the consulting firm.
  6. Avoid give consulting firms information on possible leads without first getting everything in writing (especially your commission).  And even then, the contract usually isn’t worth the paper it is written on.  Don’t expect to get any money for info on leads, so be careful who you give them out to.
  7. When referring another consultant to a consulting firm, expect a finder’s fee.  $2 per hour is the minimum that they should offer.  Flat fees typically benefit the consulting firm not you, so try to avoid them.  Remember, your finder’s fee is coming out of the consultant’s pocket.  So if the consultant is part of your network, you should waive the fee.  Your network keeps you employed.
  8. If you didn’t negotiate your rate starting at the consulting firms billing rate to the client don’t try to find out what it is, unless you are prepared for the consequences.   That knowledge will usually just make you disgruntled.
  9. Never tell the client what the consulting firm is paying you.  If they need to know, it is up to the firm to disclose that info (see rules #1 and #8).
  10. Avoid professional days.  You don’t bill for hours you don’t work, so you shouldn’t work for hours that you don’t bill.  A good project plan, with a budget to match it, is a must.  Unless of course, if you created the project plan, then you should live with the mess that you created.
[Listening to: Groove Salad - - (0:00)]

Ali G Gets Tossed Out By Andy Rooney

Ali GApparently, Andy Rooney has no patience for faux british rappers. If you've never seen the Ali G show, it's worth a watch. One of the funniest episodes I've seen was when he was visiting a K-9 police unit and asked the trainer in his "urban" style,
"Has yous eva thinks to use dogs instead of canines?"
To which the officer replied, canines are dogs. Ali G then asks,
"Ok, has you's eva thinks to use dolphins? I Heahs they's smarter than dogs."

Ali G once asked a former CIA director,
"Is yous worried dat da terrorists goin ta attack the White House with trains?"
The former director responded,
"No, there are no tracks leading to the White House."

"Perhaps theys building dem at night."

Boo-Ya Kashaa! Respek!

Thanks to DK for the scoop.

Becoming a Blogging "Category Hedonist".

When I started blogging, I was a category ascetic. I figured I should keep categories to a minimum across very strict dividing lines. I was going for a Zen approach. The thought process I had is that each category should be a worthwhile feed to subscribe. So that if you're one of my friends who doesn't know .NET from a fishing net, you could subscribe to my Day To Day feed.

But that doesn't exactly work as I don't cross-post often. Today I realized, I needed to break the ascetism and become a "Category Hedonist". I was trying to find every post I've written about category spam. I realized the only tool I had for finding those posts was Google. No longer. I've added several categories, and hope to add more in the hopes of categorizing (hey how about that? Categories are for categorization) my posts. It's useful for me, and hopefully for some of you.

In Need Of A Phil-Proof Alarm Clock

How's this for an idea? An alarm clock that only allows setting the alarm for the morning. No PM times allowed. I mean if you can't wake up by noon on your own, what's wrong with you?!

If you really need to set the alarm for a PM time, the clock can provide a special button to press while setting the alarm. But that button needs to be guarded by barbed wire and ill-tempered sharks with lasers on their heads. This is necessary to keep a groggy fool from accidentally holding the button down when he's only had 4 hours of sleep.

I missed basketball this morning because my clock was set for 6:30 PM.

Moving My Photos Off Of Ofoto

I received an email from Ofoto with the subject line "Your Ofoto images will be deleted on September 30, 2004". Yeah, that got my attention. According to the email, your account expires if you don't make a purchase every 12 months. At first, I assumed this was some sort of Phishing attack trying to get me to click on their bogus links. (NEVER click!). But I wrote customer service and sure enough, this was a legitimate email. They will delete my photos and pointed to the Terms Of Service (quoted at the bottom).

Fair enough, I can respect that the company wants to monetize its users. It's a nice service and they have every right to enforce such a policy. But it makes me wonder if this is a sound business practice or if it is a short sighted policy. For me, it just means that I'll move my photos to http://photos.yahoo.com/.

Up until right now, I was a fairly active user of Ofoto and often shared my album with others (those who did and didn't have ofoto accounts. It was viral marketing.). And I have made purchases in the past. In fact, my first gift to my wife (just after we first met) was from Ofoto. Given that, I wonder if the cost of storage of my photos is greater than the potential revenue loss of losing me as a user.

If they kept my photos, there's a greater chance I might make a purchase again than if they delete my photos. In that case, I'll certainly never make a purchase. And, I won't be spreading word of their site. Apparently Ofoto feels they can't make any money off of me. That's fine, it's business. See ya Ofoto.

Here's their storage policy if you use Ofoto.

Our storage policy is as follows:

When a new Ofoto member first uploads photos, they get 12 months of free unlimited storage, beginning on the date of that first upload.

When a member makes any Ofoto purchase, their free storage automatically extends for 12 months, beginning on the date of that purchase.

If a member purchases from another member's photos, both people get 12 months of free storage, beginning on the date of that purchase.

If 12 months pass without a purchase, the free storage expires and the stored photos will be removed from Ofoto.

To view our complete Terms of Service, please click the following link: http://www.ofoto.com/TermsOfService.jsp?

Please note that any purchase will extend your storage: That means a single Kodak print, an Ofoto Archive CD, or any of the goodies in the Ofoto Store will keep you in free storage for another 12 months, on a rolling basis.

If you have any further questions or concerns regarding your Ofoto account or the Ofoto service, please let us know.

ReSharper Property Expansion Live Template

One thing I liked about CodeRush is that it came with several property expansion templates. However, ReSharper comes with a powerful template expansion editor for creating your own templates similar to what Whidbey has. I took it upon myself to create one for ReSharper. I hope you find it useful. There's also a slight bug with this template in ReSharper that I will report to them (via this blog entry) and hope they fix.

To add this template, go to the ReSharper menu and click Options. Select the Live Templates node and click New. A window for creating a Live Template will appear. Fill it out as below.

Property Expansion Template
Figure 1: Live Template Editor.

Now, to use the template, type the letters "prop" (sans quotes) and hit the TAB key. This should expand to the following:

Specifying
Figure 2: Specifying the property type.

Don't let all the red squigglies worry you. As you can see in the figure above, the word TYPE is highlighted by a red box. Type in the type of the property and hit tab. This will then take you to the second argument of the template, the name for the private member. In the figure below, I chose string as the type.

Specifying the private member name
Figure 3: Specifying the private property member name.

At this point, you can type in the name of the private member that will hold the value of your property. Since I like to preface my private members with an underscore, you'll notice that the underscore is part of the template and is not typed in as part of the PRIVATEMEMBER argument.

As you are typing, you'll notice that public property name matches whatever you type for the private member, but with the first character capitalized as in Figure 4.

It's working.
Figure 5 Look ma, I can name a property!

Bug Alert! at this point, do not hit the TAB key. Even though we've set that the PROPERTYNAME is not editable, when you hit TAB after typing in the private member name, the cursor is taken to the end of the property expansion, but the PROPERTYNAME is removed. See figure 5. Instead, you're going to have to hit the down arrow a few times.

Property Expansion Lost The Name
Figure 5 Where's my property name!?

Conclusion
Hopefully they fix this in the next version, or provide a workaround or guideline for how a template like this should be built. I also wish there was an easy way for me to export a template so that I can share them easily. In any case, you can probably see all sorts of potential for these live templates. It's great for company specific boilerplate. If you have a greate template, post it in my comments section and I'll try to compile them.

Man I Love Blogging.

I'm hooked! To both reading blogs (via RSS feeds) as well as writing one. I'm addicted to poking my nose in the comments sections of other people's blogs. Maybe even where my nose doesn't belong. Almost certainly where it doesn't belong.

For some odd reason, I love spouting my opinion. I'll just give it out for free. You didn't ask for it? Well here it is anyways. It's not that I think I know more than you. Heck, most of the time, I don't even know if my opinion is right or wrong or even well informed. But I'll probably give it to you anyways. Perhaps I should think before I speak. But that's so in the past. I hope you don't mind. I really do like you all. Perhaps I just like hearing (or reading) myself talk.

I also like trying to be humorous. Now there's an area where I'm even more likely to fall on my ass. But you can't fault me for trying can you? You can? Well that's never stopped me before. My wife has learned that I have a very low embarassment quotient. I continually make a fool of myself, but am never embarassed by what I do.

The simple fact is that I like belonging to a community, any community. As long as there's give and take. I write something in my blog or on someone else's and someone responds. That feels good! Sounds like an old fashioned conversation you say? Well yes and no. As a conversationalist, I don't have the resources available to me as a blogger. For example, I have a terrible memory. In conversation I'll say,

"Yeah, uh-huh. Umm that's like, a really, like, good point dude. That, like, sorta reminds me of a great quote by that old dead guy... ummm Spinzer? Something about new ideas and ceasing."

But on a blog, I'm more apt to say,

Jolly good point chap, and a point well taken if I may say so. It reminds me of good old professor Chadwick at Cambridge who was fond of puffing on his oaken pipe and would read to us his favorite quote from the esteemed philosopher, Spinoza. If memory serves me correct, the quote was, "Be not astonished at new ideas; for it is well known to you that a thing does not therefore cease to be true because it is not accepted by many."

It's all about “Information At Your Fingertips” brought to us by Google.

Now back to the typical technical mumbo-jumbo.

ReSharper Reloaded

Ok, I tried CodeRush (an excellent product) and now I'm back to ReSharper. Valentin Kipiatkov, the Chief Scientist at JetBrains pointed out that there are several options that can fix some of my concerns and make it usable for me. The first concern was the intellisense delay.

The pause is intentional because you not necessarily want to use the intellisense after typing the dot. So it appears after a small delay (unless you continue to type). To change this, go to ReSharper | Options Code Completion and find "Delay:" field at the very bottom of the page. Change it's value to 0.

I'd recommend that 0 or 100 would be the default. But the fact that it is configurable is good enough for me. Another concern I had was that their intellisense listed all overloads when I just want a method list (like in VS.NET).

This is actually configured by an option but a weird point is that the default setting is exactly as you want (and as it is in VS), maybe you changed it occasinally? To configure that, go to ReSharper > Options > Code completion and uncheck "Show signatures" checkbox.

Excellent! Much better! Finally there's the pet peeve I mentioned earlier. Valentin points out an option that partially helps the situation:

auto-insertion of parens and braces can be configured by options in "Editor" page, "Auto-insertion" group box. As for your suggestion about braces, we'll think about it.

Awesome! I appreciate the excellent support, and I'm just a trial user. This is the kind of excellent customer support that will take this product far. I'm ready to recommend purchasing this for the development team at work. If you haven't tried it out, really give it a try. The refactoring and code formatting alone are worth the money. But it goes a lot further than that.

There are three big factors in this decision. The first is the refactoring support in ReSharper. That is very important to me. Secondly, the fact that there is excellent customer support. It's good to know that if there's an issue with the product, I'll get to hear from a human in a decent amount of time. Lastly, I have to admit that the price is a big factor as I plan to buy a license at home of whichever tool we use at work. ReSharper is more affordable than CodeRush, yet provides just as much a productivity boost and more code cleanliness boost (via refactoring support) overall in my opinion.

A Response To Shelley

Regarding my post on Women in XML which is really a post about women in software industry, Shelley writes:

I don't know where you work, but every place I've worked in over 20 years has had women.

Might try looking at the atmosphere of your company and why more women don't feel comfortable applying there.

In 1996, there were 378,000 science and engineering degrees awarded. Of these, 175,931 were given to women, 202,217 to men.

Many of the sciences were almost equal in participation based on sex -- including math. In computer science, though, there were 7,063 women to 17,706 men -- a greater disparity than most fields.

But even at that, women made up almost a third of the graduating program. These probably would have been the women you all might have been interviewing. Now, why do you think your company only got one woman?

I am glad to hear that her experience has been different from mine. And I didn't say that I NEVER worked with a female software developer. The person who first trained me was a female contractor. The president of my company was a former COBOL programmer. Sadly though the bulk of my software career (which is an admittedly short 7 years) has not been spent working with other talented female software developers. I believe I've missed out due to a lack of diversity.

However, assuming former company's atmosphere is at fault (especially not being informed about the company) is hardly constructive and is dismissive of our efforts at the time. It also oversimplifies the real issue. First, let me give some background.

I worked at a small custom software/consulting services of around 15 to 17 (at the height) people located in Santa Monica. Most likely, our small size was the biggest factor in our inability to attract women. I think it had very little to do with the company atmosphere. Consider that roughly half the employees (at the time) were women, just not software developers. The president (and half owner) herself was a woman and a former software developer keenly interested in attracting female software developers. She lamented the fact that there were so few candidates.

Our environment was not that of a Dot-Com. We had in-house day care with a talented and experienced caretaker, reasonable hours, and a flexible work culture. Our failure to attract women is probably (and I don't know all the answers here) due to several factors apart from the work environment. One of the simplest factors is that we were small. Nobody ever heard of us. The best way we knew to recruit was through job postings on websites such as Monster.com and Dice.com. However, there are much bigger societal and gender issues that we were probably bumping up against.

For example, research shows that not only are women less likely to separate from a job than men (Kulik, 2000), but also that women conduct a job search with less intensity than men (Keith, K. and McWilliams). I think this helps explain why we had so few respondents via the online job boards.

Cultural biases in our educations system and otherwise also have an affect on the number of candidates.

Girls and women are choosing, consciously or subconsciously, not to go into or stay in computer science. While one cannot rule out the possibility of some innate neurological or psychological differences that would make women less (or more) likely to excel in computer science, I found that the cultural biases against women's pursuing such careers are so large that, even if inherent differences exist, they would not explain the entire gap. [via Ellen Spertus: Why are There so Few Female Computer Scientists?]
Additionally, for many females, computers are more meaningful and compelling if they are able to link them with other fields and are able to keep computer science's social context in mind. Margolis and Fisher (2002) call this appeal "computing with a purpose." However, computer science curricula has traditionally been oriented on the basis of the fascinations of male students, and the aspects of computers that females find interesting may not be emphasized. This lack of emphasis on certain characteristics may discourage women, allowing them to feel computers "aren't for them." [via Maria Enderton: Honors Thesis, Women in Computer Science]

I think this points out that there is a real basis in saying that attracting women to a software development role in numbers on par with men is a difficult task. And for very small companies, it is difficult to even attract a few. This is not say that this is a good thing, but its the situation we're in. Rather than saying "Well you must be doing something wrong.", we need to ask "What can we do to improve the situation together?" Given the evidence I put forth, in the next couple months, I may be in a position to hire a developer or two as a senior development manager at a different company than the one mentioned here. What tips would you give me to hiring the best and the brightest?  At the end of the day, I think we're working toward the same goals.

Oh, and we actually work in the field because we like it, not because it's sexy. But is that why you work in the field? Because it's sexy?

Absolutely. Nothing sexier than typing on a keyboard all day bathed in the soft glow of two LCDs. Actually, I sort of fell into it. The remark that I made in my last post that programming has no "sex appeal" and that it isn't "sexy", that wasn't intended to be taken literally. My point is that software development is not generally seen as a field that can provide a fulfilling career opportunity for women, or the general public at large. It doesn't have a very positive exposure in the popular culture. When you ask a classroom of kids what they want to be when they grow up, you'll hear things such as "Doctor", "Lawyer", "Fireman". Heck, when you ask highshool freshman, you'll typically hear the same thing (I know, I used to teach a summer science and math enrichment program for gifted students about to enter highschool.) . But rarely will you hear "Computer Programmer." When I was a kid, my answer was always "I want to be a professional soccer player!"

footnotes

Keith, K. and McWilliams, A. (1999). The Return to Mobility and Job Search by Gender . Industrial and Labor Relations Review, 52(3), 460-477.

Kulik, L. (2000). A Comparative Analysis of Job Search Intensity, Attitudes Toward Unemployment, and Related Responses. Journal of Occupational and Organizational Psychology. 73, 487-500.

Girl Power! (And the women of XML)

Kill Bill Vol2Kill Bill
We finished Kill Bill Vol 2 last night and absolutely loved the entire movie. By entire movie, I mean part 1 & 2 combined. Part 1 was a more visual feast while the second produced the story and dialogue we expect from Q. My wife puts it among her favorites, mainly because she loves any movies with "Girl Power".

Women of XML
This brings me to the topic of "Women Power!" in relation to technology. Dare posts this most excellent list of some of the top women in XML.

This list is very encouraging. I have to admit, that personally, I've never worked with a female software developer or system administrator except for the first month or so of my first job. And this isn't for lack of trying. At my first company, the president was a woman, and all of our project managers were women as well. But the developers were all men. When we were hiring, my boss really hoped to see some qualified women come in to interview. If memory serves me correct, I remember interviewing a grand total of one woman. That's all that responded!

Unfortunately, there's a lot of factors involved that have kept women out of technology. Naturally, there's the workplace chauvinism encountered in the old days (and I'm sure even now). But there's also the bias that the current generation of employable women faced as young girls and in school. When you have a talking Barbie doll that says "Gee, Math is HARD!", what kind of message are you sending young girls?

Apart from the subtle sexism, there's also the fact that programming hasn't been marketed to women very well. It has no "sex appeal". Hopefully this is starting to change, but when the general public thinks about programmers, there's the image of the anti-social grungy pizza loving Coke fiend (cola I mean) who is isolated and seeks glory by working 80 hr weeks to put out the next version of "Kill Everything That Moves And Make Them Bleed" first-person shooter.

Where is the Ally McBeal of software development!? There's nothing inherently sexier about Law (as my lawyer friends can attest) than software. No really. Really!

Bear Drinks 36 Cans of Favorite Beer

Man, and I thought the bears in Alaska were tough.

AP - Rain-eeeeer .... Bear? When state Fish and Wildlife agents recently found a black bear passed out on the lawn of Baker Lake Resort, there were some clues scattered nearby — dozens of empty cans of Rainier Beer.
[Via Yahoo! News - Oddly Enough]

Cruise Control .NET Resources

Since I’m just getting started with Cruise Control, I thought I’d look around the web and blogosphere and put together some resources on configuring CruiseControl.NET.

And there’s also the CruiseControl.NET site itself and the community site.

After reading through many of these resources, I have a question about directory structures. You see, I try to be an obedient Microsoft developer (will it pay off?) and set up my directories as outlined in the Microsoft Patterns & Practices article Team Development with Visual Studio .NET and Visual SourceSafe.

The article proposes that you group code into "Systems" which may contain one or more VS.NET Solutions. A Solution of course may contain one or more Projects. Below is figure 3.5 from the article illustrating the directory structure.

Directory Structure
Figure 3.5. Visual Studio .NET and VSS Folder Structure

In general, projects and solutions won’t be shared across systems, i.e. a solution in one system won’t reference a project in another. However I do have one exception in that I have a code library system with projects that other solutions may reference. For example:

Projects
    CodeLibrarySystem
        CodeLibrarySolution
            Project1
            Project2

    SomeOtherSystem
        SomeSolution
            Project1
            Project3

So, in my case, should I map a CruiseControl.NET project to a System or a Solution? Any recommendations?

Technorati tags:

Why The ThreadPool Is Very Often The Way To Go

In a previous post, I talked about Anynchronous sockets and its reliance on the ThreadPool and made an uninformed remark about potentially needing to up the ThreadPool count. Ian posted a comment describing why the ThreadPool is very often the way to go for socket programming, correcting my assumption. But as always, measure measure measure to be sure. Go read it. Thanks!

Technorati Tags:

Moderating Comments. How About An API?

I've heard a lot of complaints about what a b*tch moderating comments turns out to be. So why not create an API for moderating comments?

Suppose your blog engine put all incoming comments in a private authenticated RSS feed. You can then subscribe to this feed and for each item, hit "YES" or "NO" via your RSS Aggregator. I'd be willing to write an IBlogThis plug-in to support such an API if someone adds it to the various blogging back-ends. If it caught on, I'd be happy to add it to RSS Bandit if Dare and Torsten like the idea and approved it.

The API would probably be similar to the CommentAPI or my RatingAPI, but with a few modifications specific to comments. I'll propose one later.

Question: When Is A Good Time To Call GC.Collect()?

Answer: When you don't have enough change for the phone booth.

I'll be here all week, thank you very much. Bad pun notwithstanding, the answer to this question is pretty much never (see Rico's almost rule #1). The Garbage Collector in .NET is like a highly motivated and skilled employee. If you quit being a micro-manager ("You forgot to put the cover sheet on the TPS report") and stop looking over its shoulder, it's able to just do its job and perform quite well.

However, note that Rico says "Almost Rule #1". That must mean there are appropriate exceptions to the rule, no matter how few they may be. What are those situations? The reason I ask is I ran into the following code on the net (dramatization):

/// 
/// Stops the socket server and closes 
/// every client connection.
/// 
public void Stop()
{
    if(_isDisposed)
        throw new ObjectDisposedException(
            "SocketServer", 
            "Object is already disposed.");

    CloseConnectedClients();
    CloseListener();

    GC.Collect();
    GC.WaitForPendingFinalizers();
}

This is the Stop() method of your typical Socket Server. It closes any connected socket clients and then closes the listening thread. After that, it calls GC.Collect() and GC.WaitForPendingFinalizers(), violating Rico's almost rule. Is this perhaps one of those appropriate times to call GC.Collect()?

Typically, your socket server will have been running for a long time, so it is very likely it will have been promoted to Generation 2 and contain references to a several other Generation 2 objects. Rico points out that

If your algorithm is regularly producing objects that live to gen2 and then die shortly thereafter, you're going to find that the percent time spent in GC goes way up. Forcing more of these collects is really the last thing you wanted to do (assuming you could, note again GC.Collect() doesn't promise to do a gen2 collect).

However, this is situation is different in that the server has been around a while and calling Stop() on a server typically means you're not planning to use the Server any time soon afterwards. In fact, you're most likely about to dispose of it.

Given that, It seems to me that this might be one of those cases where calling GC.Collect() is appropriate. The goal here is a one time Generation 2 collection. Of course, there's no guarantee that a Generation 2 collect will occur. Maybe this is a situation where it makes no difference either way. Any thoughts?

For more reading:
Garbage Collector Basics and Performance Hints
Programming For Garbage Collection

Ugly Basketball

BasketballBasketball was ugly this morning. Lots of bickering and fouling. Dan, you didn't miss much man. Sometimes you just want to slap everyone upside the head and tell them to grow up and graduate from Pre-School. But that's insulting to pre-schoolers who are much more mature than the fellas this morning. Then again, sometimes you wish you'd just make the damn game winning shot instead of clanking it in and out.

Resharper Pet Peeve

One pet peeve I have is how the auto completion works regarding methods. I know this is nitpicky, but I'm wondering how other IDE's that try to help you handle this. Suppose I type out the following and am about to hit the open parenthesis character.

public void SomeMethod

Resharper automatically adds a closing parenthesis and puts your cursor in between them.

public void SomeMethod(Cursor Is Here)

Now the reason I don't like this is after I'm done typing the arguments, I still have to type a character (either a closing parenthesis which it absorbs or a right arrow key) and then type my open brace. I'd prefer it if it didn't add the closing parenthesis and instead, when I did close the parenthesis, it would automatically add the open and close brace. Thus the sequence would look like:

public void SomeMethod(object someParam 
[about to type closing parens]

to

public void SomeMethod(object someParam)
{
    Braces added automatically and Cursor is Here
}

This makes more sense to me as this is where I'm going to be spending more of my time. In any case, if I'm just being a whiner, I can live with that. I haven't played enough with Whidbey or other IDE enhancements to know how they handle this situation. It's the little things that count.

First Impression of Resharper 1.0.2: It's Sloooow

Resharper After hearing so much about how IntelliJ IDEA is the ideal IDE and blows every other IDE to smithereens from various Java pundits (and even a friend who's a C# and Java developer), I was excited to try out Resharper 1.0.2 from Jetbrains, the maker of IDEA.

Installation went smoothly and I really am impressed with all the productivity enhancements contained within this tool. Rather than wait for Whidbey, I can have code expansions and refactoring NOW! The code formatting feature will surely help your team avoid coming to blows over such important and divisive issues such as "curly brace on its own line or after a method declaration?". Everyone can have the code formatted to his or her own tastes. There's a whole slew of other noteworthy features I won't go into.

The one problem I have with ReSharper, and this is a doozy, is that it replaces the VS.NET Intellisense with its own, and its implementation way too slow for real development. Note that I'm running a fairly decent machine: Pentium 4 1.7 GHZ 512 MB of RAM. One thing I appreciate about VS.NET's Intellisense is that it is snappy and can keep up with me. So it's a huge detriment when I'm typing along and hit "." and have to wait a second for the auto-completion box to display. I hope there's a way to disable the auto-completion, but maintain all the other great features. Otherwise I'm afraid I will have to uninstall this.

Anyone else have good or bad experiences with this product? Any recommendations?

UPDATE: I couldn't take it any longer. I had to uninstall this. It's a shame

Little Man In The Box

Odd yet interesting.

SURVEY: Team Development with Visual Studio .NET and Visual SourceSafe

Patterns and Practices I'm trying to convince my coworkers that we should use the Isolated development mode for ASP.NET projects as described in the Patterns and Practices document Team Development with Visual Studio .NET and Visual SourceSafe. They've agreed to read the document and we'll meet to discuss. I hope the document convinces them, because I've had too many headaches in the past dealing with FrontPage extensions.

My question to you all out there is do you set up your own development environment according to the guidelines set out in this document? How is it working for you or how have you changed it?

A Niggle or Two About Asynchronous Sockets And Thread Safety

Ian Griffiths finds a niggle about my post on sockets.

This may surprise a few friends of mine who regard me as a "human dictionary", but I had to look up the word "niggle". Apparently only the "human" part of the appellation applies. I've apparently fooled them by reading a lot of sci-fi fantasy and choosing to learn and use "impressive" words such as Bacchanalian in everyday conversation ("I wrote this code in a drunken stupor from a bacchanalian display of excessive beer drinking."). It's really all smoke and mirrors. But I digress...

His comment is quite insightful and well worth repeating here in full.

One minor niggle with this code...

Although the example is correct as it stands, it doesn't mention an important issue: the Socket class is not thread-safe. This means that if you do use the async operations (and by the way, I'm completely with you here - I'm a big fan of the async operations) you need to take steps to synchronize access to the socket.

As it stands there's nothing wrong with this example as far as I can see. But what if you also have an asynchronous read operation outstanding? Can you guarantee that a read and a send won't complete simultaneously, and that you'll be trying to access the socket from both completion handlers simultaneously.

So in practice, you tend to want to use some kind of locking to guarantee that your socket is only being used from one thread at a time, once you start using async socket IO.

(Also, you left out one of the clever parts of IO completion ports - the scheduler tracks which threads are associated with work from an IO port, and tries to make sure that you have exactly as many running as you have CPUs. If one of the threads handling work from an IO completion port blocks, the OS will release another work item from the completion port. Conversely, if loads of IO operations complete simultaneously, it only lets them out of the completion port as fast as your system can handle them, and no faster - this avoids swamping the scheduler under high load.)

I have to say, Ian's depth of knowledge on such topics (or nearly any geek topic) never ceases to impress me. Fortunately for my app, the client socket only receives data every three seconds and never sends data back to the remotely connected socket (how boring, I know). In any case, I will double check that I am synchronizing access to the socket just in case. Perhaps I'll use the TimedLock to do that. ;)

While we're in the business of finding niggles (Ian, you've hooked me on this word. For some strange reason, I can't stop saying it) I should also point out that IO Completion ports awaken threads from the ThreadPool in order to perform an asynchronouse action. The entire asynchronous invocation model of .NET is built on the ThreadPool. Remember that the next time you call a method that starts with "Begin" such as "BeginInvoke". Chances are, it's using a thread from the ThreadPool (especially if its a framework method. I'll make no guarantees for methods written by your coworkers.)"

By default, the max threadcount for the ThreadPool is 25 per processor. In my application, the remote socket sends short packets of data on a regular interval, so the threads that handle the received data are very short lived. Sounds like an ideal use of the ThreadPool doesn't it? However, if I were expecting a huge number of simultaneous connections, I might look into changing the machine.config file to support more than 25 ThreadPool threads per processor. Before making any such change, measure measure measure.

If you have a situation where the operations on the data are long lived, you might consider spawning a full-fledged thread to handle the remote client communications and operations. Long running operations aren't necessarily the best place to use a thread from the .NET built in ThreadPool.

Technorati Tags: ,

Deep Dish

No, I'm not talking about Pizza from Chicago. I'm talking about this dynamic duo:

Deep Dish

As you can see at the bottom, I'm listening to their remix of Dido's Thank You which won a Grammy. These guys are one of my favorite electronica bands out there. They're much more in the deep funky progressive house area. Somewhat dark, without being too malicious. I highly recommend you check them out. Especially this Dido remix.

[Listening to: Dido . Thank you - Deep Dish - Global Underground 021 - Moscow CD1 (7:25)]
Technorati Tags:

Help Make Blogs More Visible!

There are by some estimates more than a million weblogs. But most of them get no visibility in search engines. Only a few "A-List" blogs get into the top search engine results for a given topic, while the majority of blogs just don't get noticed. The reason is that the smaller blogs don't have enough links pointing to them. But this posting could solve that. Let's help the smaller blogs get more visibility!

This posting is GoMeme 4.0. It is part of an experiment to see if we can create a blog posting that helps 1000's of blogs get higher rankings in Google. So far we have tried 3 earlier variations. Our first test, GoMeme 1.0, spread to nearly 740 blogs in 2.5 days. This new version 4.0 is shorter, simpler, and fits more easily into your blog.

Why are we doing this? We want to help thousands of blogs get more visibility in Google and other search engines. How does it work? Just follow the instructions below to re-post this meme in your blog and add your URL to the end of the Path List below. As the meme spreads onwards from your blog, so will your URL. Later, when your blog is indexed by search engines, they will see the links pointing to your blog from all the downstream blogs that got this via you, which will cause them to rank your blog higher in search results. Everyone in the Path List below benefits in a similar way as this meme spreads. Try it!

Instructions: Just copy this entire post and paste it into your blog. Then add your URL to the end of the path list below, and pass it on! (Make sure you add your URLs as live links or HTML code to the Path List below.)

Path List
1. Minding the Planet
2. Luke Hutteman's public virtual MemoryStream
3. JayBaz_MS blog
4. You've Been Haacked! and you like it.
5. (your URL goes here! But first, please copy this line and move it down to the next line for the next person).


(NOTE: Be sure you paste live links for the Path List or use HTML code.)

[Via Luke Hutteman's public virtual MemoryStream]

Pictures From Naches Peak Trail Near Mt. Rainier

Having been on one of the most beautiful hikes during our trip to Seattle, it would be a grave disservice not to post a few pictures of the hike here. For all you Microsofties out there (and other geeks in Washington state), I highly recommend getting out of the office for this hike. Bring some water and sunscreen.

The four to five mile trail begins on the Pacific Crest Trail No. 2000 (the entire Pacific Crest Trail stretches from Canada to Mexico) from Chinook pass. At the parking area, you'll cross Route 410 by walking on a wooden overpass seen above. The two in the picture below are the friends we visited, Dan and Grace Kalish.

Beginning of the hike
Car careens off the road while hikers wave at camera.

After a bit of hiking, through lush green forest, we came upon the first of several lakelets. The hike has an elevation gain of just 700 feet, so it's fairly easy, though we managed to make it a challenge by taking a wrong turn and visiting a full fledged lake. The detour set us back around another half hour.

A lake
Dan wonders how those people in the lake got so small

Akumi and I had a plane to catch that evening and we were running out of time and getting a bit worried. It took us a bit longer than we expected to get out here, and the unexpected detour cost us even more time. At that point, we decided to play it safe and return back the way we came and not complete the loop. What a terrible decision that would have been. When we returned to the main loop, another hiker told us we were exactly halfway around the loop. That led to the obvious conclusion that we should continue. What a fortuitous decision, as this trail saves all the best views for those willing to stay for act 2.

Mt. Rainier
You've seen one picture perfect lake surrounded by violet wildflowers in the woods with an enormous mountain backdrop, you've seen them all.

Phil has a snack
Man loves nature. Man eats nature.

Not one to let a photographic opportunity go by, we made sure to pose for a group shot with our new friend, Mt. Rainier. As big as it looks in the photos, it looked absolutely ginormous in person. It positively encroaches on us as we take this shot.

Group Shot
That cardboard backdrop is so damn convincing!

For most of the rest of the hike, we were treated to wonderful views of the mountain. It started to get rather blase. "Yet another view of the one of the most spectacular woodland scenes I've ever seen. Ho hum."

Hiking along
Tired of my incessant demands to stop and pose, my friends pose a mutiny.

Wildflowers
Rainier tries to hide behind some trees.

At the end, the hike ended up being reasonably vigorous due to our detour, but quite manageable over all. The next time we hike here, we plan on making it a picnic next to the lake with the view of the mountain. I highly recommend this hike.

Directions From Seattle: via the Seattle Post Intelligencer
Go south on Interstate 5 and take the state Route 18/Auburn exit (before Tacoma). Follow the signs to Auburn and state Route 164 (take the second Auburn exit off Highway 18, not the C Street exit). Follow 164 through Enumclaw to state Route 410 and turn left. Continue east to Chinook Pass, about 44 miles from Enumclaw. At Chinook Pass, continue a short distance past the wooden overpass to a parking area on the left side of Route 410 (the Mather Memorial Parkway). This is the parking area for the PCT with stock access and portable toilets, elevation 5,040 feet. If you are beginning from Tipsoo Lake, park at the Tipsoo Lake picnic area lot and look for the signed Naches Peak Loop trailhead opposite the lake.

Blocking Outgoing Messages

Dave Winer writes:

There's something missing from Windows. An application that hooks into the outbound Internet message flow, and shows me where messages are going. This would allow me to figure out what spyware is running on my system even if the various utilities can't get rid of them. Then the next step would be to allow me to block traffic to certain servers. That would disable the spyware. It seems that I should have control of my machine at that level.

And Jeff Sandquist responds that Windows XP SP2 can do this via the new firewall, but look again. The firewall built into XP blocks incoming traffic, not outgoing. My guess is that feature will come with SP3. For now, I recommend the free version of ZoneAlarm which is perennially considered by many to be the best desktop firewall software out there. It will notify you when an application tries to send an outgoing message to the internet and its quite easy to configure.

Is Your Dog a Sh*t Factory

This is too funny. Rory talks about his dog and his visionary ideas for improving dogs in general.

Read It...

Why Block At All? Thoughts on threading and sockets

The path of least resistance when writing threading code as well as socket communications is to use techniques that cause indefinite blocking of some sort. Personally, I prefer never to block indefinitely. For example, it's quite common to see code such as:

lock(someObject)
{
    //Do Something here...
}

Nothing wrong with this inherently, but this piece will try to acquire a lock on someObject indefinitely. Imagine if you mistakenly had code like (yes, it's a bit contrived)

using System.Threading;

//... other stuff ...

object someObject = new Object();
object someOtherObject = new object();

public void LockItUp()
{
    lock(someObject)
    {
        Console.WriteLine("Lock 1 acquired.");

        ManualResetEvent mre = 
                new ManualResetEvent(false);
        WaitCallback callback = 
                new WaitCallback(ThrowAwayTheKey);        

        ThreadPool.QueueUserWorkItem(callback, mre);
        
        // wait till other thread has lock on 
        // someOtherObject
        mre.WaitOne(); 

        lock(someOtherObject)
        {
            Console.WriteLine("I never get called.");
        }
    }
}

void ThrowAwayTheKey(object resetEvent)
{
    lock(someOtherObject)
    {
        Console.WriteLine("Lock 2 acquired.");
        ManualResetEvent mre = 
                resetEvent as ManualResetEvent;
        if(mre != null)
            mre.Set(); //original thread can continue.

        lock(someObject)
        {
            Console.WriteLine("Neither do I");
        }
    }
}

Calling the method LockItUp will cause a deadlock and the application will hang until you kill it. Although this example is a bit contrived, you'd be surprised how easy it is in a sufficiently large and complicated system with multiple developers for you to run into this situation in a more roundabout manner. I see this often enough because using the lock statement is the path of least resistance. Instead, try using the TimedLock struct.

Another situation this type of thing comes up is with socket programming. Often I see code like this:

using System.Net.Sockets;

//... other stuff ...

byte[] _buffer = new byte[4096];
public void Listen(Socket socket)
{
    int bytesRead 
        = socket.Receive(_buffer, 0, 4096
                , SocketFlags.None);

    //You're sitting here all day.
}

If the remote socket isn't forthcoming with that data, you're going to be sitting there all day holding that thread open. In order to stop that socket, you'll need another thread to call Shutdown or close on the socket. Contrast that with this approach:

byte[] _buffer = new byte[4096];
public void BeginListen(Socket socket)
{
    socket.BeginReceive(_buffer, 0, 4096
            , SocketFlags.None
            , new AsyncCallback(OnDataReceived)
            , socket);
    //returns immediately.
}

void OnDataReceived(IAsyncResult ar)
{
    Socket socket = ar.AsyncState as Socket;
    int bytesRead = socket.EndReceive(ar);
    
    //go on with your bad self...
}

BeginListen returns immediately and OnDataReceived isn't called until there's actual data to receive. An added benefit is that you're not taking up a thread from the ThreadPool, but rather you're using IO completion ports. IO Completion ports is a method Windows uses for asynchronous IO operations. When an asynchronous IO is complete, Windows will awaken and notify your thread. The IO operations run on a pool of kernel threads whose only task in life is to process I/O requests.

Since BeginListen returns immediately, you're free to close the socket if no data is received after a certain time or in response to some other event. This may be a matter of preference, but this is a more elegant and scalable approach to sockets.

For more on asynchronous sockets, take the time to read Using an Asynchronous Server Socket and related articles.

Technorati Tags: ,

TimedLock Success Story!

This seems to be my favorite geek subject, but I have to tell you a success story using Ian Griffith's Timed Lock struct with my enhancement.

To recap, when you fail to acquire a lock on an object because another thread already has one, my enhancement allows you to see the stack trace of the blocking thread. Well the other day, I was running a suite of unit tests against a socket server I was building when one of the tests failed with a ThreadTimeoutException. Looking at the stack trace, I found the line of code where another thread was unnecessarily holding a lock on the object. I used to spend a lot of time poring through logs trying to decipher threading issues such as this.

Technorati Tags: ,

Writing Software Is Easy. Clients Make It Hard.

Patrick Cauldwell points out that the challenge of coding a business app isn’t in writing the code, that’s easy. The challenge is in understanding business requirements, and not because developers and architects can’t understand plain English.

In my experience, I find that often, “business people” (for the lack of a better word) do not apply the same rigor to developing a business model for an application as developers do towards requirements gathering, specifications, and coding for the application.

I understand that agile methodologies are designed to help manage change, but even they can’t keep up when the business owner doesn’t even know what the requirements should be, but is spouting them out anyways. What do you do when the business owner has been involved in every step of the project, played with every prototype and interim release, but at the end says, well that’s not what I want.

For ~95% of business software, the actual code needed to implement them ends up being, if not trivial, then at least not technically challenging.  Business software projects go over budget/schedule etc. because the business rules aren’t known (to anyone) or because no one in the organization really knows what they want.  ...snip...

So when people complain that projects are going way over budget/schedule/what have you, it’s almost always (in my experience) due to the fact that engineers spend 6 hours a day poring over vague and conflicting sets of documents, and 2 hours writing code.

[Via Patrick Cauldwell’s Blog]

As a developer friend of mine used to say,

This job would be great if we didn’t have clients.

Of course I prefer the paycheck.

How To Be Lazy...or...Understanding Requirements

If you’re a lazy mofo like me, there’s one thing you’re not lazy about, getting out of having to do a lot of work. An important skill that should be on every lazy developer’s utility belt is the ability to understand requirements.

However, there’s a subtle technique to this. When I say, “understand requirements”, I don’t necessarily mean understanding what the client tells you the requirement is, but taking a moment to dig deeper and get to the real purpose of the requirement. Let me tell you a story based on a true story.

WeLikeCustomers.com has a two email systems for communicating to its clients. One system sends news letters and “Please come back” emails to clients who have opted in. The other system sends emails welcoming newly registered users as well as password reminders etc... The second system is designed to send only the most important emails so as not to get blacklisted.

Millard in Marketing decides that the second system should route emails through an email delivery service that guarantees delivery. He tells Damien the developer that only emails in a certain category should be sent through the new delivery service, and all others should be sent in the current manner.

Well Damien thinks about it and tells Millard it will take a day or so to add this routing within the second system. Currently the system only supports sending emails to one configured SMTP server. Now he has to add the ability to send some emails to another SMTP server based on certain criteria. He dives right into designing a general purpose email routing system. After a bit of time, he has the sudden thought,

“Now why the hell are they routing only a portion of emails to this new service anyways?”

So he asks Millard, who replies,

“To make it easier for you of course.”

After some discussion, Damien finds out that Millard would prefer to send all emails to the delivery service. So he changes one setting in his config file pointing to the service’s SMTP address, closes his office door, and takes a nap. Meanwhile, Millard is sending out emails complimenting Damien for going above and beyond the call of duty.

Be like Damien.

The Odd LA Pickup Joint

I'm happily married, but if you're not, and you live in L.A., I recommend you take your dog for a walk at the Barrington Dog Park, on the east side of Barrington just south of Sunset. We were playing a game of soccer, but we couldn't help noticing that all the talent was in the dog park area adjacent to us. Looked like a bonafide LA pickup joint.

Alaska. We'll Pay You To Live Here.

UPDATE: I cannot help you move to Alaska. This post was written in 2004. If you want to move to Alaska, please don’t contact me. Try looking for information at the official Alaska homepage. Thanks!

Alaska’s Flag As a relocated Alaskan, I read Rory’s post about moving Canada to the right a bit so that Alaska could join the “lower 48” with amusement. I don’t think that idea would go over too well with Alaskans, as we...er...they take great pride in their independence, not only in spirit, but in location. Not only that, it could affect the fishing season, and you don’t mess with the fishing season in Alaska, the biggest state in the Union. That’s right Texas, the stars at night are even bigger and brighter in Alaska. Get over it, we rule you.

Alaska Map However, Alaska is not paradise on Earth (except in the summer when the sun stays out quite late drinking and carousing). Did you know they pay residents to live there? It’s a little thing called the "Permanent Fund Dividend". The Permanent Fund is a huge investment of oil revenues in a variety of stocks and bonds. Around October of every year, the interest earned from the fund pays each resident anywhere between 1 to 2 grand a year, depending on how well the market does. Just in time for some good Christmas shopping.

Not only that, there’s no sales tax and no income tax in Alaska. Yeah. Starting to sound like a good place to live, no? Well, before you rush off to go panning for gold, keep in mind that winter lasts around 8 to 9 months of the year, so I hope you like winter sports.