Sunday, May 30, 2010

Apple Overtakes Microsoft in Market Value

Apple Overtakes Microsoft in Market Value: End of an Era?: "At the close of Wednesday’s trading, Apple was valued at $222 billion, while Microsoft was worth $219 billion. Apple’s shares ended the day at $244.11, while Microsoft’s finished at a seven-month low of $25.01. And it isn’t only Cupertino’s successes, but also Redmond’s failures that are responsible for the new power dynamic between the two companies. Overall, Microsoft stock is down 20 percent compared to 10 years ago, while the value of Apple’s has grown tenfold over the same period."

Saturday, May 15, 2010


A great animated video for a TED talk by Daniel Pink related to his recent book Drive.

Thursday, May 13, 2010

Third Time is the Charm

I decided that for what I needed Netty (or Mina) was overkill.

So I rewrote my server code using thread-per-connection and blocking io. I still used NIO Channels because I wanted to be able to use gathering writes (and because it was closer to the previous code).

And I still had the same problem!

That tells me it probably wasn't a mistake in my NIO non-blocking Selector version.

And the same fix "worked" for this version. (synchronizing the SocketChannel write)

That seems to indicate the problem is really in SocketChannel.write (or ByteBuffer)

I posted a question on the network forum on Sun (or should I say Oracle) but so far no response.

So I rewrote the server code a third time, using just old style Socket, no NIO, no channels.

This time it seems to work!

On the positive side, the blocking, thread-per-connection versions (with channels or sockets) seem to be about 15% faster than the non-blocking Selector version.

Assuming I don't find any problems, and depending on what (if any) response I get to the forum question, I'll probably go ahead with this version.

Tuesday, May 11, 2010

Not Making Sense

Two more days working on my concurrency bug. I'm growing less and less confident that I'll "figure it out". The more I narrow it down, the less frequently it happens, which makes it more and more difficult (and time consuming) to know whether I've "fixed" it.

I'm really reluctant to say it, but I'm starting to wonder if there's a bug in Java. I have it narrowed down to where I check the data on the server immediately before writing it and it's always ok. But every so often the client will receive garbage. (Which usually leads to a timeout because it's waiting for a newline.) I'm pretty sure it's not a problem on the client side because it only happens when the server is multi-threaded.

If this was C or C++ I'd assume I had a bad pointer and was overwriting memory or that I was referencing memory that was prematurely free'd. But that's not supposed to be possible in Java.

There is no concurrent access in my code to the data that is being sent. I don't reuse the buffer or anything like that. I've tried using a read-only buffer, and I've also tried allocating a fresh buffer every time.

I have found a "fix". If I synchronize the channel.write on a global object, so only one thread can write at a time, then it seems to work. At least I've run it for about 10 times as long as it usually takes to get a failure.

But this "fix" makes no sense. First, channel.write is supposed to be thread safe. Second, concurrent writes (when they happen) are to separate channels, channels are not shared by multiple threads.

It could be a concurrency bug in Java or the OS, but why would I be the only one to encounter it?

Of course, this change may not be directly related to the problem. It may just be altering the timing enough to make the bug not happen, or to happen so rarely I'm not seeing it.

I've gone back and re-read all the NIO material I can find on the web. Despite a certain amount of conflicting advice I think I have a pretty good idea how it works, how to use it, and the common errors. I even read the arguments against using NIO (which I'm sympathetic to, given my problems).

Although it seems to be working, I'm not comfortable leaving it as it is. Since I don't know the source of the problem, or why/how the "fix" works, the bug could reappear at any time. But I'm also running out of things to try. It's narrowed down to only a few hundred lines of fairly straightforward code, most of which is identical to examples found on the web.

So my options are to abandon NIO and use a simple thread per connection model. According to some reports, this would be faster for the number of connections I expect (up to several hundred).

Or I could use someone else's framework. The contenders seem to be Apache Mina and JBoss Netty. (see Netty vs Mina)

I think I'll probably give Netty a try and see how it goes. But it's frustrating not being able to figure it out - I hate "giving up"!

Monday, May 10, 2010

Be Precise

Guest Post by
Penny McKinlay

I’m sure all of us have used the Help feature on a software program and been frustrated and annoyed because it didn’t make sense or didn’t answer our question.

One of my goals as a technical writer is to develop a good relationship with the customer. I want them to turn to the documentation feeling confident that it will help them complete their task quickly and successfully.

I don’t want to confuse or antagonize them.

Avoid Confusion

I prepare the online documentation for customers of an integrated trucking and accounting software package. I used to use the verb “select” when telling customers to pick the appropriate option on a pull-down menu.

Fortunately, one of the trainers pointed out to me that this was really confusing for the customers because there was a Select button at the bottom of many of the screens. Now, I only use the word “select” if I am referring to this button.

The Help carefully distinguishes between “placing a checkmark in the checkbox” and “generating a check.” And we deliberately use the American spelling of “check” so as not to irritate or confuse American customers.

We consistently refer to “Owner Operators” rather than switching back and forth between “Owner Operators,” “Leased Carriers,” and “Third-Party Contractors.”

Don’t Annoy the Customer

I try and write the Help from the user’s perspective: “you will not be able to invoice your Order until you do this” or “use this report to review outstanding trucking transactions.”

We used to say that the software would “allow” customers to do certain things, but we realized that the word “allow” was really condescending. Now, we use phrases such as “this screen will help you to . . . .”

We also try very hard to avoid jargon because it’s intimidating and makes readers feel stupid. Software programmers talk about “parameters” and “locking down.” The Help talks about “options” and “protecting.”

