Monday, April 30, 2012

You can’t have your cookie and cache it too

I recently discovered a poorly documented (in fact I couldn’t find any documentation about it) side effect of writing server-side cookies.  They cause outputcaching not to work, and they do so in a nonobvious way. 

If your outputcache directive looks like this:

<%@ OutputCache Duration="100" VaryByParam="none" location="Any" %> 

But somewhere in your page you have code that looks like:

Response.Cookies["user"]["value"] = "something";

The page will not be cached.  Sure, it’ll have the public cache-control/expires headers, but the value will always be 100 (duration), and it won’t be cached by IIS.  There won’t be any errors or warnings, it simply won’t cache properly.  In our case it was even less obvious because the cookie writing code had been written a long time ago in a base page, and was only triggered on certain pages with certain querystring parameters.  Even when I discovered pages that I had assumed to be cached were not, I saw the cookie but dismissed it because I mistakenly assumed the effect would be the other way around.  I assumed that a cookie on a cached page simply wouldn’t work right, the first request would write cookie and then every user thereafter would receive the cached page with the cached cookie value effectively giving everyone the same cookie.  You know what the say about assumptions.

After wasting a lot of time with the Failed Request Tracing, which proved impossible to decipher, I cycled back to my suspicious cookie logic.  Once I removed the cookie logic, caching behaved normally.  A quick audit uncovered a second place where some old rudimentary tracking logic was also writing cookies with a similar effect on caching. 

If you’re combining outputcaching with writing cookies on the server-side I’d suggest taking another look.


Technorati Tags: ,

RIF Notes #16

"One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision"Bertrand Russell

“Have you no backbone? have you no spine? Whatever happened to no one gets left behind?”

Wednesday, April 25, 2012

Jason speaks out…sort of.

I was recently interviewed on the Uhuru podcast.  Other than the fact that you could probably play a drinking game based on the number of times I say “sort of”, it turned out pretty well.


Tuesday, April 17, 2012

The 40 year old Twinkie

Last year I experienced a confluence of events that would be an exaggeration to say  changed my life, so I’ll opt to say they modified my life, not the least of which was turning forty.  Turning forty itself wasn’t that significant, more of a relief once the threshold had passed. I guess I had been subconsciously aware of its looming arrival.  Nevertheless, it got me thinking about my age and my health.  Until my thirties I had always been extremely thin, but that lost decade had seen me fluctuate between 160 and 190 lbs.  Each time I’d get heavy, disgust myself and then attempt to loose some weight fast, using Atkins, South Beach and other nonsense.  They worked temporarily but weren’t sustainable lifestyles. 

About the time I turned forty last year, a few other things happened.  I had been diagnosed which some severe reflux and some other minor health concerns that required that I alter my diet.  I went to Disney with my family and found myself once again disgusted with my 180 lb. self in family photos from the trip.  And I came across the Twinkie diet by chance.  The Twinkie diet crystallized for me what I always believed but for whatever reason was reluctant to accept.  And I’m sure I can list a lot of familiar reasons.  Ultimately, its all about calories, period.  No perfect mixture of proteins and vegetables of a certain color, not eating a bigger breakfast, or eating numerous tiny meals throughout the day. 

Inspired by its simplicity, I picked that last weight that I thought of myself as thin, 150 lbs.  and targeted the number of daily calories required to get there.  I used sites  like Livestrong and LoseIt.   Livestrong has the more complete food catalog but LoseIt integrated with fitbit, which I also picked up. None of those are critical, but mildly interesting.  I’m not especially anal about analyzing and tracking. Fitbit isn’t particularly accurate but it is effortless.  Therefore, I picked a low calorie number, 1500, to make sure that since I was going to be ball parking a lot, even if I was substantially off I’d still end up pretty low. I even threw in some P90X and Insanity workouts, but I had a hard time finding the time for those with any regularity, but they contributed.  After about 5 months I hit my 150 lb. goal, mostly on the wings of caloric restriction.

Unfortunately, 150 lbs. didn’t quite turn out to be a thin as I had expected and the Thanksgiving to Christmas time frame saw me gain back about six pounds.  But using the same Twinkie principles I was able drop 10 pounds again from 156 to 146, which is about as light as I’ve been since I was 25.  The beauty is that I still eat junk food, and go off the wagon pretty frequently, but as long as I’m roughly accounting for the calories the weight loss seems pretty sustainable.

Now if I could only suck back down to my 112 lb. high school wrestling weight, now that would be something.

Tuesday, April 3, 2012

Cuckoo for POCO Puffs: NHibernate edition

