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