From: Frank Buss
Subject: another sockets library
Date: 
Message-ID: <1we11uy3zyxt2.jmc26ojssla8$.dlg@40tude.net>
I've created a small library for asynchronous sockets. They are used in
high performance web servers, like lighthttpd, because you need only one
thread for serving thousands of clients.

http://www.frank-buss.de/lisp/net-0.1.tgz

Currently it is C, only, but platform independant (works on Windows, Mac
OSX and Linux). There is a server and client example.

The goal of this library is to asynchronous server and client sockets for
TCP and UDP. Documentation is in net.h. For Windows I have already created
a Visual Studio .NET project, which creates a DLL and the sample programs.
For Linux and Mac there are shell scripts, which compiles the server and
client program.

The netWait function calls the onNetRead callbacks, if there are some data
for a socket available. With netRead the data will be read non-blocking. If
less data is read than in the OS buffer, the callback will be called again
(this is called level-triggered).

If you write data, it writes as much as possible without blocking. If less
bytes than requested are written, the onWrite callback is called again,
when it is possible to write more bytes without blocking. This is some kind
of edge-triggered, because it is only signalled once, after some data has
been written, and not all the time, when new data can be written. This
concept is used in Windows by default and simulated on the other platforms.

The implementation was a bit difficult, because there are different
underlying concepts on the 3 systems, because the (mostly) platform
independant "select" has a file limit of 64 on Windows and some Linux
systems.

The next step will be to write a CFFI wrapper for it, but first I would
like to hear some comments, if the interface (see net.h) is ok, or should
be changed or improved.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de

From: Antony Sequeira
Subject: Re: another sockets library
Date: 
Message-ID: <6pednVLm249PNtvbnZ2dnUVZ_rSjnZ2d@comcast.com>
Frank Buss wrote:
> I've created a small library for asynchronous sockets. They are used in
> high performance web servers, like lighthttpd, because you need only one
> thread for serving thousands of clients.
> 
> http://www.frank-buss.de/lisp/net-0.1.tgz
> 
> Currently it is C, only, but platform independant (works on Windows, Mac
> OSX and Linux). There is a server and client example.
> 
> The goal of this library is to asynchronous server and client sockets for
> TCP and UDP. 

Have you looked at
http://www.monkey.org/~provos/libevent/
It is used by
http://www.danga.com/memcached/

Personally, I think something like that integrated into the various CLs 
is very valuable.

I think asynchronous or at least non blocking IO is one of the features 
that can't be added on top of CL using CL (I am aware of CMUCL serve event).
That does not concern me too much.
What concerns me is that, it may not be feasible to add this 'cleanly' 
even through FFI (whatever kind). I am hoping I am wrong.

A model on how non-blocking IO can be integrated into a multi-threading 
aware language can be seen in Java (that's the one I know cause I have 
actually used it :) ), I just lurk hear learning interesting stuff, and 
not understanding 90% of the posted code :)

-Antony
From: Frank Buss
Subject: Re: another sockets library
Date: 
Message-ID: <82670v1wfydn$.l6glo1xlz3ia.dlg@40tude.net>
Antony Sequeira wrote:

> Have you looked at
> http://www.monkey.org/~provos/libevent/

Thanks, this looks interesting. Unfortunately it uses "select" on Windows.
select is limited to 64 sockets on this platform, unlike my program, which
has only the limit of the maximum number of handles per process (which
looks like it is 65536, including files, window handles, windows event
objects etc.).

But it uses the same BSD like license I have planned for my library. Maybe
I can reuse some code from it :-)

> I think asynchronous or at least non blocking IO is one of the features 
> that can't be added on top of CL using CL (I am aware of CMUCL serve event).
> That does not concern me too much.
> What concerns me is that, it may not be feasible to add this 'cleanly' 
> even through FFI (whatever kind). I am hoping I am wrong.

Why do you think it is not feasible? This is the exported interface of my
library:

http://www.frank-buss.de/tmp/net.h

Everything is called from within the same thread (the callbacks are called
synchronously from the netWait function). This means even non-multithreaded
CL implementations like CLISP could use it.

