Archive for August, 2008

Software Development Books: Investing In Yourself

10 commentsWritten on August 24th, 2008 by
Categories: Books, Software Development

I currently have 20 books in my list of recommended books. I've read all of those books in the past 2 years, which means i'm averaging about 10 books a year. That's probably a bit much, and i have to admit i've been reading a bit less lately than i used to. But i've noticed that a lot of developers that i know hardly ever read books about software development. Which is too bad, because those books really are a cheap way of investing in yourself and your career.

Well, perhaps cheap isn't the best word to use. After all, some of these books are somewhat expensive, and buying a lot of them certainly adds up. But if you pick the right books, they are usually more than worth the money they cost. Besides, you shouldn't just look at the price of the book. The most important thing to keep in mind is the knowledge and insight you can get from them. That typically depends on the type of books you buy though. I usually avoid books that are library/framework/language-specific, unless i am very interested in a specific topic.

The books that usually provide the biggest value are the ones that teach you things that you can use in any development environment. It can be about development methodologies, certain concepts or practices, patterns (not just design patterns but architectural patterns, coding patterns, testing patterns, ...), as long as the knowledge is reusable. These kinds of books allow you to learn from the experiences of some of the best people in this industry. And the best thing about it is that you can learn a lot from these books in a few days (or weeks), even though it probably took the authors a couple of years to acquire that knowledge and experience. Isn't that one of the coolest forms of reuse you can think of?

Now obviously, reading a couple of books won't instantly put you on the same level as the authors, but at the very least it allows you to significantly increase your skills and insight with relatively little effort. And when you start applying that knowledge, you can start reaping the benefits of it pretty soon. It could definitely make your job easier. It most likely will increase the quality of your output at work. It almost certainly increases your value as a software developer.

So do yourself (and everyone else) a favor, and read a good book on software development once in a while. And if you need some help picking out the good books, just look here :)

Easing The Pain Of WCF Debugging

16 commentsWritten on August 20th, 2008 by
Categories: WCF

WCF is pretty cool, i guess. It's quite powerful, and it's so configurable it even has options to control the speed of the CPU fans of the users of your service. Ok, maybe you can't really configure that, but with approximately 12.4 billion WCF configuration settings available to you, who knows? But the biggest problem i have with WCF is the painful debugging experience when something goes wrong.

Ever got a client-side exception that looked like this?

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
   System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +73
   System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +110

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
   System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +183
   System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +54
   System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +32
   System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count, TimeSpan timeout) +32
   System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count) +53
   System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +37
   System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +131
   System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +28
   System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +223

[IOException: The read operation failed, see inner exception.]
   System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +333
   System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count) +79
   System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +72

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.8590000'.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +7594687
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +275

Rather messy, no? Does it give you any clue as to what could possibly be wrong? Nope. This particular client-side exception occurs when something goes wrong server-side, at some point after you've already returned your return value in your service implementation. Of course, you don't actually see it happening server-side. So i tried setting IncludeExceptionDetailInFaults to true on the service implementation... didn't make a difference. I set IncludeExceptionDetailInFaults to true on the service host but that didn't work either. Sigh.