Writing Tips

Be precise, be consistent, consider your audience – good things to keep in mind whatever we’re writing.

For more tips on business writing, visit my web site.

Penny McKinlay

enTourage eDGe™

enTourage eDGe™
Another interesting alternative to the iPad or Kindle. I'm not sure it's ready for prime time though - it sounds like it's slow, heavy, limited battery life, and no apps. Other than that, it looks great :-)

I'd really like to go for something more "open" than the iPad or Kindle, but the problem is the apps and books. No one has all the apps like Apple, or the books like Amazon.

If we can move toward HTML 5 apps and get away from DRM, then we'll have a lot more freedom with hardware.

Which still leaves the question whether anyone can match Apple in terms of design and user experience. Even people who promote Android admit that it's not as polished as Apple. The software might get there eventually - Linux (e.g. the latest Ubuntu) is starting to rival Windows and OS X. But Apple's hardware design and polish is tough to match.

Saturday, May 08, 2010

iPhone / Touch Apps

I gave my sister Penny an iPod Touch for her birthday and figured I'd better give her some recommendations for apps. Here's some of what I have on my iPhone:

Evernote (free) - save notes, photos, documents, works with web, Windows, and Mac versions
BlogPress ($2.99) - blog post writing tool, you can write offline
Note Taker ($1.99) - hand write notes with your finger (free Lite version)
Kindle (free) - ebook reader, works with Kindle devices or Windows and Mac software
Tripit (free) - trip itinerary, syncs with web site
iKeePass ($0.99) - password manager, works with web, Windows, and Mac versions
Remote (free) - remote for iTunes on Mac computers
Facebook (free)
Echofon for Twitter
Encyclopedia ($8.99) - offline copy of Wikipedia
iBird (free to $29.99) - bird guide (search for iBird)
GoodReader ($0.99) - PDF reader (free Lite version)
Instapaper (free) - save web pages for later offline reading (Pro version $4.99)
Outliner ($4.99) - syncs with web site
Google Earth (free)
oMaps ($1.99) - open maps
Fugawi iMap ($4.99) - topo maps of Canada and USA, can download maps for offline
Copilot Live Directions (free) - offline street maps of Canada and USA
Stanza (free) - ebook reader
Eucalyptus ($9.99) - ebook reader, access to 20,000 free books
Dropbox (free) - works with Windows and Mac software and web site
Gnu Go (free)

Thursday, May 06, 2010


Another day working on my bug but at least I've made some progress, at least as far as narrowing it down.

I managed to simplify my test to just repeating the same request over and over (instead of the semi-realistic mix of operations in the original test) This greatly reduces the amount of code where the bug could be.

Next I wrote a test client in Java to do that same request. But it succeeded. (Of course, you never know if one more run would run into the bug.)

Doing more testing with the cSuneido client I realized that the bug occurred more often (or only) when the client and the server were on separate machines. So I tried running my Java client on a separate machine. And now it failed too.

So now I know the problem isn't with cSuneido, or Parallels, or Windows.

I narrowed it down even further by commenting out all the real work of the request (the database querying stuff) leaving only the framework of request handling. It still fails. This reduces the amount of code where the bug could be even more.

But I'm still puzzled. My simple test client plus test server has yet to fail, even running on separate machines. But the test client plus the real server does fail, even though the real server is cut down to where it's doing little more than the test server. There must be some difference. Or else it's just that the probability of the error is less and I haven't run it enough times.

Just to give an idea, when it's failing, it fails about once every million requests. Gotta love that kind of bug!

So I still haven't found the problem, but I might be getting closer.

Tuesday, May 04, 2010

This is what I was afraid of!

I just spent another day trying to find my jSuneido concurrency bug, with no concrete progress. That makes four days I think, definitely the trickiest bug on this project (so far). It's this kind of bug that makes me afraid of concurrency in the first place.

I made a test server and test client and at first I thought I had recreated the problem, but the fix I found only worked for the test program, not jSuneido :-( Since then my test server and client have worked perfectly, despite extending them to be more like the real jSuneido code.

I've tried synchronizing here and there and making defensive copies of this and that but the bug still happens. I've read and re-read the code. I've drawn diagrams of the sequence of events.

I start to wonder if the bug is in the cSuneido client rather than the jSuneido server. But that doesn't really make sense because we have thousands of people using the cSuneido client and we don't see this problem.

My next step is to write a simple Java client for the jSuneido server. That will eliminate the cSuneido client. I think the best bet is to try to gradually narrow down the problem and isolate it.

I don't doubt I'll find the problem eventually. The question is how many days I'll need to bang my head against the wall. Hopefully the wall crumbles before my head!

Saturday, May 01, 2010

People Hate Change

My company sells specialized software for trucking companies. Often companies that we sell to have been using QuickBooks. And the people in those companies are very reluctant to leave QuickBooks and switch to using our software. And even after they do switch they continue to complain that our software does not work like QuickBooks.

QuickBooks is a good program and no question there are QuickBook features that are our software lacks. But for trucking companies our software does a lot more than QuickBooks ever will. QuickBooks doesn't handle the specialized needs of trucking companies, our software does. But to the people being faced with change, none of that matters, they want the familiar.

This was brought home recently by a long time customer of ours. They're not a trucking company and the software they have is very old. (It's DOS text mode software!) Recently they wanted to set up another company and wanted another copy of this ancient software. We suggested they just use QuickBooks. They came back and said they hated QuickBooks and that their current software is much better! This is so obviously not true that it was funny. It was a good reminder of how strongly biased people are to what they are used to.