> A model on how non-blocking IO can be integrated into a multi-threading 
> aware language can be seen in Java (that's the one I know cause I have 
> actually used it :) )

I have used to Java NIO classes for a multiuser game server, too, and my
feeling was that it was terrible complicated to use. The API is
OO-over-designed, like many Java classes, e.g. I don't like the distinction
between Socket and SocketChannel.

The goal for my library is, that it is as easy to use as possible. This
implies that it should not aim to handle every objects, like files or
fifos, I want just network connections. I'm thinking about not to support
UDP, too, because this would increase the complexity of the API and most
applications won't need it.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Antony Sequeira
Subject: Re: another sockets library
Date: 
Message-ID: <DbKdnaAi3oLML9bbnZ2dnUVZ_tKjnZ2d@comcast.com>
Frank Buss wrote:
> Antony Sequeira wrote:
> 
>> Have you looked at
>> http://www.monkey.org/~provos/libevent/
> 
> Thanks, this looks interesting. Unfortunately it uses "select" on Windows.
> select is limited to 64 sockets on this platform, unlike my program, which
> has only the limit of the maximum number of handles per process (which
> looks like it is 65536, including files, window handles, windows event
> objects etc.).
I am a bit late on replying :(
Yes, but it would be good to fix that instead of doing a new lib. Of 
course you are the one doing the work :)
> 
> But it uses the same BSD like license I have planned for my library. Maybe
> I can reuse some code from it :-)
> 
>> I think asynchronous or at least non blocking IO is one of the features 
>> that can't be added on top of CL using CL (I am aware of CMUCL serve event).
>> That does not concern me too much.
>> What concerns me is that, it may not be feasible to add this 'cleanly' 
>> even through FFI (whatever kind). I am hoping I am wrong.
> 
> Why do you think it is not feasible? This is the exported interface of my
> library:
> 
> http://www.frank-buss.de/tmp/net.h
> 
> Everything is called from within the same thread (the callbacks are called
> synchronously from the netWait function). This means even non-multithreaded
> CL implementations like CLISP could use it.
Ok. I am just not sure how a loop to check the selectors gets integrated 
or how exceptions are to be handled. But never mind, keep posting on 
progress.
> 
>> A model on how non-blocking IO can be integrated into a multi-threading 
>> aware language can be seen in Java (that's the one I know cause I have 
>> actually used it :) )
> 
> I have used to Java NIO classes for a multiuser game server, too, and my
> feeling was that it was terrible complicated to use. The API is
> OO-over-designed, like many Java classes, e.g. I don't like the distinction
> between Socket and SocketChannel.
> 

Yes, I managed to use them to get some work done. By 'model' i meant 
that one could get a good idea about what goes along with a non-blocking 
IO. Anyone trying to design IO classes along with classes for 
non-blocing IO should study the Java mess.

Keeping the relationships/interactions between encoders/decoders, raw 
file IO, file buffering, socket IO and making all of it non-blocking and 
playing well with threading and exceptions is hard.

-Antony
From: szergling
Subject: Re: another sockets library
Date: 
Message-ID: <1179048888.065134.119800@q75g2000hsh.googlegroups.com>
On May 13, 12:50 pm, Frank Buss <····@frank-buss.de> wrote:
> I've created a small library for asynchronous sockets. They are used in
> high performance web servers, like lighthttpd, because you need only one
> thread for serving thousands of clients.
>
> http://www.frank-buss.de/lisp/net-0.1.tgz
>

[[...]]

>
> The next step will be to write a CFFI wrapper for it, but first I would
> like to hear some comments, if the interface (see net.h) is ok, or should
> be changed or improved.

I had a quick glance through it, and I like it. It is small and
simple, but until there's an impenetrable mess of typedefs, #ifdef,
and c-style macros, you cannot call it a 'decent' library (just
joking... or am I?). I would probably use it as a cookbook/reference
now. It's nice to have three different io and polling code side-by-
side for easy reading, especially when they are so uncluttered.
Actually, to call it 'net' might be a bit too generic... now, early
on, would be a good time for a better name that won't "clash" (but who
else would call their projects 'net'?).