After some Live Searching (i was actually googling, but let's make Microsoft think at least someone outside of Redmond uses Live Search) i discovered that you can enable WCF tracing. Bingo! Why didn't Juval Lowy's book mention this? It's supposed to be the WCF Bible.... Oh well, thanks to Google, i mean Live Search, we now know how to enable WCF's tracing:

  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="wcfTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WcfTrace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

You can also use the Service Configuration Editor tool which is available in the Windows SDK, but spare yourself the pain of that tool and just copy/paste this xml in your config file.

Now run the service again, and do whatever it was that triggered the weird client-side exception. After the exception occurred, open the WcfTrace.svclog file with either an editor (it's not very readable though) or with the Microsoft Service Trace Viewer tool (which is not too bad actually).

When i opened my trace output, i immediately saw a red item in the Activity list... so i clicked on it, and i finally saw the problem:

There was an error while trying to serialize parameter http://tempuri.org/:ProcessReadOnlyRequestsResult. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '. Please see InnerException for more details.

There we go... the client-side exception was terribly useless, but this is the best kind of exception: not only is it clear about what's wrong, it even gives you the solution to the problem. Btw, if you get that client-side exception, it doesn't mean that your problem will be the same as the one listed here. It could literally be anything if it doesn't happen inside of your service implementation. I've seen the same client-side exception when one type somewhere in the object graph didn't have a DataContract attribute, for instance.

So anyways, do yourself a favor and enable WCF tracing while you're still in development... it could save you a lot of time.

Oh and bonus points go to whoever points out which of WCF's many configuration settings actually make the real exception appear in the client-side stacktrace :)

Thank you, Visual Studio 2008 SP1

9 commentsWritten on August 20th, 2008 by
Categories: IDE

finally :)

The CI Build should be a given

2 commentsWritten on August 19th, 2008 by
Categories: Continuous Integration

Just read an interesting post by Tim Barcz. It's about a team struggling to adopt agile practices, and if given a chance to start over, what they should set up first: a CI build or a unit testing process.

I don't understand why someone would even have to choose between them. Setting up a regular CI build (with that i mean a simple compile + running all the tests) for a project should never take more than 10 minutes, tops. That is assuming that you already have a build server in place, obviously. But with Team City being so incredibly easy to install and configure, that can no longer be an issue.

So what does it take then? Drop in a simple, standard build script which builds your project and runs the tests, add a build configuration and you're done. Setting up a basic CI build should never take more work than that, unless you have some very specific needs, or the project structure is somewhat messy... as in: it doesn't compile if you don't have certain assemblies in folders that are either hardcoded or 'assumed' to be there... which should be avoided at all times :)

Seriously though, long build scripts or requiring a lot of time to set up a new CI build are all signs that your CI process in general needs some refracturing (nope, not a typo).

And in case you needed some motivation: even TFS 2008 allows you to set up a CI build in less than 5 minutes of work :)

Dealing With Recruiters

5 commentsWritten on August 18th, 2008 by
Categories: Off Topic, Rants

One of the things i dislike the most about being a developer is dealing with recruiters. Even if you're not listed on any of the job-sites, these people still call you, often in the middle of the workday. I generally feel uncomfortable when you have to deal with a call like that while you're at work because i don't want people to think i'm looking for another job (which i'm not). So i keep the sound of my phone off, and i only answer calls from numbers that i have in my contacts or recognize. If i don't know the number, i divert the call to voicemail (and i don't really listen to those messages either).

So today i noticed that a certain number tried to call me 4 times. Of course, i don't pick up. Tonight after work though, i was expecting a call from someone else and i accidentally answered a call from the same number that had tried to call me today. Turns out it was some recruiter.

Him: "Hi I'm So AndSo from DevelopersMeatMarket and i was wondering if you were looking for a new career opportunity" Me: "Nope, not interested" Him: "I actually tried calling you a few times today, don't you even wanna hear me out?" Me: "Not really... I actually try to avoid recruiters, to be honest" Him: "Well, you do realize that recruiters are an important part of this business, right? After all, we're the people who get developers great jobs. Answering those calls is very important for your career."

owkey... if there's one thing i dislike more than dealing with recruiters, it's dealing with recruiters with an attitude.

Me: "Oh really? So tell me, what do you say to your customer when he starts complaining to you that i'm spending too much time dealing with recruiters for my next job?"

At that point he sounds uncomfortable, as if he had no idea how to respond to that.

Me: "Or should i start ignoring other recruiters once i start working for your company?"

Him: "Well, umm... "

Again, silence.

Me: "Right, i think we can wrap up this conversation... good luck finding somebody"

And then i hung up. When will they learn?