Random Thoughts of a Scatterbrain.
 Sunday, July 15, 2007

Commitment Chains, GUIs, Frustration, And Other Ramblings...

7/15/2007 11:29:58 PM (Eastern Daylight Time, UTC-04:00)

Warning: massive brain dump ahead...

As I was laying down to sleep and having a discussion with my wife - much to her dismay - the topic of her current graduate class came up and she mentioned how much she enjoyed just sitting down and writing for 45 minutes each class.  I found it strange that she should put it in such a perspective.  I mean, there's nothing preventing her from taking the time to sit down and write for 45 minutes each day (and she did keep a journal up until maybe 3 or 4 years ago) as surely, countless minutes of her day (and any average person's day) is spent doing mindless things like watching television or eating or something else equally useless.

The idea of commitment chains occurred to me as I was using an analogy about exercise and trying to convince her that writing for 45 minutes each day is relatively trival compared to working out.  Think about it: in exercising, one starts a chain of commitments which can seem unconsciously daunting.  To exercise is to sweat, to sweat is to necessitate an immediate shower (well, unless you don't mind body odor or the salty stickiness of sweat), to exercise necessitates a larger load of laundry, and most importantly, in this proposition, is that it necessitates a healthy lifestyle lest that exercise went for naught. 

It is a relatively large commitment chain to make simply by exercising and perhaps this is why so many people find it so difficult to maintain a healthy lifestyle: the weight of this commitment chain is simply too heavy.  On the other hand, writing for pleasure carries little commitment of any kind.  You write if you want to, you don't if you are not in the mood.

What's the point?  No point, really :-D  I guess if there was a point, then perhaps it is that very often in life, we don't really take into consideration how little commitment it takes to do what we want to do and do what we enjoy.  We also fail to realize how these low commitment activities have a profound effect on our lives as they help us feel like we've done something.  Simple things like taking a stroll around the block, watering some flowers, laying down and watching the clouds pass, sitting with a cat on the grass, drinking a cup of lemonade on a hazy summer afternoon.  Perhaps that's the secret to finding balance in life: to have a healthy mixture of tasks with long commitment chains (work, family, health) mixed with activies of low commitment (I'm mixed on whether blogging is the former or the latter, but I do find it constructive to put thoughts to text some times).

Shifting gears now.

Prior to this discussion, we had another discussion about how we visualize dates.  I was thinking back to something that I had once read about how to interview tech candidates: propose that some object typically comes in a set of 14.  Now 5 additional elements are introduced...ask the candidate how he or she would organize the new elements.

Some people, like my wife, would tend to place the 5 elements "below" the 14 elements and line them up and start to form a multidimensional array - or a matrix, if you will.  Some people like me, would visualize it as a separate block of elements, but in a linear manner...more like containment where the first set contains 14 elements and the second set contains 5, but they are part of yet a larger set.  It is less of a repeating pattern and more of a general grouping.

This manifested itself clearly in the way in which we think about and visualize dates.  For her, as day of the week is important, she tends to organize her events and key dates in a typical calendar fashion and in fact, she can visualize it so well, that given one event in a month, she can probably tell you the day of the week of any other date in the month nearly instantly.  She views the set of 7 days in a week as a part of a matrix much as a calendar is typically visualized.

In my case, as day of the week is generally not that important, I visualize date and time as linear and quite abstract (I think the most natural way to think about it since it really is linear and absolute...it is only the incidental cyclical nature of our orbit around our Sun that defines constructs like seconds, minutes, hours, days, weeks, years and so on).  In my case, I am terrible at remembering dates and I am terrible at remembering order; I only roughly index that I have something to do some time in the future.  Ask me what I'll be doing two weeks from now, and it'll take me a good amount of time to figure that out whereas my wife's response will be nearly instantaneous.  I tend to think of time in blocks where I have commitments (meetings, errands, and so on) and blocks where I don't have commitments.

When you really think about it, time itself is completely abstract (what is it? will it end? when did it start? how much of it is there? what does it look like? what is the absolute unit of time?  can it really even be counted?), but the organization and demarcatinon of time into units seems...weird and useless to me; I am fine thinking about it in the abstract (i.e. "some time in the future, I need to do this") and not as an absolute (i.e. "on such and such date at such and such time, I need to do this" or "x units from now, I need to do this").  

There is a parallel in my profession: as a software developer, there is nothing tangible about the constructs that I build; the contructs that I build are purely abstract in nature: every GUI, every construct in software, is but an abstraction of numerous lines of code - or, is it the other way around?  Software is but one layer of abstraction on top of another...modern day software could not exist without the huge levels of abstractions that have been built to allow programs to be written efficiently.  Buttons are not buttons, they are rectagles.  Rectangles are not rectangles, they are arrangements of lines.  Lines are not lines, but merely a linear set of pixels.  But in essence, there is nothinig to grasp and to utilize to visualize proportion, all of it is purely hypothetical and kind of "uploaded" into my brain as a set of objects, relationships, and other abstract constructs when I sit down at my desk in the morning. 

In actuality, I find this process of uploading and unloading quite unpleasant (particularly the unloading part).  I have been told by my coworkers, wife, and family members that I can become quite unruly when I'm involved in my work.  The reality of it is that when I'm in my groove, unloading and then loading so much abstraction and so much data causes some sort of mental instability...I just get frustrated at the individual forcing the purge or I just lose my groove and have to kind of veg for the rest of the day...I simply cannot be constructive.

From an observer's perspective, I think this makes me seem like a loner or anti-social or if a colleague is coming to me with questions, it may seem like I'm impatient or uncooperative.  In reality, my bitter reaction is more of a defensive mechanism to kind of keep myself from having to go through these periods of derailment as in my case it's not a temporary derailment...it's like a long term derailment once it happens as there is simply too much data to store and reload that it's taxing on my mind.

For this reason, I think I've recently been in some hot water with some coworkers.  I simply don't take afternoon interruptions very well as that is the time when it is hardest to recover from derailment at that point.

Of course, the whole reason that this discussion and train of thought came up was the movie Stranger Than Fiction (it's an absolutely brilliant screenplay with an absolutely excellent performance by Will Ferrell (everytime you think he's going to break into his "normal" genres, he surprises you and keeps his acting true to the character...a brilliant perfomance)). 

This movie draws my attention on various levels: it is at once a deep inspection of what it means to live and to be alive, it asks what exactly is the scope of one life in the grander scheme of the universe, on some level it is a movie about religion (I haven't really fully formulated this part of it yet), and of course, it's a touching romantic comedy :-).

I also found the specials (and this isn't the first time) to contain some very insightful information on teamwork and project management that would apply to almost any field (but that's a discussion for another day).

What also caught my attention was how director Marc Forster and the visual effects team realized how Harold's thoughts were visualized with these planar "screens" with metrics, text, and data layered together.  It's much the same way I visualize data, code, structures, and tasks, all on virtual screens that I slide around, stack, layer, and intermingle.  I now realize that there is no organization to how I think about these constructs and abstractions...I simply see them in my mind as if before me was a stack of cards strewn about and yet I am able to reach out and pluck the ace of spades at will with no effort.

Maintaining such mental order requires a lot of effort and a lot of concentration.  I think it is because of the amount of effort required to work the way that I do, that I am so unpleasant when interrupted (much to the dismay of my wife, mother, and coworkers).  And believe me, it's not that I don't like to help others with the development issues or educate other developers and team members, rather such tasks are not my primary concern and shifting gears is extremely difficult when you have to maintain such large abstractions and structures in the mind.

So of course, the question is, what is the solution?  Well, perhaps I need to invest some time in some organizational books.  Perhaps I need a whiteboard to help unload some of the data and make it easier to reload as well.  Perhaps I need a bigger desk so I can scribble more and keep better notes.

Well, I think that about wraps this up.  Possibly not the most coherent or well organized entry, but it contained data would have kept me up all night if I didn't unload it :-)

Sticking It To The Man (Maybe)

7/15/2007 5:31:38 PM (Eastern Daylight Time, UTC-04:00)

There used to be a time, decades ago, when there was only one telephone carrier and everyone was forced to use it, regardless of whether the service or price sucked. 

Nowadays we have a much greater variety of choices from AT&T to Verizon to MCI for local and long distance calls.  We also have some new comers to the game such as Comcast and Cablevision who offer telephone service over cable.

For the longest time, my mother was using MCI for her local and long distance.  For whatever reason, she suddenly decided (as she is oft inclined to do) that it cost too much.  We decided to switch to AT&T as she felt that it was a trustworthy and reliable brand.  Little did we know that the new AT&T seems to outsource its customer service, charges a hefty connection fee (even when no physical connection setup was required), and she ended up spending exactly the same each month as she did with MCI...

Jump forward a few months after the AT&T debacle (they were still trying to get her to pay a connection fee...).  After a year, her promotional rate with Comcast for Internet connectivity jumped dramatically.  At this time, her best option - of course - was to switch over to the Comcast Triple Play.  We were assured that the cable telephony was a good choice and that the battery backup on the modem meant that even when the power went out, we would still have dialing capabilities.

Of course, what they failed to mention was that if the Internet connectivity gets flaky (as is oft the case with Comcast), so does your ability to use the phone...D'oh!  Well, it should have been obvious to me, but I dunno, I was thinking that maybe the modem had special capabilities that allowed it to operate indepenently of the Internet connectivity.  Turns out that every once in a while, we'll pick up the phone and there will be no dial tone because the modem loses connection or the DNS servers are down somewhere on the grid or some other issue.  It also turns out that the special telephony modem that we have to use is noticeably slower at servicing Internet traffic compared to my previous Motorola (blazing fast); there is now a noticeable lag when frequenting some of the web pages in my daily queue.

For the time being, the promotional price is great: about $33/month ($99/month for Triple Play for one year) for unlimited long distance to anywhere in the US.  This is much better than what Verizon or AT&T charges for the same features (about $50/month).  What they don't always make so clear is that after a year, the price jumps dramatically to $140.95/month or roughly the same price for telephone service as with Verizon or AT&T...except without the reliability of the good old PTSN.

If you really sit down to think about it, that comes out to roughly $600/year for phone service.  That's PS3 territory.

But there is an alternative, there is a brave new world in telephony: Skype (okay, it's really not that new, but I don't personally know anyone who uses Skype exclusively of landlines (although I know a few who use cellular lines exclusively)).

I signed up for a free trial at the end of last year that gave me 30 days of SkypeOut for free.  I found the service to be generally acceptable and convenient (since I spend almost all day in front of the computer anyways).

But what makes Skype even more compelling are the new accessories which are being developed around it: standalone (no PC requried) devices which allows one to use Skype as a total replacement for landelines.

The two that I looked into were the Netgear SPH150D and the Philips VOIP8411B.  Both of these phones sport the following features:

  • The latest DECT technology
  • Multi-handset capable (up to 4 each)
  • Dual mode (supports PTSN and Skype)
  • Don't require PC to use

What seals the deal is that SkypeIn, which allows you to get a number that any landline or cellular line can dial and features unlimited calls anywhere in the US to landlines and cellular lines (and of course free calls to any other Skype user), costs only $60/year.  So for a tenth of the cost of traditional landlines or cable telephony, I can get roughly the same quality services and I can call from my computer.  I also think that the portability is also cool as hell...I can answer my phone anywhere in the world as long as I'm connected to the Internet.

I convinced my wife that when we move this time (just about 20 days to go), we're gonna try to go cold turkey with Skype (we're went with the Netgear phone) and see if it'll work for us.  We both make long duration long distance calls pretty regularly for our jobs so it'll be interesting to see how it works out.  For us, 911 capabilities is not an issue as we both have cell phones.  Dependency on the Internet connection is also not a problem as it's no worse than Comcast or Optimum and whenever we tend to be on long important calls, we also tend to be in some sort of net conference...so having the reliability of PTSN is kind of pointless if the net meeting is down. 