Any tests? How would you test a thing like this anyway (it seems to
belong to the class of Heisenbug generators: sockets, io, threads, gc
and other pseudo-random things). There's also a library (nio) for this
in CL. Not sure how good it is...

Well, these are just my initial impressions. Will be reading some more
- most of the code is beyond my actual experience (I've never
personally written such code, but I'm mostly familiar with their
concepts). Sorry can't help more.
From: Frank Buss
Subject: Re: another sockets library
Date: 
Message-ID: <9qsdmglk6hjs.19xkg5zo2vy6f$.dlg@40tude.net>
szergling wrote:

> I had a quick glance through it, and I like it. It is small and
> simple, but until there's an impenetrable mess of typedefs, #ifdef,
> and c-style macros, you cannot call it a 'decent' library

I like clean C implementations, where all code which needs #ifdefs, is
moved to seperate files (it is not always possible, e.g. for the inevitable
declspec modifiers for Windows DLLs). I think this leads to easier to
maintain code. But I expect more #ifdefs, e.g. when porting it to different
Unix systems :-)

> Actually, to call it 'net' might be a bit too generic... now, early
> on, would be a good time for a better name that won't "clash"

I'll plan to integrate it into the Common Lisp Application Builder project,
then it will be named lispbuilder-net.

> Any tests? How would you test a thing like this anyway (it seems to
> belong to the class of Heisenbug generators: sockets, io, threads, gc
> and other pseudo-random things).

> There's also a library (nio) for this
> in CL. Not sure how good it is...

Do you mean this project? http://www.cliki.net/NIO

Looks intersting, especially that no native library is needed, but it has
no Windows support. Nevertheless it is licensed as BSD, too, so maybe I can
use some ideas of it. IPv6 looks like a good idea to include; it doesn't
make the API much more complicated.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: szergling
Subject: Re: another sockets library
Date: 
Message-ID: <1179056178.495273.169660@w5g2000hsg.googlegroups.com>
On May 13, 10:11 pm, Frank Buss <····@frank-buss.de> wrote:
> szergling wrote:

[[...]]

> > and other pseudo-random things).
> > There's also a library (nio) for this
> > in CL. Not sure how good it is...
>
> Do you mean this project?http://www.cliki.net/NIO

Sorry, I wasn't clear enough before. That's the one.

As for the testing, I was reading about all the hairy things in

http://www.die.net/doc/linux/man/man4/epoll.4.html

and thought that I couldn't fully reason over all possibilities (see
the Q&A for example), so I wasn't sure if all the edge cases would
carry over into what your library is trying to do... (probably Linux
specific only).

Just some random thoughts.
From: Frank Buss
Subject: Re: another sockets library
Date: 
Message-ID: <mzte5rm9i34n.zz1x28xlc2o5$.dlg@40tude.net>
szergling wrote:

> As for the testing, I was reading about all the hairy things in
> 
> http://www.die.net/doc/linux/man/man4/epoll.4.html

You are right, it looks a bit complicated. But the API is very simple,
which limits possible errors. E.g. the starvation problem can occur, only,
when using edge-triggering and an application doesn't read all data.
Reading all the data all the time would make the application interface more
complicated anyway, so I choose level-triggering. But using
level-triggering for netWrite didn't fit with the Windows way of FD_WRITE
(which looks more easy to use for application programmers), so this was the
reason I enable and disable POLLOUT all the time (same for kevent).

My idea is to define an easy to use semantic for the net* functions and
then to statically verify that it works with the implementation, but I'm
sure I have overseen many things and multithreading will be interesting,
too (e.g. when writing from different threads to the same socket and how it
interacts with netWait), so many test cases are necessary.

> and thought that I couldn't fully reason over all possibilities (see
> the Q&A for example), so I wasn't sure if all the edge cases would
> carry over into what your library is trying to do... (probably Linux
> specific only).

Some Q&As are dealing with more than one epoll fd. The epoll fd is not
accessible from the Lisp code, but maybe to make it simpler, it is a good
idea to allow only one event loop :-)

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Frank Buss
Subject: Re: another sockets library
Date: 
Message-ID: <100q3swfqi91i.1csksagx84xma.dlg@40tude.net>
szergling wrote:

