SF.net SVN: fclient: [311] trunk/sandbox/fcp2/client.py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <ju...@us...> - 2008-03-06 11:58:27
|
Revision: 311
http://fclient.svn.sourceforge.net/fclient/?rev=311&view=rev
Author: jurner
Date: 2008-03-06 03:58:32 -0800 (Thu, 06 Mar 2008)
Log Message:
-----------
use iohandler now
Modified Paths:
--------------
trunk/sandbox/fcp2/client.py
Modified: trunk/sandbox/fcp2/client.py
===================================================================
--- trunk/sandbox/fcp2/client.py 2008-03-06 11:57:34 UTC (rev 310)
+++ trunk/sandbox/fcp2/client.py 2008-03-06 11:58:32 UTC (rev 311)
@@ -182,7 +182,6 @@
import atexit
import copy
import logging
-import socket
import subprocess
import time
@@ -199,8 +198,9 @@
from fcp2 import consts
from fcp2 import config
from fcp2 import events
-from fcp2 import message
from fcp2 import fcparams
+from fcp2 import message
+from fcp2 import iohandler
from fcp2 import types
from fcp2 import key
@@ -225,8 +225,7 @@
@cvar MaxSizeKeyInfo: (bytes) maximum request size for key info requests
@cvar inimumRunTime: (seconds) minimum runtime when the L{run} method is called.
Required to make shure persistent requests can be taken up from the node.
- @cvar SocketTimeout: (seconds) default socket timeout
-
+
@ivar events: events the client supports
@@ -242,8 +241,7 @@
DefaultFcpPort = int(os.environ.get('FCP_PORT', '9481'))
MaxSizeKeyInfo = 32768
MinimumRunTime = 1 # FIX: 0001931
- SocketTimeout = 0.1
-
+
consts = consts
config = config
message = message
@@ -271,7 +269,7 @@
}
self._nodeHelloMessage = None
self._requests = {} # currently running requests (requestIdentifier --> request)
- self._socket = None
+ self.ioHandler = iohandler.IOHandler()
for event in self.events:
event += self._captureEvent
@@ -294,7 +292,7 @@
@todo: complain if the client is already closed?
"""
- self._loggers['Runtime'].info(consts.LogMessages.ClientClose)
+ self._loggers['Runtime'].info(consts.LogMessages.Closing)
# clean left over DDA test tmp files
for initialRequest in self._ddaTests:
@@ -304,14 +302,9 @@
self._ddaTests = []
self._requests = {}
- if self._socket is None:
- # complain or not?
- pass
- else:
- self._socket.close()
- self._socket = None
- if msg is not None:
- self.events.ClientDisconnected(msg)
+ self.ioHandler.close()
+ if msg is not None:
+ self.events.ClientDisconnected(msg)
def _finalizeRequest(self, msg, request, event):
@@ -488,43 +481,31 @@
@event: ClientConnected(event, message) is triggered as soon as the client is connected
"""
- self._loggers['Runtime'].info(consts.LogMessages.Connecting)
- # try to Connect socket
- if self._socket is not None:
- self._close(None)
-
- # poll untill freenet responds
- timeElapsed = 0
- while timeElapsed < duration:
-
- # try to Connect socket
- if self._socket is not None:
- self._close(None)
- self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self._socket.settimeout(self.SocketTimeout)
- try:
- self._socket.connect((host, port))
- except socket.error, d:
- yield None
- else:
- self._loggers['Runtime'].info(consts.LogMessages.Connected)
-
- # send ClientHello and wait for NodeHello
- #NOTE: thought I could leave ClientHelloing up to the caller
- # but instad of responding with ClientHelloMustBeFirst
- # as expected when not doing so, the node disconnects.
- # So take it over here.
- self.sendMessage(
+ #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
+ 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
+ if result:
+ errorMsg = self.sendMessage(
consts.Message.ClientHello,
Name=self._connectionName,
ExpectedVersion=self.ExpectedFcpVersion,
)
+ yield None
+ if errorMsg is None:
+ timeElapsed = 0
while timeElapsed <= duration:
+ yield None
msg = self.next(dispatch=False)
-
if msg.name == consts.Message.ClientSocketTimeout:
- timeElapsed += self.SocketTimeout
+ timeElapsed += max(self.ioHandler.io.Timeout, 0.1)
yield None
elif msg.name == consts.Message.NodeHello:
@@ -532,35 +513,29 @@
# check if version is ok
if self.versionCheckNodeHello(msg):
self.events.ClientConnected(msg)
+ yield self._nodeHelloMessage
+ raise StopIteration
else:
- disconnectMsg = message.Message(
- consts.Message.ClientDisconnected,
- DisconnectReason=consts.DisconnectReason.VersionMissmatch,
- Param=msg,
- )
- self._close(disconnectMsg)
- yield self._nodeHelloMessage
- raise StopIteration
+ disconnectReason = consts.DisconnectReason.VersionMissmatch
+ disconnectParam = msg
+ break
else:
- self._loggers['Message'].debug(consts.LogMessages.MessageReceived + msg.pprint())
+ disconnectReason = consts.DisconnectReason.UnkownNodeHello
+ disconnectParam = msg
break
- break
-
- # continue polling
- self._loggers['Runtime'].info(consts.LogMessages.ConnectionRetry)
- timeElapsed += timeout
- time.sleep(timeout)
- self._loggers['Runtime'].info(consts.LogMessages.ConnectingFailed)
+
+ if disconnectReason is None:
+ disconnectReason=consts.DisconnectReason.ConnectingFailed
disconnectMsg = message.Message(
consts.Message.ClientDisconnected,
- DisconnectReason=consts.DisconnectReason.ConnectingFailed,
- Param=None,
+ DisconnectReason=disconnectReason,
+ Param=disconnectParam,
)
self._close(disconnectMsg)
- raise StopIteration
-
+ raise StopIteration
+
def getConnectionName(self):
"""Returns the connection name used by the client
@@ -584,6 +559,7 @@
"""
for logger in self._loggers.values():
logger.setLevel(debugVerbosity)
+ self.ioHandler.setDebugVerbosity(debugVerbosity)
def startFreenet(self, cmdline):
@@ -624,7 +600,7 @@
@param msg: (Message) to handle
@return: True if the message was handled, False otherwise
"""
-
+
CancelPersistentRequests = 0 # for testing... if True, cancels all PersistentRequests
# check if we have an initial request corrosponding to msg
@@ -1197,28 +1173,26 @@
@note: use this method to run the client step by step. If you want to run the
client unconditionally use L{run}
"""
- msg = message.Message.fromSocket(self._socket)
- if msg.name == consts.Message.ClientSocketDied:
- self._loggers['Runtime'].critical(consts.LogMessages.SocketDied)
+ try:
+ msg = self.ioHandler.readMessage()
+ except iohandler.IOTimeout, details:
+ msg = message.Message(consts.Message.ClientSocketTimeout)
if dispatch:
- disconnectMsg = message.Message(
+ self.events.Idle(msg)
+ except iohandler.IOBroken, details:
+ msg = message.Message(
consts.Message.ClientDisconnected,
DisconnectReason=consts.DisconnectReason.SocketDied,
- Param=msg,
+ Param=details,
)
- self._close(disconnectMsg)
- #raise socket.error(msg['Param']['Details'])
-
- elif msg.name == consts.Message.ClientSocketTimeout:
- if dispatch:
- self.events.Idle(msg)
+ self._close(msg)
+ raise iohandler.IOBroken(details)
else:
- self._loggers['Message'].debug(consts.LogMessages.MessageReceived + msg.pprint())
if dispatch:
self.handleMessage(msg)
return msg
+
-
def run(self):
"""Runs the client unconditionally untill all requests have completed
@note: a KeyboardInterrupt will stop the client
@@ -1268,10 +1242,8 @@
@param data: data to atatch to the message
@param params: {para-name: param-calue, ...} of parameters to pass along
with the message (see freenet protocol)
- @raise SocketError: if the socket connection to the node dies unexpectedly
- If an error handler is passed to the client it is called emidiately before the error
- is raised.
+
@note: you can use this method to send a message to the node, bypassing all
track keeping methods of the client
"""
@@ -1280,29 +1252,27 @@
def sendMessageEx(self, msg):
"""Sends a message to freenet
- @param msg: (Message) message to send
- @return: Message
- @raise SocketError: if the socket connection to the node dies unexpectedly.
- If an error handler is passed to the client it is called emidiately before the error
- is raised.
-
+ @param msg: (L{message.Message}) message to send
+ @return: (L{message.Message}) disconnect if something went wrong
+
+ @note: If an error occurs the client is closed
@note: you can use this method to send a message to the node, bypassing all
track keeping methods of the client
"""
- self._loggers['Message'].debug(consts.LogMessages.MessageSend + msg.pprint())
+ errorMsg = None
try:
- msg.send(self._socket)
- except socket.error, d:
- self._loggers['Runtime'].critical(consts.LogMessages.SocketDied)
- disconnectMsg = message.Message(
+ self.ioHandler.sendMessageEx(msg)
+ except iohandler.IOBroken, details:
+ errorMsg = message.Message(
consts.Message.ClientDisconnected,
DisconnectReason=consts.DisconnectReason.SocketDied,
- Param=message.Message(consts.Message.ClientSocketDied, Exception=socket.error, Details=d)
+ Param=details
)
- self._close(disconnectMsg)
- raise socket.error(d)
- return msg
+ self._close(errorMsg)
+ raise iohandler.IOBroken(details)
+ return errorMsg
+
#########################################################
##
## config related methods
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|