So overall, I'm excited to stick it to the man :-D

I'll keep this site posted with my review and experiences as I spend more time with Skype and the Netgear phone.

Update:

Argh!  Chalk this one up to poor product description, packaging, or something like that, but it wasn't clear at all that one needs to purchase SkypeOut/Skype Unlimited to receive the unlimited outbound calls.  In essence, $60 only buys an inbound number and unlimited inbound calls...outbound calls with SkypeIn are still charged at local/long distance rates. 

I'm kind of conflicted...on the one hand, dude, it's $90 for a whole year.  On the other hand: Damn these people for not clearly advertising their services and costs and using sensible bundles to do so.

 Tuesday, July 10, 2007

Software, Artistry, and Frustration

7/10/2007 10:52:46 PM (Eastern Daylight Time, UTC-04:00)

In describing my approach to software development, I like to use the term practical artistry.  What does this mean exactly?

Well, the practical part of it is that the class libraries, interfaces, and components have to work the way that tey were designed.  They should also be easy to use, easy to understand, easy to integrate with.

The artistry portion of this term is much harder to quantify.  Just what is artistry when used in the context of software development?

Art Tatum offers a very compelling definition:

Art is a method of communication which unifies surface details and form while taking both the intended meaning and aesthetics into account. This requires significant amounts of problem solving. The artist is constantly asking, "How can I best express this idea without ruining the proportions of the work as a whole."

