From: Ondrej Lichtner <olichtne(a)redhat.com>
This module implements the base class ConnectionHandler that is used to
store and handle multiple connections that are communicating during
recipe execution.
The module also contains the functions send_data and recv_data which are
used to deliver messages in our communication protocol.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/ConnectionHandler.py | 116 +++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
create mode 100644 lnst/Common/ConnectionHandler.py
diff --git a/lnst/Common/ConnectionHandler.py b/lnst/Common/ConnectionHandler.py
new file mode 100644
index 0000000..eb80055
--- /dev/null
+++ b/lnst/Common/ConnectionHandler.py
@@ -0,0 +1,116 @@
+"""
+This module defines the base class for connection handling, and helper
+functions used in our communication protocol.
+
+Copyright 2013 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+olichtne(a)redhat.com (Ondrej Lichtner)
+"""
+
+import select
+import cPickle
+import socket
+from _multiprocessing import Connection
+
+def send_data(s, data):
+ pickled_data = cPickle.dumps(data)
+ length = len(pickled_data)
+
+ data_to_send = str(length) + " " + pickled_data
+
+ try:
+ if isinstance(s, socket.SocketType):
+ s.sendall(data_to_send)
+ elif isinstance(s, Connection):
+ s.send(pickled_data)
+ else:
+ return False
+ except socket.error:
+ return False
+ return True
+
+def recv_data(s):
+ if isinstance(s, socket.SocketType):
+ length = ""
+ while True:
+ c = s.recv(1)
+ if c == ' ':
+ length = int(length)
+ break
+ elif c == "":
+ return ""
+ else:
+ length += c
+ data = ""
+
+ while len(data)<length:
+ c = s.recv(length - len(data))
+ if c == "":
+ return ""
+ else:
+ data += c
+
+ data = cPickle.loads(data)
+ elif isinstance(s, Connection):
+ data = s.recv()
+ data = cPickle.loads(data)
+ else:
+ return None
+ return data
+
+
+class ConnectionHandler(object):
+ def __init__(self):
+ self._connections = {}
+
+ def check_connections(self):
+ requests = []
+ rl, wl, xl = select.select(self._connections.values(), [], [])
+ for f in rl:
+ try:
+ data = recv_data(f)
+
+ if data == "":
+ f.close()
+ self.remove_connection(f)
+ else:
+ id = self.get_connection_id(f)
+ requests.append((id, data))
+
+ except socket.error:
+ f.close()
+ self.remove_connection(f)
+ except EOFError:
+ f.close()
+ self.remove_connection(f)
+ return requests
+
+ def get_connection(self, id):
+ if id in self._connections:
+ return self._connections[id]
+ else:
+ return None
+
+ def get_connection_id(self, connection):
+ for id in self._connections:
+ if self._connections[id] == connection:
+ return id
+ return None
+
+ def add_connection(self, id, connection):
+ if id not in self._connections:
+ self._connections[id] = connection
+
+ def remove_connection(self, connection):
+ d = {}
+ for key, value in self._connections.iteritems():
+ if value != connection:
+ d[key] = value
+ self._connections = d
+
+ def clear_connections(self):
+ self._connections = {}
--
1.7.11.7