TechTips: Building web-applications for a *LOT* of users

Delphi makes it easy to design web-enabled applications ... up to a
point.  It's very easy to build ISAPI DLLs, for example, where the
web-server gets a request, spawns a thread, calls your code from the
thread, and you're supposed to formulate and send back a response as
HTML text.  All that much can be done in an afternoon.

Delphi also makes it possible to handle moderate amounts of overload,
which will naturally occur as your site becomes more popular and the
number of connections begins to increase.  Database-connection pooling,
for example, allows the threads to "wait in line" for the chance to
issue a database query.

But what will happen when your site becomes, say, "the next eBay?"  (I
mean, *besides* "well, I'll get stock options and move to Tahiti, and
the next programmer can fix it for me!" ;-))  How do you build an
application that can handle -that- kind of workload?  How do you build
apps that can allow a large number of simultaneous users to do more
complicated things with your site?  Doing this requires a basic change
of attitude -- a basic change in the architecture of how your
application will be constructed.  It will require more work, from the
very start.

I can't hope to map out the full elements of such a design for you in a
TechTip, and I can't anticipate what -your- application will require,
but let me toss out the germs of a few good ideas that will give you a
push in the right direction.

(This is the second most fun thing to watch at such a restauraunt
besides "what happens when a tour bus drives up AND their cash registers
are down!") A fast-food restauraunt has an efficient system for handling
massive workload by =dividing up the order among workers by task.=  You
interact with only one person, the order-taker.  Meanwhile, other
workers in the restauraunt are doing only one thing and doing it as fast
and as continuously as they can.  And they are doing it simultaneously.
"The fry guy" is churning out french-fries WHILE the "burger man" is
whamming out Big Macs as fast as he can, and so on.  Your order comes
together and is delivered to you as soon as the parts are there.
Meanwhile, the order-taker may have slid your tray to one side and
accepted another order.  Each person (worker-thread) is doing their
assigned task as rapidly as possible but does not overcommit.  If a
serious backlog develops in one area, reserve troops can be deployed to
any one of the work-activities, to the full capacity of the hardware
(the frier, the grill, and so on).

In web-talk, then, "the page producer" is the order-taker ... but the
order taker does not take one order and immediately go off and fill it.
The order taker never fries anything, MAYBE he fills a soft-drink cup
for you but in most stores that's your job now.  The "page producer"
simply enters a request and places it, simultaneously, on the
appropriate work queues.  When the response is fully assembled by the
various worker-bees, the page-producer delivers it to you.

You may not like it when orders stack-up, but the essential idea here is
that they can.  Every order is represented by a paper ticket, or its
equivalent.  The "state" of the order is recorded there.  Many threads
are looking at it and updating it simultaneously.

Have you noticed the McDonald's cash registers that now say 'average
service time 42 seconds?' or somesuch?  The ticket is also capturing
statistics about how long each part of each request takes to be
serviced.  The data from a day's worth or a week's worth of tickets can
be *modeled* later in various simulation computers to analyze where the
bottlenecks are occurring and how the overall process can be refined.  

MTS is the Microsoft Transaction Server.  There are other transaction
servers (like CICS) but the main thing here is ... plan from the outset
on using one.

A transaction-server is like "the restauraunt itself."  It handles the
basic mechanics of dispatching and queueing work, and storing
information about work in progress, and monitoring and controlling the
operation of "the restauraunt itself."  It's specifically designed to
handle high-workload situations, and for dealing with "transactions"
that may or may not be directly linked to a "database transaction."

The transaction-server model is very much like the fast-food restauraunt
I've described -- and it's the key to writing applications that CAN
handle large workloads gracefully.  MTS (I'm using the term generically
here) does all the dirty-chores of accepting and dispatching work among
groups of dedicated server-processes.  It can split-up "your order" into
separate smaller orders "to the fry-guy," "to mister burgerman," "to the
queen o' the shakes" (sorry, folks, my fast-food days and fast-food
slang are coming back on me ... all in fun), and keeping it all straight
-- for you.

The main thing that all of this avoids is "thrashing," or what some
authors call "DESTRUCTIVE overloading."  You know that the system will
alternate between times when it's deserted -- when the only thing there
is to do is sweep the floors a-gain -- and times when two tour-buses
drive up at the same time.  Workload management enables your server to
handle this variability without breaking down completely.  It also
enables you to gather statistics that will allow you to analyze what
happened after the fact, to determine whether you need to buy more
hardware or hire more warm-bodies or what have you.

Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259  (PGP public key available.)

> Fast(!), automatic table-repair with two clicks of the mouse!
> ChimneySweep(R):  "Click click, it's fixed!" {tm}