This ties in with Fred Brooks' principle of conceptual integrity for it is the artist alone who sees the proportions of his work and the artist alone who shall ensure that the work abides by the guidelines of the orginal design intent.

Another term that I like to use is exemplary craftsmanship.  This concerns the little details that make code aesthetically pleasing, readable, and well crafted.  Many small details affect this quality of code such as consistent naming schemes, using extra keystrokes and not abbreviating non-standard terms, ensuring that spacing is consistent, formatting code in a consistent manner so as to make it more readable, and commenting public APIs.  On a higher level, it concerns the organization of code and the clear separation of domains (not in the Fowler sense, but in a more abstract sense) in a manner that enhances the extensibility and orthogonality of the code.

It's not just code, it's any trade.  A panel and house wired by a master electrician will certainly be different than a panel and house wired by an apprentice.  The cabling will be neat, the runs will be well thought out, the circuits will be well labled, the panel will be well organized, little details will have been considered, and the artistry of the finished work is apparent even to laymen.

With this in mind, I consider myself to still be an apprentice; I still seek to learn the trade from a master craftsman and I still seek to hone my skills and develop my artistry so that I may also craft software of a high caliber.  But I work hard to ensure that some sense of practical artistry and exemplary craftsmanship is apparent in everything I do.  From simple tasks like ensuring proper indentation in my source files, selecting the right margins in my documentation, and using the right fonts to more complex design issues like organizing libraries in proper dependency chains, achieving orthogonality in modules, and organizing objects in consistent and well defined fashions (i.e. utilizing design patterns).

