SF.net SVN: fclient: [349] trunk/sandbox/fcp2/client.py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2008-03-09 12:54:37
|
Revision: 349
http://fclient.svn.sourceforge.net/fclient/?rev=349&view=rev
Author: jUrner
Date: 2008-03-09 05:54:35 -0700 (Sun, 09 Mar 2008)
Log Message:
-----------
many comb overs
Modified Paths:
--------------
trunk/sandbox/fcp2/client.py
Modified: trunk/sandbox/fcp2/client.py
===================================================================
--- trunk/sandbox/fcp2/client.py 2008-03-09 12:53:45 UTC (rev 348)
+++ trunk/sandbox/fcp2/client.py 2008-03-09 12:54:35 UTC (rev 349)
@@ -177,6 +177,14 @@
# TODO: check if this is a bug in Fcp
# NOTE: seems to be fixed in [build 1112], fixes removed
#-------------------------------------------------------------------------------------------------------------------------------------------------
+# PutComplexDir
+#
+# x. currently not handled on PersistentPut. have to test this
+#
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------
+
+
import os, sys
import atexit
@@ -205,7 +213,8 @@
from fcp2 import key
from fcp2.fcp_lib import namespace
-from fcp2.fcp_lib import tools
+from fcp2.fcp_lib import tools
+from fcp2.fcp_lib import uuid
del hack
@@ -301,7 +310,8 @@
self._ddaTests = []
self._requests = {}
- self.ioHandler.close()
+ if self.ioHandler.isOpen():
+ self.ioHandler.close()
if msg is not None:
self.events.ClientDisconnected(msg)
@@ -334,6 +344,19 @@
del self._requests[request['Identifier']]
+
+ def _newUuid(self, uuids=None):
+ """Creates a new unique identifier
+ @param uuids: if desired any iterable containing uuids to enshure the identifier is unique in the iterable
+ @return: (str) uuid
+
+ """
+ uuid_ = uuid.uuid_time()
+ if uuids is not None:
+ while uuid_ in uuids:
+ uuid_ = uuid_time()
+ return uuid_
+
def _registerRequest(self,
msg,
requestType,
@@ -356,7 +379,7 @@
@return: (str) identifer of therequest
@note: the identifier returned is unique to the client but may not be unique to the node
"""
- identifier = fcparams.newUuid(uuids=self._requests) if identifier is None else identifier
+ identifier = self.newUuid(uuids=self._requests) if identifier is None else identifier
# equip requests with some additional params
@@ -373,18 +396,22 @@
@requestparam: B{RequestType:} one or more of the L{consts.RequestType} flags
@requestparam: B{Identifier:} identifier of the request
"""
- msg['Identifier'] = fcparams.newUuid(uuids=self._requests) if identifier is None else identifier
+ msg['Identifier'] = self._newUuid(uuids=self._requests) if identifier is None else identifier
msg['RequestType'] = requestType
msg['InitTime'] = time.time() if initTime is None else initTime
if requestType & consts.RequestType.MaskGet:
msg['FilenameCollision'] = filenameCollision
msg['UserData'] = userData
msg['PersistentUserData'] = persistentUserData
- msg['ClientToken'] = fcparams.messageToParams(msg)
+ msg['ClientToken'] = ''
+ msg.updatePersistentParams()
+
elif requestType & consts.RequestType.MaskPut:
msg['UserData'] = userData
msg['PersistentUserData'] = persistentUserData
- msg['ClientToken'] = fcparams.messageToParams(msg)
+ msg['ClientToken'] = ''
+ msg.updatePersistentParams()
+
elif requestType & consts.RequestType.MaskGenerateKeypair:
pass
elif requestType & consts.RequestType.SubscribeUSK:
@@ -401,18 +428,18 @@
## connection related methods
##
###############################################################
+ #TESTED
def close(self):
"""Closes the client
@note: make shure to call close() when done with the client
"""
msg = message.ClientDisconnected(
DisconnectReason=consts.DisconnectReason.Close,
- Param=None,
)
self._close(msg)
-
-
- def closeFreenet(self):
+
+ #TESTED
+ def closeNode(self):
"""Shuts down the freenet node"""
self.sendMessage(message.Shutdown())
@@ -431,7 +458,15 @@
pass
return nodeHello
+ #TESTED
+ def isOpen(self):
+ """Checks if the clients connection is open
+ @return: (bool) True if so, False otherwise
+ """
+ return self.ioHandler.isOpen()
+
+ #TESTED
def iterConnect(self, host=DefaultFcpHost, port=DefaultFcpPort, duration=20, timeout=0.5):
"""Iterator to stablish a connection to a freenet node
@param host: (str) host of th node
@@ -446,53 +481,50 @@
#TODO: we have to yield a few round here to make NodeHello injection work in unittests
# no idea exactly how many...
- disconnectReason = None
- disconnectParam = None
+ if self.ioHandler.isOpen():
+ disconnectMsg = message.ClientDisconnected(
+ DisconnectReason=consts.DisconnectReason.Reconnect,
+ )
+ self._close(disconnectMsg)
+
+ disconnectReason = consts.DisconnectReason.IOConnectFailed
t0 = time.time()
for result in self.ioHandler.iterConnect(duration=duration, timeout=timeout, host=host, port=port):
yield None
- timeElapsed = time.time() - t0
-
+
# try to get handshake
+ timeElapsed = time.time() - t0
if result:
- errorMsg = self.sendMessage(
+ self.sendMessage(
message.ClientHello(
Name=self._connectionName,
ExpectedVersion=self.ExpectedFcpVersion,
)
)
- yield None
- if errorMsg is None:
- timeElapsed = 0
- while timeElapsed <= duration:
+
+ while timeElapsed <= duration:
+ yield None
+ msg = self.next(dispatch=False)
+ if msg == message.ClientSocketTimeout:
+ disconnectReason = consts.DisconnectReason.NoNodeHello
+ timeElapsed += max(self.ioHandler.io.Timeout, 0.1)
yield None
- msg = self.next(dispatch=False)
- if msg == message.ClientSocketTimeout:
- timeElapsed += max(self.ioHandler.io.Timeout, 0.1)
- yield None
-
- elif msg == message.NodeHello:
- self._nodeHelloMessage = msg
- # check if version is ok
- if self.versionCheckNodeHello(msg):
- self.events.ClientConnected(msg)
- yield self._nodeHelloMessage
- raise StopIteration
- else:
- disconnectReason = consts.DisconnectReason.VersionMissmatch
- disconnectParam = msg
- break
-
+ elif msg == message.NodeHello:
+ self._nodeHelloMessage = msg
+ # check if version is ok
+ if self.versionCheckNodeHello(msg):
+ self.events.ClientConnected(msg)
+ yield self._nodeHelloMessage
+ raise StopIteration
else:
- disconnectReason = consts.DisconnectReason.UnknownNodeHello
- disconnectParam = msg
- break
+ disconnectReason = consts.DisconnectReason.VersionMissmatch
+ break
+ else:
+ disconnectReason = consts.DisconnectReason.UnknownNodeHello
+ break
- if disconnectReason is None:
- disconnectReason=consts.DisconnectReason.ConnectingFailed
disconnectMsg = message.ClientDisconnected(
DisconnectReason=disconnectReason,
- Param=disconnectParam,
)
self._close(disconnectMsg)
raise StopIteration
@@ -510,7 +542,7 @@
@param connectionName: (str) connection name or None to use an arbitrary connection name
@return: (str) connection name
"""
- self._connectionName = fcparams.newUuid() if connectionName is None else connectionName
+ self._connectionName = self._newUuid() if connectionName is None else connectionName
return self._connectionName
@@ -523,8 +555,8 @@
self.ioHandler.setDebugVerbosity(debugVerbosity)
- def startFreenet(self, cmdline):
- """Starts freenet
+ def startNode(self, cmdline):
+ """Starts the freenet node
@param cmdline: commandline to start freenet (like '/freenet/run.sh start' or 'c:\freenet\start.bat')
@return: (str) whatever freenet returns
@@ -543,10 +575,10 @@
def versionCheckNodeHello(self, nodeHelloMessage):
"""Performa a version check of the client against the specified NodeHello message
@return: (bool) True if version is ok, False otherwise
- @note: if this check returns False the client will emidiately disconnect in L{connect()}
- and triggers a ClientDisconnected event. Overwrite to adjust
+ @note: this implementation checks for FCPVersion == L{ExpectedFcpVersion}
+ and a Build >= L{ExpectedNodeBuild}
"""
- if nodeHelloMessage['FCPVersion'] >= self.ExpectedFcpVersion:
+ if nodeHelloMessage['FCPVersion'] == self.ExpectedFcpVersion:
if nodeHelloMessage['Build'] >= self.ExpectedNodeBuild:
return True
return False
@@ -578,7 +610,7 @@
return False
# resend request with new identifier
- newIdentifier = fcparams.newUuid(uuids=self._requests)
+ newIdentifier = self._newUuid(uuids=self._requests)
self._requests[newIdentifier] = initialRequest
del self._requests[requestIdentifier]
initialRequest['Identifier'] = newIdentifier
@@ -592,8 +624,7 @@
code = msg['Code']
if code == consts.ProtocolError.ShuttingDown:
disconnectMsg = message.ClientDisconnected(
- DisconnectReason=consts.DisconnectReason.Shutdown,
- Param=None,
+ DisconnectReason=consts.DisconnectReason.NodeClosing,
)
self._close(disconnectMsg)
return True
@@ -829,16 +860,24 @@
return True
- elif msg == message.PersistentGet:
+ elif msg == message.PersistentGet or msg == message.PersistentPut or msg == message.PersistentPutDir:
# unknown request... try to restore it
if initialRequest is None:
- fcParams = fcparams.paramsFromRequest(msg)
-
- # not one of our requests... so cancel it
- if fcParams is None or CancelPersistentRequests:
- if fcParams is None:
- self._loggers['Runtime'].critical(consts.LogMessages.RequestInvalidClientToken)
+
+ #FIXME: PutComplexDir???
+ if msg == message.PersistentGet:
+ initialRequest = message.ClientGet()
+ elif msg == message.PersistentPut:
+ initialRequest = message.ClientPut()
+ elif msg == message.PersistentPutDir:
+ initialRequest = message.ClientPutDiskDir()
+
+ initialRequest.params.update(msg.params)
+ result = initialRequest.restorePersistentParams()
+ if not result or CancelPersistentRequests:
+ if not result:
+ self._loggers['Runtime'].critical(consts.LogMessages.InvalidPersistentParams)
self.sendMessage(
message.RemovePersistentRequest(
Identifier=requestIdentifier,
@@ -847,18 +886,8 @@
)
return True
- initialRequest = message.ClientGet()
- self._registerRequest(
- initialRequest,
- fcParams[fcparams.IRequestType],
- identifier=requestIdentifier,
- initTime=fcParams[fcparams.IInitTime],
- userData=None,
- persistentUserData=fcParams[fcparams.IPersistentUserData],
- filenameCollision=fcParams[fcparams.IFilenameCollision],
- )
-
- initialRequest.params.update(msg.params)
+ self._requests[initialRequest['Identifier']] = initialRequest
+
#FIX: remove Started param from PersistentGet / Put
del initialRequest.params['Started']
#FIX: [0001965: Persistence vs PersistenceType]
@@ -868,7 +897,7 @@
self.events.RequestRestored(initialRequest)
return True
- # known request ..we don't handle that
+ # known request ..don't handle it
return False
@@ -879,23 +908,22 @@
modified = {}
# check if PersistentUserData has changed
- params = fcparams.paramsFromRequest(initialRequest)
- if params is not None:
- clientToken = msg.get('ClientToken', None)
- if clientToken is not None:
+ clientToken = msg.get('ClientToken', None)
+ if clientToken is not None:
+ modified[consts.RequestModified.PersistentUserData] = None
+
+ #TODO: its more or less a guess that PersistentUserData has changed
+ # ...as long as no other param is changed at runtime we are ok
+ # otherwise we would have to set flags to indicate wich member
+ # of ClientToken changed. See --> modifyRequest()
+ #
+ # hmm ..thinking again, this would only work if we could make shure
+ # PersistentUserData can only be modified through modifyRequest().
+ # So no way.
+
+ #TODO: ??? try ...except
+ initialRequest.restorePersistentParams()
- #TODO: its more or less a guess that PersistentUserData has changed
- # ...as long as no other param is changed at runtime we are ok
- # otherwise we would have to set flags to indicate wich member
- # of ClientToken changed. See --> modifyRequest()
- #
- # hmm ..thinking again, this would only work if we could make shure
- # PersistentUserData can only be modified through modifyRequest().
- # So no way.
- modified[consts.RequestModified.PersistentUserData] = None
- for i, fcParam in enumerate(fcparams.FcParams):
- initialRequest[fcParam] = params[i]
-
# check if PriorityClass has changed
priorityClass = msg.get('PriorityClass', None)
if priorityClass is not None:
@@ -930,52 +958,6 @@
## put related
- elif msg == message.PersistentPut or msg == message.PersistentPutDir:
-
- # unknown request... try to restore it
- if initialRequest is None:
- fcParams = fcparams.paramsFromRequest(msg)
-
- # not one of our requests... so cancel it
- if fcParams is None or CancelPersistentRequests:
- if fcParams is None:
- self._loggers['Runtime'].critical(consts.LogMessages.RequestInvalidClientToken)
- self.sendMessage(
- message.RemovePersistentRequest(
- Identifier=requestIdentifier,
- Global=msg['Global'],
- )
- )
- return True
-
- requestType = fcParams[fcparams.IRequestType]
- if requestType in (consts.RequestType.PutData, consts.RequestType.PutFile):
- initialRequest = message.ClientPut()
- elif requestType == consts.RequestType.PutDir:
- initialRequest = message.ClientPutDiskDir()
- elif request == consts.RequestType.PutMultiple:
- initialRequest = message.ClientPutComplexDir()
-
- self._registerRequest(
- initialRequest,
- requestType,
- identifier=requestIdentifier,
- initTime=fcParams[fcparams.IInitTime],
- userData=None,
- persistentUserData=fcParams[fcparams.IPersistentUserData],
- filenameCollision=fcParams[fcparams.IFilenameCollision],
- )
-
- #FIX: remove Started param from PersistentGet / Put
- del initialRequest.params['Started']
- initialRequest['RequestStatus'] |= consts.RequestStatus.Restored
- self.events.RequestRestored(initialRequest)
- return True
-
- # known request ..we don't handle that
- return False
-
-
elif msg == message.PutFailed:
if initialRequest is None:
return False
@@ -1088,7 +1070,6 @@
elif msg == message.CloseConnectionDuplicateClientName:
disconnectMsg = message.ClientDisconnected(
DisconnectReason=consts.DisconnectReason.DuplicateClientName,
- Param=None,
)
self._close(disconnectMsg)
return True
@@ -1137,8 +1118,7 @@
self.events.Idle(msg)
except iohandler.IOBroken, details:
msg = message.ClientDisconnected(
- DisconnectReason=consts.DisconnectReason.SocketDied,
- Param=details,
+ DisconnectReason=consts.DisconnectReason.ConnectionDied,
)
self._close(msg)
raise iohandler.IOBroken(details)
@@ -1200,19 +1180,20 @@
@note: you can use this method to send a message to the node, bypassing all
track keeping methods of the client
"""
- errorMsg = None
+
+ # Reminder to self:
+ #
+ # if socket dies on sendall ther is no way to determine if and how much data was send
+ # ...so assume data was send, cos there is no way to proove it was not send
try:
self.ioHandler.sendMessageEx(msg)
except iohandler.IOBroken, details:
errorMsg = message.ClientDisconnected(
- DisconnectReason=consts.DisconnectReason.SocketDied,
- Param=details
+ DisconnectReason=consts.DisconnectReason.ConnectionDied,
)
self._close(errorMsg)
raise iohandler.IOBroken(details)
- return errorMsg
-
-
+
#########################################################
##
## config related methods
@@ -2121,7 +2102,7 @@
if persistentUserData is not None:
initialRequest['PersistentUserData'] = persistentUserData
- initialRequest['ClientToken'] = fcparams.messageToParams(initialRequest)
+ initialRequest['ClientToken'] = initialRequest.updatePersistentParams()
modified[consts.RequestModified.PersistentUserData] = None
initialRequest['Modified'] = modified
@@ -2134,7 +2115,7 @@
)
if persistentUserData is not None:
initialRequest['PersistentUserData'] = persistentUserData
- msg['ClientToken'] = fcparams.messageToParams(initialRequest)
+ msg['ClientToken'] = initialRequest.updatePersistentParams()
if priorityClass is not None:
msg['PriorityClass'] = priorityClass
@@ -2207,10 +2188,12 @@
if requestKey.filename:
newRequest['URI'] += '/' + requestKey.filename
+
+ filenameCollision = newRequest.get('FilenameCollision', None)
self._registerRequest(
newRequest,
requestType,
- filenameCollision=newRequest['FilenameCollision'] & consts.FilenameCollision.MaskHandle,
+ filenameCollision= None if filenameCollision is None else filenameCollision & consts.FilenameCollision.MaskHandle,
#initTime=time.time(),
persistentUserData=newRequest['PersistentUserData'],
userData=oldUserData,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|