import os, time, socket
from marshal import dumps
from WebKit.Object import Object
from MiscUtils.Configurable import Configurable
class Adapter(Configurable, Object):
def __init__(self, webKitDir):
Configurable.__init__(self)
Object.__init__(self)
self._webKitDir = webKitDir
self._respData = []
def name(self):
return self.__class__.__name__
def defaultConfig(self):
return {
'NumRetries': 20,
'SecondsBetweenRetries': 3
}
def configFilename(self):
return os.path.join(self._webKitDir, 'Configs', '%s.config' % self.name())
def transactWithAppServer(self, env, myInput, host, port):
"""Get response from the application server.
Used by subclasses that are communicating with a separate app server
via socket. Returns the unmarshaled response dictionary.
"""
dict = {
'format': 'CGI',
'time': time.time(),
'environ': env,
}
# @@ gat 2002-03-21: Changed retry strategy. Now, we'll only retry the initial
# connection to the appserver. After that, any failure means the request failed.
# This is to avoid processing a request twice.
retries = 0
while 1:
try:
# Send our request to the AppServer
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
break
except socket.error:
# Retry
if retries <= self.setting('NumRetries'):
retries += 1
time.sleep(self.setting('SecondsBetweenRetries'))
else:
raise socket.error('timed out waiting for connection to app server')
data = dumps(dict)
s.send(dumps(int(len(data))))
s.send(data)
sent = 0
inputLength = len(myInput)
while sent < inputLength:
chunk = s.send(myInput[sent:])
sent += chunk
s.shutdown(1)
# Get the response from the AppServer
bufsize = 8*1024
# @@ 2000-04-26 ce: this should be configurable, also we should run some tests on different sizes
# @@ 2001-01-25 jsl: It really doesn't make a massive difference. 8k is fine and recommended.
# Wait for 0.5 seconds for data:
# s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, struct.pack('ll',0,5))
while 1:
data = s.recv(bufsize)
if not data:
break
self.processResponse(data)
return ''.join(self._respData)
def processResponse(self, data):
"""Process response data as it arrives."""
self._respData.append(data)
|