Unfortunately, in my short career, my interactions with other developers have left me disappointed on this front for the most part except for three individuals whom I didn't have nearly enough time to interact with (this is not to say that I haven't worked with many fine developers, but three stand out as practicing these principles of craftsmanship).  These three were true craftsmen in the sense that the little details mattered to them.  Improving their skills as developers was an important aspect of everyday development.  Writing good code and following well known guidelines and principles meant something.  The naming of every class, of every variable, required at least some passing thought so as to ensure that each construct was congruent and aligned with the whole.

Of course, such discussion of artistry as it applies to software is not just frivolous academia, Maarten Boasson writes in The Artistry of Software Architecture:

Designing software is not very different from designing any other complex structure: Few people are good at it; no single recipe always produces a good product; and the more people involved, the smaller the probability of success.  On the other hand, a design produced by someone who is good at design provides an excellent basis for long, reliable service.

Software engineers consider the artistry of the design not only evaluating aesthetics but also the practical results of such a design such as orthogonality and added extensibility.  Boasson further comments:

In exceptional cases, a good software design is no less valuable than the great masterpieces that have been created throughout our rich history.  Examples of both bad and good designs can be found all around us, in almost every engineering field; practically everyone recognizes a piece of art when they see it.

So I often wonder why it is the case that I encounter and, of much greater concern, find high degrees of tolerance for bad design.  Not just bad design, but bad development practices like inconsistent usage of formatting elements (spacing, newlines, tabs), naming namespaces and classes against well established guidelines and practices, and other details like inconsistent casing.  Leadership just doesn't seem to care for the most part and it requires the rare and truly inspired individual project manager to understand the long term value of encouraging practical artistry and exemplary craftsmanship.

Bear in mind: it's not that I approach writing software with any sort of artistry or snobbery in mind...indeed, a good portion of it is the grunt work - simply putting the hammer to the nail, or putting the brush to the canvas, so to speak.  But at the end of the day, there is a personal satsifaction that is achieved from not just writing any code, but writing good code.  There is a satsifaction that comes from recognizing and implementing a superior system design.  Of course, it goes beyond personal satisfaction, good design, as Boasson writes, can provide long term value in the form of extensibility, maintainability, and reusability.

In almost all cases, as the majority of developers are not self motivated to write such code, it takes strong leadership, clear definitions or design guidelines, and enforcement of the policies to ensure that quality software - not just working software, but quality software - is crafted.

To me, it is the little details that go towards creating a better product.  There is certainly a time and place for prototyping and RAD - and certainly, I utilize these techniques all the time, but there is also a time to formalize the lessons learned from such exercises and to create a masterpiece...to write code that you would find have no qualms about showing to the world and exposing it to critique.

