From 858413d10233fc63c26c9894c4da59fc670f4e2b Mon Sep 17 00:00:00 2001 From: erickson Date: Tue, 3 Aug 2010 22:07:29 +0000 Subject: [PATCH] added socket disconnect; more socket fault tolerance; login re-try's since hitting a sip server with a pile of simultaneous logins is not always successful git-svn-id: svn://svn.open-ils.org/ILS-Contrib/constrictor/trunk@947 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- contrib/sip2/sip2_client.py | 66 +++++++++++++++++++++++++------- contrib/sip2/sip2_item_info_endurance.py | 2 + 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/contrib/sip2/sip2_client.py b/contrib/sip2/sip2_client.py index 5d5dc8056..c41d3bc7b 100644 --- a/contrib/sip2/sip2_client.py +++ b/contrib/sip2/sip2_client.py @@ -13,7 +13,7 @@ # GNU General Public License for more details. # ----------------------------------------------------------------------- -import sys, socket +import sys, socket, random, time import constrictor.task import constrictor.script import constrictor.log as log @@ -32,29 +32,54 @@ class SIP2Client(object): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except socket.error, msg: - log.log_error("%s\n" % msg[1]) + log.log_error("SIP2 socket error: %s\n" % msg[1]) return False try: self.sock.connect((self.server, self.port)) except socket.error, msg: - log.log_error("%s\n" % msg[1]) + log.log_error("SIP2 socket error: %s\n" % msg[1]) return False return True + def disconnect(self): + try: + self.sock.close() + except socket.error, msg: + log.log_error("SIP2 socket error: %s\n" % msg[1]) + return False + def send_msg(self, msg): log.log_debug('SIP2 socket sending: %s' % msg) - self.sock.send(msg + line_terminator) + try: + self.sock.send(msg + line_terminator) + except socket.error, msg: + log.log_error("SIP2 socket write error: %s\n" % msg[1]) + return None + + return True + def recv_msg(self): data = '' buf = '' while True: - buf = self.sock.recv(2048) + + try: + buf = self.sock.recv(2048) + except socket.error, msg: + log.log_error("SIP2 socket error: %s\n" % msg[1]) + return None + + if buf is None or buf == '': # server kicked us off + log.log_error("SIP2 server ejected us") + return None + data = data + buf log.log_debug("SIP2 socket read: %s" % buf) + if data[-(len(line_terminator)):] == line_terminator: break @@ -73,16 +98,31 @@ class SIP2Client(object): log.log_info("LoginTask: %s %s %s" % (username, password, institution)) msg = '9300CN%s|CO%s|CP%s|' % (username, password, institution) - client.send_msg(msg) - data = client.recv_msg() - if data[:3] == '941': - log.log_info("SIP2 login OK") - return True - else: - log.log_error("SIP2 login failed: %s" % data) - return False + for i in range(3): + + client.send_msg(msg) + data = client.recv_msg() + + if data is None: + # let's start over and try again + time.sleep(random.random() / 100) + client.disconnect() + client.init_socket() + continue + + if data[:3] == '941': + log.log_info("SIP2 login OK") + return True + + else: + log.log_error("SIP2 login failed: %s" % data) + return False + + log.log_error("SIP2 login failed with no server response") + return False + time.sleep(random.random() / 100) # reduce the chance of initial login collisions return LoginTask().start() def item_info_request(self, institution, copy_barcode): diff --git a/contrib/sip2/sip2_item_info_endurance.py b/contrib/sip2/sip2_item_info_endurance.py index e71e88289..3774fba17 100644 --- a/contrib/sip2/sip2_item_info_endurance.py +++ b/contrib/sip2/sip2_item_info_endurance.py @@ -44,6 +44,8 @@ class SIP2ItemInfoEnduranceScript(constrictor.script.Script): if not client.item_info_request(institution, copy_barcode): break + client.disconnect() + constrictor.script.ScriptManager.go(SIP2ItemInfoEnduranceScript()) -- 2.11.0