> Any tests? How would you test a thing like this anyway (it seems to
> belong to the class of Heisenbug generators: sockets, io, threads, gc
> and other pseudo-random things).

Currently there is a server and client sample program. I think it would be
better to write unit testing code from Lisp. Should be not too difficult,
because the library provides server and client sockets, which means you can
send and receive data inside one testing application. And maybe some shell
scripts can execute multiple Lisp processes for automatic interprocess
tests.

This reminds me to another problem: Currently it is possible to use only
one event loop. Should I enhance this to allow multiple event loops? This
needs one extra handle parameter to all interface functions and netStartup
returns this handle, so the interface would not become much more
complicated, but maybe the implemenation.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: ······@gmail.com
Subject: Re: another sockets library
Date: 
Message-ID: <1179143144.610831.155410@o5g2000hsb.googlegroups.com>
Hi Frank,

On May 13, 2:50 am, Frank Buss <····@frank-buss.de> wrote:
> I've created a small library for asynchronous sockets. They are used in
> high performance web servers, like lighthttpd, because you need only one
> thread for serving thousands of clients.
>
> http://www.frank-buss.de/lisp/net-0.1.tgz
>
> Currently it is C, only, but platform independant (works on Windows, Mac
> OSX and Linux). There is a server and client example.
>
> The goal of this library is to asynchronous server and client sockets for
> TCP and UDP. Documentation is in net.h. For Windows I have already created
> a Visual Studio .NET project, which creates a DLL and the sample programs.
> For Linux and Mac there are shell scripts, which compiles the server and
> client program.
>
> The netWait function calls the onNetRead callbacks, if there are some data
> for a socket available. With netRead the data will be read non-blocking. If
> less data is read than in the OS buffer, the callback will be called again
> (this is called level-triggered).
>
> If you write data, it writes as much as possible without blocking. If less
> bytes than requested are written, the onWrite callback is called again,
> when it is possible to write more bytes without blocking. This is some kind
> of edge-triggered, because it is only signalled once, after some data has
> been written, and not all the time, when new data can be written. This
> concept is used in Windows by default and simulated on the other platforms.
>
> The implementation was a bit difficult, because there are different
> underlying concepts on the 3 systems, because the (mostly) platform
> independant "select" has a file limit of 64 on Windows and some Linux
> systems.

I've seen this remark about Windows sockets and select() a few times
before. Being an author of a sockets library for Lisp myself (and
aiming for
maximum portability - without additional requirements!) I was
triggered by
it and went on a web-seach.

What you see is actually not true, as
http://www.sockets.com/winsock.htm#Deviation_MaxSockets points out:

  "The maximum number of sockets which a Windows Sockets application
  can make use of is determined at compile time by the manifest
constant
  FD_SETSIZE. This value is used in constructing the fd_set structures
  used in select(). The default value in winsock.h is 64. If an
application is
  designed to be capable of working with more than 64 sockets, the
  implementor should define the manifest FD_SETSIZE in every source
file
  before including winsock.h. One way of doing this may be to include
the
  definition within the compiler options in the makefile, for example
adding
  -DFD_SETSIZE=128 as an option to the compiler command line for
  Microsoft C. It must be emphasized that defining FD_SETSIZE as a
  particular value has no effect on the actual number of sockets
provided by
  a Windows Sockets implementation."

Anyway, I hope it helps you to simplify your code where possible. I
intend to
use it myself where I need to in order to make my library's behaviour
match
with most unices.

bye,


Erik.
From: Frank Buss
Subject: Re: another sockets library
Date: 
Message-ID: <12iurdc09m69g$.1u865xakksqkw.dlg@40tude.net>
······@gmail.com wrote:

> I've seen this remark about Windows sockets and select() a few times
> before. Being an author of a sockets library for Lisp myself (and
> aiming for
> maximum portability - without additional requirements!) I was
> triggered by
> it and went on a web-seach.

Thanks, I didn't know this. Looks like in Windows the fd* macros uses an
array instead of a bit-field. But I'll use the event notification concept
with the invisible window anyway, because then I don't have to set a limit
at compile time and I don't have to write code for managing the select
array.

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de