It is with this in mind that I find myself currently flustered.  Is it just me?  Am I being too uppity about all of this?  It's hard to say...I am truly conflicted about this as I cannot see how I can work productively and cooperatively in a team with people who do not honor the same sense of craftsmanship and artistry.  I awake and find that someone has scribbled on my canvas in a weak imitation of my style using colors that clash with the existing palette.  Analogously, I open the electrical panel to find that someone has stuffed some low grade wire haphazardly into the panel without any clear labeling.  I cannot help myself but cringe at the thought of integration - yes cringe.  I don't want to deal with ugly code and yet the leadership doesn't seem to care one way or the other and I am powerless to affect change (partly because I am a blunt edge and possess no sense of finesse whatsoever in dealing with these situations)...*sigh*

I can only hope that some of my desire to achieve practical artistry in code and design inspires others on my team, otherwise this will be painful to endure.

 Friday, July 06, 2007

WCF Configuration Intellisense

7/6/2007 4:06:38 PM (Eastern Daylight Time, UTC-04:00)

Hmm...I thought it was kind of odd that Visual Studio didn't support intellisense for WCF configuration elements (but then again, I've kind of become intimately familiar with the core elements without having the schema).

Turns out that you have to take care of it manually by updating the schema file for configuration.

Blogger Govind has a post with the necessary file and instructions.

Helps configuration go much more smoothly until Orcas arrives.

I'm surprised that this hasn't been posted across more blogs since it seems like a big, big bonus to have this for developing WCF applications.  Is it common knowledge?  Was there an SP that updated the schema files?  I know that installing .Net 3.0 didn't change the configuration files on my system at least.

 Tuesday, July 03, 2007

Enterprise Library vs. Log4Net

7/3/2007 5:35:18 PM (Eastern Daylight Time, UTC-04:00)

If there's one thing that really irks me is allegiance for the sake of allegiance.

Don't get me wrong, I have nothing against Microsoft Enterprise Library and in fact, in absense of any better alternatives, EL is indeed the best option for a whole slew of development tasks and better than rolling one's own solution.  But of course, the question is then: are there better alternatives.

Take logging for example.  There has been a movement in our team to use EL instead of log4net.  In all honesty, it's not a battle that I want to wage...it's simply not worth it for logging, but I think that for anyone considering one or the other, some serious evaluation is in order.  EL logging simply cannot hold a candle to log4net.

As I commented on James Newton Kings' blog:

James,

About 2 years ago, I started to seriously integrate logging into my applications.  During that time, I went through several rounds of testing both log4net and EL and I am currently in a discussion with other developers in my group on whether we should use the best available tool (log4net 1.2.11) or the do it the Microsoft way (EL 3.0/3.1).

In my opinion, the lack of hierarchical loggers is a significant weakness of EL as it requires much more thought and planning to make sure that you can isolate components down the line.  While flexibility is good, I think that having the free form category, priority ID, and event ID make it far more confusing than it has to be...18 overloads?  Do you expect people to remember or use the right category every time?  What about misspellings?  Of course, one could always write a layer to abstract these weaknesses of EL such as add a layer to translate Log.Debug() to some internal EL call, but then you have to ask if you've gained anything in the process.

Aside from this, I'm not sure if you are aware, but log4net utilizes buffered appenders for certain classes of appenders with the ADO.Net appender being one of those.  What does this mean?  I think you will see significant performance increases with buffered appenders (say buffer 250 messages in one flush versus making 250 individual inserts).

In addition, the procedures that are used by EL (although they can certainly be modified) add overhead out of the box.  For example, if WriteLog is called it *always* makes a second call to AddCategory, regardless of whether the category exists).  This is a round trip call from SQL Server to the calling client since there are no triggers on insert to the Log table and there is no call to AddCategory from WriteLog.  In addition, in the scenario that you end up with a category name that isn't in the log (yet another lookup), *another* lookup and insert is performed via InsertCategoryLog.  Since there are FK constraints on the tables, each insert also incurs an additional lookup behind the scenes to validate the foreign key.

Aside from this, I've found that log4net tends to fail gracefully whereas EL...not so much.  For example, if you try to use logging, but fail to include the correct configuration, the exception will bubble up to your application.  On the other hand, log4net will always trap the exception and not let it bubble up to your application and thus not raising an error where you would not expect.  Sure, you could put try-catch around all of your logging statements if you're using EL...but then, you have to ask yourself WHY?

I also forgot to mention that log4net, out of the box, allows loading of configuration files from any XML string (in application code without recompile of the source code).  This means that if one were so inclined, logging configuration would be stored on a central server, downloaded, and loaded on the fly.  If one were so inclined, it could be stored as embedded content with the assembly.  This flexibility allows for a great variety of design scenarios out of the box.

