Global State On Servers Considered Harmful

The
other day I noted that extending the built-in objects in JScript .NET is no longer
legal in “fast mode”. “urn:schemas-microsoft-com:office:office” />Of
course, this is still legal in “compatibility mode” if you need it, but why did we
take it out of fast mode?

 

As
several readers have pointed out, this is actually a kind of compelling feature. It’s
nice to be able to add new methods to prototypes:

 

String.prototype.frobnicate
= function(){/* whatever */}

var s1
= “hello”;

var s2
= s1.frobnicate();

 

It
would be nice to extend the Math object,
or change the implementation of toLocaleString on Date objects,
or whatever.

 

Unfortunately,
it also breaks ASP.NET, which is the prime reason we developed fast mode in the first
place. Ironically, it is not the additional
compiler optimizations that a static object model enables which motivated this change! Rather,
it is the compilation model of ASP.NET.

 

I
discussed earlier how ASP uses the script engines — ASP translates the marked-up
page into a script, which it compiles once and runs every time the page is served
up. ASP.NET’s compilation model is similar,
but somewhat different. ASP.NET takes
the marked-up page and translates it into a class that
extends a standard page class. It compiles
the derived class once, and then every time the page is served up it
creates a new instance of the class
and calls the Render method
on the class.

 

So
what’s the difference? The difference
is that multiple instances of multiple page classes may be running in the same application
domain. In the ASP Classic model, each
script engine is an entirely independent entity. In
the ASP.NET model, page classes in the same application may run in the same domain,
and hence can affect each other. We don’t
want them to affect each other though — the information served up by one page should
not depend on stuff being served up at the same time by other pages.

 

Now
I’m sure you see where this is going. Those
built-in objects are shared by all instances of all JScript objects in the same application
domain. Imagine the chaos if you had
a page that said:

 

String.prototype.username
= FetchUserName();

String.prototype.appendUserName
= function() { return this + this.username; };

var greeting
= “hello”;

Response.Write(greeting.appendUserName());

 

Oh
dear me. We’ve set up a race condition. Multiple
instances of the page class running on multiple threads in the same appdomain might
all try to change the prototype object at the same time, and the last one is going
to win. Suddenly you’ve got pages that
serve up the wrong data! That data might
be highly sensitive, or the race condition may introduce logical errors in the script
processing — errors which will be nigh-impossible to reproduce and debug.

 

A
global writable object model in a multi-threaded appdomain where class instances should
not interact is a recipe for disaster, so we made the global object model read-only
in this scenario. If you need the convenience
of a writable object model, there is always compatibility mode.

Tags ASP JScript .NET Scripting

Comments (5)

Cancel reply

You must be logged in to post a comment.

  1. Dan Shappir says:Question 1: Is this the reason you also enforce the use of var in fast mode?Question 3: Out of curiosity – can you say how JScript.NET is fairing in the ASP.NET world vs. C# and VB.NET ?
  2. Log in to Reply
  3. Question 2: Doesn’t this make the term “fast mode” a bit of a misnomer? Shouldn’t it be “ASP.NET mode”?
  4. October 30, 2003 at 3:08 am
  5. Eric Lippert says:1) Yes — enforcing var improves clarity, improves optimizations and prevents accidental fouling of the global namespace.3) I have not the faintest idea. Remember, I haven’t actually worked on JS.NET for over two years now, and even if I was, I’m a developer, not a market researcher. (I can tell you that as far as throughput performance goes, JScript.NET on ASP.NET performs about as well as VB.NET, and both are 5%-10% slower than the equivalent C# in common scenarios — or, at least that was the case when I last ran the numbers.)
  6. Log in to Reply
  7. 2) Don’t be silly. I mean, we could have called them “incompatibility mode” and “slow mode” too, but obviously we wouldn’t. Fast mode was motivated by the requirements of ASP.NET, but the benefits go beyond ASP.NET scenarios.
  8. October 30, 2003 at 11:53 am
  9. Anonymous says:Ignore me I am testing.
  10. Log in to Reply
  11. October 30, 2003 at 12:14 pm
  12. Blake says:Perhaps a compromise could be reached for a future version of the language. It seems most of the interesting reasons for modifying the prototypes of the built in objects are all cases that are one-time setup. If these prototypes were writable only at appdomain creation time and read-only there after I think both sides could be happy?Log in to Reply
  13. (Not that there’s any current way to implement a .cctor in JS.NET that I’m aware of.)
  14. October 30, 2003 at 2:39 pm
  15. Samuel Bronson says:”ASP.NET mode” may be ridiculously specific, but it still seems like “fast mode” doesn’t say enough: it doesn’t say anything about allowing the script engine to be longer-lived or shared…
  16. Maybe it should be called something like “static mode”?
  17. June 28, 2010 at 12:22 pm
Advertisements

1 thought on “Global State On Servers Considered Harmful

  1. One thing you could’ve tried is to leave the global builtin objects read-only and keep track of each instance’s modifications. This might’ve been *slightly* slower, but I think it would’ve been worth the extra convenience.

Leave a Reply to sollyucko Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s