Migrating from EF model-first to code-first with FluentAPI wasn't terribly difficult and resulted in far simpler code.  Once completed, the resulting POCO's were pure enough to appear to be compatible with NHibernate.  The question I wanted to answer was how similar Fluent NHibernate is to EF’s code-first FluentAPI in terms of how it managed those POCOs.  What I was ultimately looking for was some kind of definitive answer that demonstrated that they were either similar enough as to make no difference or dissimilar in ways that made one clearly superior to the other.  The most thorough and recent comparison I had seen was Dino Esposito's in 2010, and that wasn't definitive nor was it necessarily tailored to our particulars.

Hey my man, what it look like?

What I found was that the model-first to code-first conversion was a much bigger switch than from code-first to NHibernate.  The resulting NHibernate implementation looked nearly identical to the EF code-first FluentAPI version. There were a few syntactic differences in the FluentAPI.  With NHibernate I had to use ".Not.Insert().Not.Update()" in cases where I had both a navigation property and a foreign key Id so that the insert/update statements didn't duplicate columns.  The Linq provider implementation was slightly different too.  Instead of DbSet properties of the context NHibernate uses a generic query method (session.Query<Myobject>()), and instead of Include() NHibernate uses Fetch() and ThenFetch().  I think anyone would agree that these are pretty minor differences.  From the perspective of the resulting code there was very little difference in complexity, organization or syntax.  For my humble purposes and based on this somewhat shallow analysis, it looks like they are similar enough as to make no difference.

The secret awaits eyes unclouded by ambition

Beyond the code I did discover some noteworthy differences between NHibernate and EF.  EF doesn’t have a built in mechanism to trace the generated SQL, which seems like such an obvious basic feature.  I overcame this by using extension methods before, but this is only a partial solution.  It will only trace SELECT statements, not the INSER, UPDATE and DELETE’s and it doesn’t include parameter values.  I took a look at EFProviderWrappers and wasn’t encouraged.  Its mainly sample code not an actively maintained project, it requires some odd configuration tricks, and doesn't support code-first’s DbContext.  While I could adapt this sample for my purpose, it really shouldn’t be necessary.  NHibernate will output the generated sql with a simple ‘ShowSql’ configuration setting.  Its not hard to hear the claimed lack of maturity and extensibility points in EF ringing true when the first, most basic one, is a hassle.

Those who are bound by desire see only that which can be held in their hands

On the flip side, I found that NHibernate dependencies to be fragile.  I downloaded the Fluent NHibernate 1.2 version which included Nhibernate 3.1.  Immediately upon running the application I began encountering a series of dependencies issues.  The two most troublesome of which were:

Could not load file or assembly 'NHibernate.ByteCode.Castle' or one of its dependencies. The system cannot find the file specified.
The type initializer for 'NHibernate.Cfg.Configuration' threw an exception. The invoked member is not supported in a dynamic assembly

I solved the former by adding it as a reference to every project that referenced the assembly that referenced NHibernate.  I don't find that to be a particularly satisfactory solution.  The latter was resolved by upgrading my other assemblies to use log4net 1.2.10, another odd nuisance.  While searching for answers to those two particular issues I discovered a frightening number of other compatibility woes plaguing others.  A well documented Microsoft supported and integrated Entity Framework requires far less fuss and googling.

You just get that sucker to the designated place at the designated time, and I will gladly designate his ass... for dismemberment!

So far, there’s not much to fight about.  Either I have to do a little extra work to get tracing, or a little extra work to make sure my versions and dependencies are straight.  There are, however, some more strategic considerations. 

  • NHibernate’s Level 2 cache is dreamy, the EFProviderWrapper is pitiful.  Until Microsoft or a third party writes a commercial Level 2 cache for EF, NHibernate has the advantage, with a caveat.  I’m not sure how well the Level 2 cache works or is to work with in practice, but more importantly the likelihood of our data access being all or mostly managed by an O/RM is a long way off, which somewhat devalues its usefulness in the short term. Still I can’t help but be enamored by the possibility.

  • Entity Framework is the preferred data access technology from Microsoft. That means documentation, support, integrated tooling, potentially wider adoption.  Its not hard to imagine EF reaching feature parity and even surpassing NHibernate in the near future, other than the fact it should have already done so and still has a ways to go.  The more troubling aspect of the “it comes from Microsoft” double edged sword is that to get new EF features we had to upgrade the entire platform from .NET 3.5 to .NET 4.0.  I’m hoping we don’t need .NET 4.5 to get EF 5.x features.  NHibernate is somewhat freer in this regard to add features independent of the full framework.

Well, I did you one better. I mastered "the art of fighting... without knowing how to fight".

Objectively, I might give the slight edge to NHibernate, all things being equal.  But a slight edge isn’t quite enough to go off into unchartered territory with NHibernate just yet.  I think we’ll continue down the path of converting our EF v1 style model-first code to Entity Framework code-first with FluentAPI (I’m still not sure how to refer to it), while taking comfort in the fact that as long as our POCO’s are pure its not a decision that is irrevocable.