Random Thoughts of a Scatterbrain.
 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

 Tuesday, May 29, 2007

5 Lessons For Barbeque'n

5/29/2007 8:03:00 AM (Eastern Daylight Time, UTC-04:00)
  1. Cut veggies into large sizes.  This makes it easier to work with them and not have them fall through the grate.
  2. Put small items onto skewers.  Items like shrimp just won't work on the grill without a skewer.
  3. If you're making chicken or other meats low in fat, brush the grilling surface with some oil first.
  4. Make bigger fires.  Charcoal is surprisingly difficult to light without lighter fluid.  Do it right the first time and make a big-ass fire.  Put some newspaper under the coals.
  5. Enjoy yourself!
 Monday, May 28, 2007

25 Up

5/28/2007 2:01:42 PM (Eastern Daylight Time, UTC-04:00)

I just finished watching the documentary 49 Up.

There's something quite moving in watching people mature from 7 to 49 in a matter of minutes and to see the change in their ideals, dreams, and their lives.  It was fascinating watching these individuals age and see how their lives took shape.

It's equally fascinating as you start to reflect on where you've been and where you shall be in  more years.

If there's one thing I've taken from the movie, is the importance of being happy in your circumstances and making the best of your lot in life.  Dreams come and go, as do opportunities.  Mistakes are made and there trying times are a certainty, but in the end, it's important to realize the brevity of your existence.  It is easy to blame circumstance and others for one's misfortune and hardships, but ultimately, the life is your own and you must do with it what you will.

The Dalai Lama writes in The Meaning of Life:

Shantideva reasons that if something can be done to fix a situation, there is no need to worry.  Whereas on the other hand, if there is nothing that can be done, there is no use in worrying.

If there is one person in the series that embodied this the most, I think it would have to be Neil, who, for a good part of his adult life, seemed to wander aimlessly.

Neil turned out to be one of the most interesting of the entire group. At seven he was funny, full of life and hope. At 14 he was doing well in comprehensive school but was more serious and subdued. In one of the biggest shocks of the series however, by the time of 21 Up he was homeless in London, having dropped out of Aberdeen University after one term, and was living in a squat and finding work as he could on building sites.

At 35 amazingly, he had turned his life around to a great degree and found his calling in politics.

For some of the kids, like Andrew, life turned out exaclty as scripted (either by themselves or by their parents).  For others, it is a meandering journey where childhood dreams are often crushed by the realities of the world.  The key, I think, is to be able to accept these defeats, take a lesson from them, and to see the opportunities ahead instead of the failures in the past.

The thread that struck me the most about the lives of each of the individuals in the documentary is the common importance of family and how it is a driving force in finding that peace.  Of the subjects, only Neil did not marry or have children; at 49, this lack of a family of his own and the troubled relationship with his parents, was perhaps one of his own greatest regrets in his life.

In reflecting on my own thoughts on this subject, I find that today, I'm much less enthused about the idea of being a father then I was when I was a teenager.  Not because I don't like kids or that I don't want the experience of being a father - one day - but it just feels like I'm still a bit too selfish to my own needs to be a father.  I like living my life on my schedule.

49 Up is an excellent documentary that I think all young adults should watch and study.  I think it reveals a lot about how fleeting one's perception of the world is and how it evolves over time.  It gives insight into what it really means to find happiness and to find purpose in life.

 Thursday, May 24, 2007

Palm Readings Vindicated (Sorta, Kinda)!

5/24/2007 2:30:25 PM (Eastern Daylight Time, UTC-04:00)

Came across an interesting article on Yahoo today on how finger lengths/ratio can be used to predict SAT performance.

Specifically:

Kids with longer ring fingers compared to index fingers are likely to have higher math scores than literacy or verbal scores on the college entrance exam, while children with the reverse finger-length ratio are likely to have higher reading and writing, or verbal, scores versus math scores.

To me, what's interesting is that palm reading - or chiromancy - is centuries old and has been derided as being nothing more than a pseudoscience or even worse, a sham. So it's interesting to discover that perhaps there is some legitimacy to chiromancy after all.

Indeed, in my case, my ring finger is longer than my index finger - which indicates that I'd be more proficient at demonstrating spatial and mathematical skills - reflects the 100 point differential in my SAT verbal and math scores in favor of math.

The article goes on to mention that:

Exposure to testosterone in the womb is said to promote development of areas of the brain often associated with spatial and mathematical skills, he said. That hormone makes the ring finger longer. Estrogen exposure does the same for areas of the brain associated with verbal ability and tends to lengthen the index finger relative to the ring finger.

This makes me wonder what other parts of our personalities, skills, and abilities are manifested in our appearances and physical attributes.

Very interesting indeed.

RSS 2.0 Atom 1.0 CDF