John Black said:
I keep hearing about how Javascript / Node.js is great for web servers
because its "event driven" and "non-blocking"... Statements like this
are often made: "JavaScript happens to be a great fit for writing
servers due to its event-driven nature."
This statement doesn't mean very much except that the person who made it
is almost certainly repeating something she heard elsewhere without
actually knowing what the terms mean.
But how hard is it to use Perl for an event driven application like a
web server. Seems to me you can just have a main thread processing
the event requests. For each request, it spawns a thread to go off
and do the work which reports back when done. The main event queueing
thread is not "blocked" while the other threads are doing the work.
Presto - event driven... What am I missing?
NB: The text below is heavily simplified in order to explain the general
principle.
'Blocked' usually means 'process called into the kernel in order to
receive input on file descriptor ... and now waits until some is
available'. In a situation where many independent clients talk to a
single server using individual TCP connections, eg, in a web server, the
server obviously can't block on a single connection until input data
becomes available and continue to deal with the connections of other
clients at the same time. A so-called 'concurrent TCP server' is needed
in this case. A simple way to provide that is to create a new process
(or thread, although perl threads are not light-weight compared to perl
processes) per client so that each process deal with exactly one TCP
connection and is thus free to make potentially blocking I/O calls as it
suits it. A somewhat more complicated but usually more efficient way is
to use a so-called 'event-driven server': In this case, the process
blocks in system call which waits for input ('events') on multiple file
descriptors concurrently. As soon as data becomes available on any of
them, the process returns to userspace, reads the available data and
continues "where it left of last time" (based on somehow recorded state
information) for this TCP connection and then the next and the next and
so on, until all available input has been consumed. Afterwards, it goes
to the 'wait for something to happen'.
Unfortunately, the only thing perl supports out of the box for this is
select (which has two meanings in Perl) which is the oldest (AFAIK,
invented for 4.2BSD) API providing this facility and the most widely
supported (meaning, it will work on Windows as badly as anywhere
else). Depending on the system you are using (or 'the systems you plan
to support') other interface with more or less useful/ sensible perl
support may be available.
Because 'generalized event loop' (with 'cooperative userspace threading'
hiding ready to ambush in some dark corner nearby) is an all-time
classic of recreational programming, you'll also find uncountable
numbers of mutually incompatible 'generalized event loop' implementation
on CPAN (most of them presumably abandonware).