Here is a common question about TclHttpd:
How does TclHttpd to handle simultaneous hits from multiple clients
- does this involve locking or threading?
Tcl supports non-blocking, event-driven I/O
By default, TclHttpd uses non-blocking, event-driven I/O to multiplex
itself among
multiple client hits. It takes 1000's of hits daily on big web sites.
It does this by using the event loop features built into the Tcl
runtime system. Tcl has a "fileevent" command that registers
Tcl commands to be called when I/O is available on a socket.
It also has a "vwait" command that enters the event loop so that
the Tcl runtime can wait for events and make callbacks to the script level.
See the simple network server
example for more details about how this works.
What happens when the server blocks while servicing a request?
There are 3 answers:
- If the request is for a CGI application, then TclHttpd runs the
CGI process and communicates with it via a pipe. The Tcl event loop means
that TclHttpd only runs when there is data available on the pipe.
So, the CGI process can block arbitrarily long and TclHttpd is free
to service other I/O requests, such as connections from new clients.
- If the server would block because the client has a slow network
connection, then because it uses non-blocking I/O, well, it doesn't block.
Instead, it relies on the Tcl event loop to trigger a fileevent when
there is new data comming from the client, or when the write socket to
the client drains its output buffer.
-
If the server blocks for some other reason it can indeed starve clients.
The most typical example is if you make SQL calls to a database server directly
from TclHttpd. Those calls will block until the SQL server returns the answer.
Right now the OraTcl and SybTcl interfaces do not really support a non-blocking
interface that will free up TclHttpd to get back into its event loop.
If you don't use threading as described below, you may want to
move your long-running SQL queries into a CGI application.
If you are just serving files and short-running
dynamic pages, then it doesn't matter. So what if you use some CPU time
to compute a page. Passing that request off to another process (a la Apache)
or another thread (a la AOLserver) only helps on a multiprocessor.
On a uniprocessor, those approaches just add overhead.
Or, you can
enable threading the TclHttpd. This requires a recompile of
Tcl with the --enable-thread configure option, and the use of the Thread
extension. You can get this with TclHttpd "Bundled distribution".
With threading, TclHttpd can pass requests to worker threads.
The thread extension is described in more detail
here.
|