3 ms·
Real world usage: an event-based architecture like the one employed in Keyspace [1]. We have an abstract class Callable, which has a member virtual void Execute
by Maro 17y ago
Real world usage: an event-based architecture like the one employed in Keyspace [1]. We have an abstract class Callable, which has a member virtual void Execute() and a global convenience function Call(Callable) which just calls ->Execute(). So a Callable is something that can be called, ie. a function pointer. We then have two concrete implementations, one for global (C) function pointers and one for class member (C++) function pointers. The whole thing is in Callable.h and is <100 lines of code, hence very lightweight.
Then, in the framework layer, we register callbacks using Callables in the IOProcessor. So if you create a TCP server with a TCP listening socket, you have a TCPRead object and you set its onComplete member, which is a Callable, to &TCPServer::OnConnect and analogously for onClose. Then, once a connection is establised you post TCPRead or TCPWrite objects for the new socket to IOProcessor to receive read notifications or perform writes, again with members onComplete and onClose.
Then, in the application layer you have actual database code which uses the network abstractions in the framework layer (which abstract away I/O), but they also use Callables to have themselves get called back when, for example an entire message has been read (eg. command is then parsed and executed) from the TCP stream or a client connection is terminated (eg. commands are canceled).
The whole program is then one big infinite loop, each iteration IOProcessor::Poll() being waken up by the O/S because something has happened, and Callables being called in turn. (On BSD, we kqueue, on Linux epoll and on Win32 Completion Ports to receive readyness notifications.) We also have support timers, which are just a linked list of Callables, and when IOProcessor::Poll() blocks we pass in the amount of time until the next timer must be executed as the timeout.
Or you can use libev/libevent, but they're not lightweight and will force you to do things their way.
[1] AGPL source is at http://scalien.com http://scalien.com