James also has two incorrect interpretations of the facts:

  1. log4net is not being developed actively.  Indeed, there was a looong period of inactivity on the realease side while the log4net project was going through integration with the Apache Software Foundation, but during that whole time, the mailing lists were active and so were the developers in helping users, answering questions, and certainly making todo lists for the release after incubation.  I would also offer the opinion that log4net should have less releases as it is the more mature, tested, and stable of the two libraries.
  2. EL is somehow more extensible than log4net.  This simply insn't true as both provide the source and both provide extensive SDK documentation, samples, and examples.

Commentor Smitha Mangalore also raises an interesting point: log4net supports logging across more platforms than does EL at this point (not to mention supporting more database targets out of the box than EL).

Just my take.  I think both have their place.  For application event logging and tracing, nothing beats log4net in terms of performance, ease of use, ease of configuration (yes, I find the configuration to be much more concise and understandable with log4net), and overall usability.

Update

So my interest was piqued: this whole discussion made me want to check the performance difference for myself.

So here are the test conditions:

  1. Machine:
    1. CPU: E6400 Core 2 Duo (2.13GHz @ 3.2GHz),
    2. Memory 4 GB RAM,
    3. Disk 1: 36GB @ 10,000 RPM
    4. Disk 2: 36GB @ 10,000 RPM
    5. Disk 3: 250GB @ 7200 RPM
    6. Disk 4: 74GB @ 10,000 RPM
  2. Test Scenario:
    1. The database will be dropped each before each test run.
    2. For EL, the default procedures and tables will be used.
    3. For log4net, the sample configuration and table definition will be used.
    4. A Stopwatch instance is created and started before the code enters a loop with 100,000 iterations.  The instance is stopped as soon as it exits the loop and the result is written to the console.
    5. For each pass, different sets of logging commands will be commented out (in retrospect, I should have used conditional compliation symbols).
    6. The only listener/appender is a database listener/appender.
  3. Results:
    1. EL: 138s
    2. log4net w/buffer = 1: 116s
    3. log4net w/buffer = 100: 78s
    4. log4net w/buffer = 250: 76s
    5. log4net w/buffer = 500: 78s
  4. Constant Work Time: 18s

So there you have it: with buffering enabled, log4net is up to nearly 2x as fast as EL.

 Friday, June 29, 2007

Two Terrible Rulings

6/29/2007 11:36:46 AM (Eastern Daylight Time, UTC-04:00)

Opening up the newspaper this morning, I came across two terrible rulings recently passed down by the Supreme Court.

The first has to do with MSRP.  I'm guessing that the majority of American's who are not filthy rich often go bargain hunting for prices below MSRP in hopes of finding that killer deal.  I'm guessing that if you're like me, you're willing to sacrifice some service at the point of sale for a better price.  This is part of principle of what has driven online sales: for the retailer, they save by not needing to have sales people or point of sale service while for customers, they often get a chance to save a huge amount over retail outlets.

From USA Today (6/29/07):

The 5-4 decision overturned a 96-year-old law that prevented manufacturers from setting minmum retail prices.  The majority wrote that lifting the pricing ban could benefit consumers if retailers offered better service or selection.

Wait, what?  How about benefitting consumers by offering a better price?  Why not leave it up to the retailers to choose which model they choose to bring in customers?  If customers wanted service, they could choose the retailer that offered it.  If they wanted to find a bargain, they could choose the retailer with the best markdowns.  Instead, the court has decided that the consumer has no say in this...no freedom of choice when it comes to price shopping.

What I found was completely asinine was a statement by Richard Doherty:

Richard Doherty of technology market researcher The Envisioneering Group agrees, saying the price ruling could lead retailers to use more free products and better services as sales incentives.  "It's sure to be to consumers' benefit this summer and Christmas."

Is this guy on crack?  How about I just want to get a good deal on a HDTV...I don't want any "quote-unquote-FREE" stuff.  I don't care for point of sales services; I do my research on the products I buy and I already know what I want when I go into the store; I want to get the best deal that I can...why not leave that decision up to the individual consumer?

To make matters worse, the article offers commentary from a multi-billionaire:

Bill Gates, of golf equipment maker Ping, says, "Not every consumer is a bargain shopper.  Some consumers are looking for quality, innovation, personalization and customer service when they shop."

That's fine, Bill, if you have the money for all that jazz, but how about the rest of us who are just trying to put away some money for retirement, for our kids, for our families?  We just want to get by with a good deal.  How about this novel idea: let the consumers decide what they value - price or service.

