def handle(self, message): print "handles journalrequest", message self.database.add(message.unpacked_data) if message.subtype == JournalType.request: for u in self.database.get_all_units(): if u.type == UnitType.commander: print "Sending to", u.name msg = Message(message.sender, u.name, MessageType.journal, JournalType.request, unpacked_data = message.unpacked_data, prio = message.prio) self.queue.enqueue(u.name, msg.packed_data, msg.prio) return True print_color("Found no commander", 'red') elif message.subtype == JournalType.response: session = self.database._Session() req = session.query(JournalRequest).filter_by(id=message.unpacked_data.response_to).first() receiver= req.sender session.close() msg = Message(message.sender, receiver, MessageType.journal, JournalType.response, unpacked_data = message.unpacked_data, prio = message.prio) print_color("forwarded response to %s %s" % (msg.receiver, msg.packed_data), 'green') self.queue.enqueue(msg.receiver, msg.packed_data, msg.prio) return True return False
def dispatch(self, local_id, response_to): print_color("dispatching: %d %d" % (local_id, response_to), 'grey') data = self.queue.peek(local_id) try: msg = Message.unpack(data, self.db) except Exception, e: print "Couldn't unpack", data return
def mark_as_failed(self, id, error_code = 2): print_color("marking %d as failed" % id, 'red') # @TODO: acuire lock maybe? session = self.db._Session() q = session.query(data.NetworkInQueueItem).filter_by(id = id) item = q.first() item.processed = error_code session.commit() session.close()
def _put(self, item): ''' Save the packed data (item) and also repack it with message_id before commit to database ''' session = self.db._Session() if item.__class__ == NetworkOutQueueItem and \ "\"subtype\": \"change\"" in item.data: ''' Check for old events for the same unit and remove them. This will speedup the startup of clients. ''' res = re.findall(r'"id": (\d*)', item.data) assert len(res) == 1 id = res[0] #print "dumping old changes for id:", id res = session.query(NetworkOutQueueItem).filter_by(name=self.name, sent=0) to_del = [] for row in res: # Remove old change events match1 = re.findall(r'"subtype": "change"', row.data) # find id matching id number and terminator match2 = re.findall(r'"id": %s[,}]' % id, row.data) if len(match1) > 0 and len(match2) > 0: #print_color(str(row), 'red') to_del.append(str(row.id)) # Remove old service levels match_service_level = re.findall(r'"type": "service_level"', row.data) if len(match_service_level) > 0: to_del.append(str(row.id)) #print "to_del", to_del if len(to_del) > 0: session.execute("DELETE FROM OutQueue WHERE id IN (" + ",".join(to_del) + ")") #print "to_add", item.data session.add(item) session.flush() try: d = json.loads(item.data) d["message_id"] = item.id item.data = unicode(json.dumps(d)) except ValueError, e: print_color("not a valid json string. Trunkated by TCP?", 'red')
def run(self): running = True while running: inputready, outputready, exceptready = select.select(self.input, [], []) print "got input" for s in inputready: if s == self.server: (client, port) = self.server.accept() print "client connected from ", port # put client in temp list based on socket self._accept_client(client, port) elif s == sys.stdin: junk = sys.stdin.readline() if junk.startswith("q"): print "got quit" running = False elif s == self.heartbeat_socket: print "got heartbeat" data = None (pinger, port) = s.accept() try: data = pinger.recv(4) if data == "ping": print "got ping => pong" pinger.send("pong") except socket.error, e: print e pinger.close() else: # read and parse content length length = 0 try: hex_length = s.recv(6) length = int(hex_length, 16) except ValueError: pass except socket.error: self._disconnect_client(s) if length == 0: log.info("Invalid content length: " + hex_length) self._disconnect_client(s) continue data = s.recv(length) if data: log.debug("data from client:" + str(data)) local_id = self.inqueue.put(unicode(data)) m = None try: m = shared.data.Message.unpack(data, self.db) except ValueError, ve: log.info("Crappy data = ! JSON") if hasattr(ve, "origerror"): print_color(str(ve.orig_error), 'red') if hasattr(ve, "data"): print_color(ve.data, 'red') log.info(ve) continue if m.type == shared.data.MessageType.login: self._login_client(s, m) else: assert type(local_id) is long assert hasattr(m, "response_to") assert type(m.response_to) is int self.message_received(local_id, m.response_to) else: self._disconnect_client(s)