Standard Event Driven Object Library for D

Robert Fraser fraserofthenight at gmail.com
Tue Apr 1 21:13:47 PDT 2008


Brian White wrote:
> For the last 15 years, I've been working with a custom C++ library for 
> doing event-driven development.  Neither of D's "standard" libraries 
> appear to support this kind of development and I was wondering if there 
> is any interested in working on one.
> 
> That's not to say that you cannot do event-driven development given the 
> current libraries, but it follows the form of:
> 
> - do a "select" (epoll, whatever)
> - if socket "a" has a read event, do Xr
> - if socket "a" has a write event, do Xw
> - if socket "b" has a read event, do Yr
> - etc.
> - repeat
> 
> What I'm talking about is a library where all the objects handle events 
> and in turn generate their own.  When you create a socket, it 
> automatically registers itself with an event loop for that thread.  When 
> data comes in, the socket object gets the event with no "user code" 
> required.  The socket does what it needs for tracking the connection and 
> then sends an event to (for example) the socket-stream.  It does what it 
> needs and calls whatever object is controlling it.
> 
> In the end, it becomes easy to add self-contained services.  A simple 
> HTTP server, for example, can be started with a set of files and 
> absolutely no support from "main".  It doesn't have to be passed an open 
> connection, a listening socket, or even a select-server.  In addition, 
> the HTTP server itself can make choices about how it receives events, 
> turning them on or off as necessary, or perhaps going so far as spawing 
> new threads.  When a new connection comes in, the accepting of a new 
> socket bound to a connection-handler object means that the connection 
> handler is going to get the events associated with that socket.
> 
> Now it doesn't seem at first glance that this gains you much.  If the 
> HTTP server is getting notices directly from a select-server, then it 
> can do a read (or write, as appropriate) to the correct socket and 
> process the results.  That's self-contained, too.  But when the events 
> always flow from the bottom-up, here are some other things you could get:
> 
> - Buffering:  The socket stream (indeed, the base stream itself) can do 
> read/write bufferring with no support from the top.  In the case of a 
> write buffer, in can enable/disable write events when needed with no 
> invervention from the controlling object.  And, you only need to write 
> this code once to have it work with HTTP and all other socket services.
> 
> - Specialization:  A select server gives you "read" and "write" events. 
>  A socket can generate "read", "write", "connected", "closed", and 
> "broken" events.  Why have each network service have to differentiate 
> these independently?
> 
> - Extensibility:  A new feature of the HTTP service is now to accept 
> SIGHUP to reload a set of files.  Without touching one line of "main", 
> you simply have the HTTPserver object make a request for events from the 
> global signal handler.  Want to time-out connections?  Have the socket 
> request events from a timer module and notify the server if a time-out 
> occurs.
> 
> - Parallelism:  It becomes easier (not that multi-threading is ever 
> easy) to run different objects on different execute threads.  Since 
> there is no longer a global event loop created/instantiated by "main", 
> the library can make its own decisions (with restrictions, of course).
> 
> In my C++ code, I did all this with callbacks instead of posted events 
> because, well, it's more efficient and makes better sense than a single 
> event handling function per object with a big switch statement.  D's 
> delegates and interfaces should make this even easier.
> 
> 
> Now it's not to say that this method of programming is without it's 
> difficulties.  You can get loops.  For example: a socket gets a read 
> event, passes it all the way up to the HTTPserver object which, for 
> whatever reason, decides to close the connection.  The "close" call goes 
> down the stack, affects the underlying path, deregisters it from the 
> select-server, and returns... all the way up to the HTTPserver and then 
> back down the event callbacks to the select-server where it generated 
> the read event.  The socket was open and valid when it started the 
> callback but now it's closed.  You have to plan for this.
> 
> The other big problem is that you can't do this with an existing 
> library.  It has be built-in from the ground up.  Doing this in the D 
> library would require a new socket class, a new stream class, etc., etc. 
>  It doesn't have to replace the existing one but it would be parallel.
> 
> 
> What do others think of this?
> 
> -- Brian

I was thinking about porting SEDA, but Descent is taking all my 
programming time up right now.



More information about the Digitalmars-d mailing list