Am 03.01.2006 um 01:07 schrieb Vlad Seryakov:
Will it be more generic way just to set upper limit, if we see that
upload exceeds that limit, pass control to conn thread and let it
finish reading, this way, even spooling to file will work, because
each upload conn thread will use their own file and will not hold
driver thread.
But we already have this limit. It is: maxreadahead.
If we'd want to kill many flies with one stoke, I believe
we will have to step out of the box!
By doing everything in the driver thread (provided we get the
AIO to work, which I'm sure can be done cross-platform) we are
getting only one of the things solved: upload of large conent.
We are not solving the upload progress nor any other security,
quota, whatelse, reqs. In order to do this, we'd need hooks into
the driver thread processing. This will inevitably lead to adding
a Tcl script processing into the driver thread plus some kind of
locking which could possibly cripple drivers performance.
I would not like to do anything in the driver thread which is Tcl-
related.
And, if any IO is being done there, it should not be blocking.
One of the solution: move everything which exceeds "maxreadahead" into
the connection thread. This way you have all bits and pieces and you
can define whatever checking/statistic policy you need. The code doing
the multipart dissasembly can have hooks to inspect for progress, you
can stop/discard the upload based on some constraints (file size,
whatelse)
so you have total control. The down-side: you engage the conn thread and
risk getting DOS attacks, as Gustaf already mentioned in one of his last
responses to this thread.
I think naviserver model using driver-thread for getting connections
accepted and their data read in-advance before passing ctrl to conn
thread
is good for most of the dynamic-content systems but not for doing
(large)
file uploads and/or serving (large) static content (images, etc).
I believe that event-loop-type (or AIO processing) is more suitable
for that.
After all, you can have 100's of slow peers pumping or pulling files
to/from
you at the snail speed. In such case it is a complete waste to
allocate that
many connection threads as it will blow the system memory. A
dedicated pool of
threads each running in the event-loop mode would be far more
appropriate.
Actually, just one thread in event-loop would do the work perfectly
on a single
CPU box. On many-CPU box a pool of threads (one per CPU) would be
more appropriate.
So, there it comes: we'd have to invent a third instance of the
processing!
1. driver thread
2. connection thread
3. spooling thread
The driver thread gets the connection and reads all up to maxreadahead.
It then passes the connection to the conn thread.
The conn thread decides to run that connection entirely (POST of a
simple form
or GET, all content read-in) OR it decides to pass the connection to the
spooling thread(s).
The spooling threads operate in event-loop mode. There has to be some
kind
of dispacher which evenly distributes the processing among spooling
threads.
Once in the spooling thread, the connection is processed entirely
asynchronously
as in Tcl event-loop. In fact, this whole thing can be implemented in
Tcl with
the building blocks we already have: channel-transfer between
threads, thread
management (create, teardown). Event the dispatcher can be done in
Tcl alone.
After processing in the spooling thread, the entire connection can
then be
bounced back to the connection thread OR finished in the spooling
thread.
I hope I did not write a tons of nonsense and thank you for being
patient
and reading up to here :-)
So, what do you think?
Zoran