added socket disconnect; more socket fault tolerance; login re-try's since hitting...
authorerickson <erickson@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Tue, 3 Aug 2010 22:07:29 +0000 (22:07 +0000)
committererickson <erickson@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Tue, 3 Aug 2010 22:07:29 +0000 (22:07 +0000)
git-svn-id: svn://svn.open-ils.org/ILS-Contrib/constrictor/trunk@947 6d9bc8c9-1ec2-4278-b937-99fde70a366f

contrib/sip2/sip2_client.py
contrib/sip2/sip2_item_info_endurance.py

index 5d5dc80..c41d3bc 100644 (file)
@@ -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):
index e71e882..3774fba 100644 (file)
@@ -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())