[Zodb-checkins] SVN: ZODB/branches/network/notes.txt Some notes on
networking goals for ZEO and a low-level network
Jim Fulton
jim at zope.com
Sun May 7 17:48:21 EDT 2006
Log message for revision 68008:
Some notes on networking goals for ZEO and a low-level network
framework to support them.
Changed:
A ZODB/branches/network/notes.txt
-=-
Added: ZODB/branches/network/notes.txt
===================================================================
--- ZODB/branches/network/notes.txt 2006-05-07 15:26:29 UTC (rev 68007)
+++ ZODB/branches/network/notes.txt 2006-05-07 21:48:20 UTC (rev 68008)
@@ -0,0 +1,216 @@
+
+Goals
+=====
+
+1. Make ZEO sanely testable by separating network functions.
+ It should be possible to test most of ZEO without using sockets
+ or creating separate server threads or processes.
+
+2. Same as 1.
+
+3...10 same as 1. :)
+
+11. Make the networking support more pluggable to make it easier to
+ leverage existing network architecture, most notably Twisted.
+ This will give us better access to network functions like
+ authentication or encryption.
+
+12. Get rid of insane synchronous/asynchronous modes in th client
+ storage.
+
+13. Allow simultaneous synchronous calls from the same client.
+
+Testability is by far my main goal.
+
+A basic principal is that there should be a networking layer that is
+as small as possible. There should be no networking code outside this
+layer. It should be possible to test code outside this layer without
+creating sockets, servers, subprocesses or threads.
+
+ZEO Usage Patterns
+==================
+
+ZEO is nothing like HTTP. ZEO servers typically have a small number
+(at most tens) of long-lived stateful conections, as opposed to a web
+server that may have millions of short-lived stateless connections.
+Therefore the goals of a networking architecture to support ZEO are
+quite different from those needed to support HTTP.
+
+Implementation
+==============
+
+I'm not aware of any Python networking frameworks that provide the
+kind of separation and testability I'm looking for. I hope I'm wrong
+and that someone could point me to something we can reuse. If I'm
+right, then hopefully our efforts will spur others to create simpler
+more testable frameworks. I really don't want to be in the
+networking/RPC business.
+
+The networking layer should define some simple interfaces that can
+have multiple implementations. Ideally, the implementations should
+include:
+
+1. A test-fixture implementation
+
+2. A simple socket-based implementation.
+
+3. A Twisted implementation
+
+ZEO would then be built on top of this layer.
+
+Following are some initial implementation sketches.
+
+Interfaces
+----------
+
+::
+
+ class IConnectionHandler(Interface):
+ """Objects that can handle connection events
+ """
+
+ def input_data(connection, data):
+ """Handle input data from a connection
+
+ The data is an 8-bit string.
+ """
+
+ def connection_closed(connection, reason):
+ """Recieve notification that a connection has closed
+
+ The reason argument can be converted to a string for logging
+ purposes. It may have data useful for debugging, but this
+ is undefined.
+ """
+
+
+ class IConnection(Interface):
+ """Threaded network connections
+
+ Network connections handle input and output asynchronously from
+ application code. They are threaded, typically having their own
+ threads for input and outut. Handlers react to input data that
+ they collect and pass data to them without blocking.
+ """
+
+ def __nonzero__():
+ """Return the connection status
+
+ True is returned if the connection is open/active and
+ False otherwise.
+ """
+
+ def setHandler(handler):
+ """Set the IConnectionHandler for a connection.
+
+ The existing handler, if any is returned. None may be
+ passed to remove the handler. Any input recieved while
+ a handler is unset is queued.
+ """
+
+ def write(data):
+ """Write output data to a connection.
+
+ The write call is non-blocking.
+ """
+
+ def close():
+ """Close the connection
+ """
+
+
+ class ConnectionFailed(Exception):
+ """A attempt to connect has failed.
+ """
+
+
+ class IConnectionFactoryHandler(Interface):
+ """Recieve notifications of connection-creation attempts
+ """
+
+ def connected(connection):
+ """Recieve notification that a connection had been established
+ """
+
+ def failed_connection(reason):
+ """Recieve notificantion that a connection could not be established
+
+ The reason argument can be converted to a string for logging
+ purposes. It may have data useful for debugging, but this
+ is undefined.
+ """
+
+
+ class IClientConnectionFactory(Interface):
+ """Create a connection to a server
+ """
+
+ def __call__(addresses, handler=None,
+ min_delay=1, max_delay=1, delay_backoff=1,
+ max_attempts=None):
+ """Try to make a connection to one of the given addresses
+
+ The addresses argument is an iterable of addresses. Each of
+ the addreses is tried in turn. No connection is made, then
+ delay and try again. The delay is initially min_delay. It is
+ multiplied by delay_backoff after each attempt, but is limited
+ to max_delay. If max_tries is specified, then at most that
+ many attempts will be made (to each of the addresses) to
+ connect, after which a connection error will be generated.
+
+ The handler, if passes must be ann IConnectionFactoryHandler
+ and the call will return None immediately. The handler connected
+ method will be called with an IConnection object if and when
+ the connection suceeds or call the failed_connection method if
+ the connection fails.
+
+ If no handler is passed, then the call will block until a
+ conection is made successfully or fails. If the conection
+ succeeds, am IConnection will be returned, otherwise a
+ ConnectionFailed exception will be raised.
+ """
+
+
+ class IServerConnectionFactory(Interface):
+ """Listed for incoming connections
+ """
+
+ def __call__(address):
+ """Return an iterable of IConnection objects
+
+ The iterable returned has a close method that can be called to
+ stop receiving connections.
+ """
+
+Simple implementation
+---------------------
+
+For connection (IConnection) objects, I envision using 2 threads, an
+input thread and an outout thread. The input will use select, calling
+the IConnectionHandler callback when data arrives. The output thread
+will wait on a connection for input from the application and then do
+blocking output.
+
+The conection-factory implementations will be fairly similar to what
+we have now.
+
+Ideally, these implementations will provide hooks for providing fake
+sockets or socket-factories for testing purposes.
+
+Twisted Implementation
+----------------------
+
+I'm not a Twisted programmer, but the Twisted implementation seems
+straightforward. The only tricky part is managing the twisted reactor
+loop. The loop used for ZEO would have to start before doing any
+database operations.
+
+Packaging and impact on ZEO
+===========================
+
+The framework could and probably should be packaged as a separate
+package independent of ZEO.
+
+ZEO would be refactored to use the framework. ZEO's Sized Message
+Async Connection (smac) framework could be layered on this pretty
+easily. Everything else layers on smac.
Property changes on: ZODB/branches/network/notes.txt
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Zodb-checkins
mailing list