[Zodb-checkins] CVS: StandaloneZODB/ZEO/zrpc - connection.py:1.1.2.2.2.2 marshal.py:1.1.2.1.2.2
Jeremy Hylton
jeremy@zope.com
Fri, 26 Apr 2002 15:25:30 -0400
Update of /cvs-repository/StandaloneZODB/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv11377/zrpc
Modified Files:
Tag: ZEO2-branch
connection.py marshal.py
Log Message:
First step words protocol negotiation.
New client sends a 4-byte protocol id to the server. XXX Is this
sufficient for now?
Also, rename "wait_for_server_on_startup" to "wait". This change
affects a ctor calls in a bunch of files.
=== StandaloneZODB/ZEO/zrpc/connection.py 1.1.2.2.2.1 => 1.1.2.2.2.2 ===
__super_close = smac.SizedMessageAsyncConnection.close
__super_writable = smac.SizedMessageAsyncConnection.writable
+ __super_message_output = smac.SizedMessageAsyncConnection.message_output
+
+ protocol_version = "Z200"
def __init__(self, sock, addr, obj=None):
self.obj = None
@@ -88,6 +91,7 @@
self.__reply_lock = threading.Lock()
self.__reply_lock.acquire()
self.register_object(obj)
+ self.handshake()
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, self.addr)
@@ -108,6 +112,25 @@
"""Register obj as the true object to invoke methods on"""
self.obj = obj
+ def handshake(self):
+ # When a connection is created the first message sent is a
+ # 4-byte protocol version. This mechanism should allow the
+ # protocol to evolve over time, and let servers handle clients
+ # using multiple versions of the protocol.
+
+ # The mechanism replace the message_input() method for the
+ # first message received.
+
+ # The client sends the protocol version it is using.
+ self._message_input = self.message_input
+ self.message_input = self.recv_handshake
+ self.message_output(self.protocol_version)
+
+ def recv_handshake(self, message):
+ if message == self.protocol_version:
+ self.message_input = self._message_input
+ # otherwise do something else...
+
def message_input(self, message):
"""Decoding an incoming message and dispatch it"""
# XXX Not sure what to do with errors that reach this level.
@@ -298,8 +321,9 @@
class ServerConnection(Connection):
"""Connection on the server side"""
- # XXX Do we need this class anymore?
+ # The server side does not send a protocol message. Instead, it
+ # adapts to whatever the client sends it.
class ManagedServerConnection(ServerConnection):
"""A connection that notifies its ConnectionManager of closing"""
=== StandaloneZODB/ZEO/zrpc/marshal.py 1.1.2.1.2.1 => 1.1.2.1.2.2 ===
import cPickle
from cStringIO import StringIO
+import struct
import types
class Marshaller:
@@ -30,6 +31,8 @@
cPickle.PickleError,
cPickle.PicklingError)
+ VERSION = 1
+
def encode(self, msgid, flags, name, args):
"""Returns an encoded message"""
return self.pickle((msgid, flags, name, args), 1)
@@ -41,10 +44,10 @@
try:
return unpickler.load() # msgid, flags, name, args
- except (cPickle.UnpicklingError, IndexError), err_msg:
+ except (self.errors, IndexError), err_msg:
log("can't decode %s" % repr(msg), level=zLOG.ERROR)
raise DecodingError(msg)
-
+
_globals = globals()
_silly = ('__doc__',)