Argh!

As if this wasn't bad enough, the Supreme Court also ruled to strike down school diversity programs on a national level:

The dramatic 5-4 decision throws into legal doubt programs that factor in race, including magnet schools that use race to draw students from different neighborhoods.

Accorind to Chief Justice Roberts,

Classifying and assigning schoolchildren according to...race is an extreme approach.

Well then, what would you suggest Mr. Roberts?  How do you overcome the economic hurdles that create defacto segregated schools?  How can you deny that integration - even if it is forced - is to the benefit of our racial diversity and our social fabric?

The fact is, if school children were simply assigned to schools based on location and district, it would in fact create further segregation and slowly reverse some of the progress that has been made.  I think it is true that we fear what we do not know or understand.  We view those who are different from us as outsiders because we do not understand their cultures, their languages, their traditions, and their ways; what better way to overcome the defacto segragation that occurs by township (and economic boundaries) they to help ensure a minimum level of integration?

Such an upsetting way to start the day...

 Friday, June 22, 2007

Software Engineering 101....ARGH!

6/22/2007 5:23:40 PM (Eastern Daylight Time, UTC-04:00)

Some days, I just can't handle the aggrevation...

I thought it was generally known that binary build output does not belong in source control, so I was quite dismayed when I grabbed an update to our source tree today and found myself downloading a 2MB .msi file (the output of one of our installer projects).

After discussing this with the other developers on my team, it became apparent that what I thought was a common, well known practice regarding source control is in fact, not so well known.

After presenting my arguments with little avail, I started to scour the web to find evidence support my stance:

Visual Studio Team System Guidance

What Files Should Not Be Source Controlled?

Build outputs that include assembly dynamic-link libraries (DLLs), Interop assembly DLLs and executable files (EXEs). Note that you are advised to add assemblies that are not built as part of your system build process (such as third-party controls and libraries) to Source Control within the projects that reference them.

Top 15 Ant Best Practices

Generally, avoid storing build output in version control. Provided that your source code is versioned properly, you should be able to recreate any previous release through the build process.

Introducing Source Control

Files that you cannot add to source control include the following:

...Build output files, for example, *.dll and *.exe files.

SandCastle Discussion

We do not include the *.xml outputs in source control for the same reason that we do not include *.htm outputs; you can't run a new build without checking out the files! In my view, whether an output is a *.dll or a *.htm or a *.xml is irrelevant; it's build output, so it shouldn't be source controlled. Just source control the inputs and you have everything you need to get the outputs.

It is very important to us to be able to run an automated build (no human intervention). To the extent that a future version does include a dialog that offers to check out files, I hope it will either not run at all if the files are not source-controlled, or it can be suppressed by project settings.

Source Control HOWTO: Repositories

Best Practice: Checkin all the Canonical Stuff, and Nothing else.

Although you can store anything you want in a repository, that doesn't mean you should. The best practice here is to store everything which is necessary to do a build, and nothing else. I call this "the canonical stuff."

To put this another way, I recommend that you do not store any file which is automatically generated. Checkin your hand-edited source code. Don't checkin EXEs and DLLs. If you use a code generation tool, checkin the input file, not the generated code file. If you generate your product documentation in several different formats, checkin the original format, the one that you manually edit.

If you have two files, one of which is automatically generated from the other, then you just don't need to checkin both of them. You would in effect be managing two expressions of the same thing. If one of them gets out of sync with the other, then you have a problem.

So not only is it a pain in the ass to have to download large binary files for a one line code changes, it also means that simply compiling the code (with no changes in the actual code) may cause a version change...argh!

I think that such a practice of disallowing build output in the repository also forces the team members to ensure that their code is buildable anywhere...a great quality when it comes to codebases as it means that onboarding new members or transitioning development machines, the code is ready to go.

 Sunday, June 17, 2007

Working With SharePoint Web Services

6/17/2007 7:03:15 PM (Eastern Daylight Time, UTC-04:00)

One of the most confounding things about working with the SharePoint web services is that the return values are all in XML strings (wrapped in an XmlNode).

To make working with the services even more puzzling, suppose you get a result like so:

<ContentType 
    ID="0x010100347433A509750F4D88880291599D314D04" 
    Name="My Content Type" 
    Group="My Custom Content Types" 
    Version="7" xmlns="http://schemas.microsoft.com/sharepoint/soap/">
    <Folder TargetName="_cts/My Content Type" />
    <Fields>
        <Field ... />
        <Field ... />
        <Field ... />
        <Field ... />
    </Fields>
    <XmlDocuments>
        <XmlDocument 
         NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
            <FormTemplates 
                xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
                <Display>DocumentLibraryForm</Display>
                <Edit>DocumentLibraryForm</Edit>
                <New>DocumentLibraryForm</New>
            </FormTemplates>
        </XmlDocument>
    </XmlDocuments>
</ContentType>

You would expect to be able to retrieve all of the <Field /> elements by executing the following code:

XmlNodeList nodes = xmlResponse.SelectNodes("//Field");

But it's not quite so straight forward.  You actually have to instantiate an XmlNamespaceManager with a bogus prefix:

NameTable table = new NameTable();
XmlNamespaceManager manager = new XmlNamespaceManager(table);
manager.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");

XmlNodeList nodes = xmlResponse.SelectNodes("//sp:Field", manager);

In this case, I used "sp" as my prefix. Notice that it's utilized in the XPath query as well. 

 Thursday, May 31, 2007

SharePoint SoapServerException When Using Lists Service

5/31/2007 4:19:43 PM (Eastern Daylight Time, UTC-04:00)

When using the lists service to query the "User Information List" (the SharePoint list where the users and groups is located), you may encounter the exception:

System.Web.Services.Protocols.SoapException:
    Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException'
    was thrown.
  at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(
      SoapClientMessage message,
      WebResponse response,
      Stream responseStream,
      Boolean asyncCall)
  at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(
      String methodName,
      Object[] parameters)
  at ListsDataServiceSample.SharePoint.Lists.Lists.GetList(String listName) in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Web References\SharePoint.Lists\Reference.cs:line 213
  at ListsDataServiceSample.Program.Run() in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Program.cs:line 28

This error will occur if you are not using the "Administrator" account, which of course, is not always ideal, especially if you are writing a client side app.

The solution to fix this is to grant the account permissions on the "User Information List":

And then give the user "Read" permissions on the list:

 Wednesday, May 30, 2007

Correlation Across Workflow Instances

5/30/2007 3:15:58 PM (Eastern Daylight Time, UTC-04:00)

One of the problems that I've been working on solving recently centered around correlation in workflows.  In simple terms, where a workflow may produce parallel execution paths, correlation allows the runtime to route events to the right workflow execution path.

In every example that I came across on MSDN and online, the sample cases all assumed intra-workflow correlation as opposed to inter-workflow correlation involving "parent-child" workflow instances.

I posted the initial query - and the solution I used - on this subject over at the MSDN forums:

The trick, as it turns out, is that the CorrelationToken must be initialized in the parent workflow.  To accomplish this in the sample, I made a frivolous call to an InitializeCorrelation method on my service interface using a CallExternalMethodActivity, which was marked with the CorrelationInitializer attribute.  This activity executes right before the InvokeWorkflowActivity.


[Serializable]
public class WorkflowCommunicationServiceArgs : ExternalDataEventArgs {
private string key;

public string Key {
get { return key; }
set { key = value; }
}

public WorkflowCommunicationServiceArgs(Guid instanceId, string key)
:
base(instanceId) {
this.key = key;
}
}

[ExternalDataExchange]
[CorrelationParameter("key")]
public interface IWorkflowCommunicationService {
[CorrelationAlias("key", "e.Key")]
event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

[CorrelationInitializer]
void InitializeCorrelation(string key);

[CorrelationInitializer]
void OnChildCompleted(string key);
}

public class WorkflowCommunicationService : IWorkflowCommunicationService {
#region IWorkflowCommunicationService Members

public event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

public void InitializeCorrelation(string key) {
Console.Out.WriteLine("Key -> [{0}]", key);
}

public void OnChildCompleted(string key) {
MessageBox.Show(string.Format("Completed child; Key = [{0}]", key));

RaiseChildCompletedEvent(key);
}

public void RaiseChildCompletedEvent(string key) {
if (ChildCompleted != null) {
ChildCompleted(
null
,
new WorkflowCommunicationServiceArgs(
new
Guid("5D1667BF-61F6-4bf3-81C0-E70CBE15D2EF"),
key
)
);

}
}

#endregion
}

In essence, the idea is to have two correlation initializers: one utilized by the parent/outer workflow and one utilized by the child/inner workflow when signaling back to the parent.  It seems kind of counterintuitive to require two initializations...I'm still not sure how this is working under the covers, but it works :-)

The working example can be downloaded from: http://www.charliedigital.com/junk/CorrelationTest.Working.zip

RSS 2.0 Atom 1.0 CDF