diff --git a/LCS/Messaging/python/messaging/RPC.py b/LCS/Messaging/python/messaging/RPC.py index 188d08b7e8d90f869cac48aecb125b5bea5d1510..ac54343d943105c75f4aa04c9e9023a8cb8a5f98 100644 --- a/LCS/Messaging/python/messaging/RPC.py +++ b/LCS/Messaging/python/messaging/RPC.py @@ -21,15 +21,15 @@ # RPC invocation with possible timeout from lofar.messaging.messagebus import ToBus,FromBus -from lofar.messaging.messages import ServiceMessage +from lofar.messaging.messages import ServiceMessage,ReplyMessage import uuid class RPC(): - def __init__(self,bus,service,timeout=None,GenerateExceptions=None): + def __init__(self,bus,service,timeout=None,ForwardExceptions=None): self.timeout=timeout - self.GenerateExceptions=False - if (GenerateExceptions==True): - self.GenerateExceptions=True + self.ForwardExceptions=False + if (ForwardExceptions==True): + self.ForwardExceptions=True self.BusName=bus self.ServiceName=service self.Request = ToBus(self.BusName+"/"+self.ServiceName, @@ -49,25 +49,33 @@ class RPC(): def __call__(self,msg,timeout=None): if (timeout==None): timeout=self.timeout - MyMsg=ServiceMessage(msg) - MyMsg.reply_to=self.ReplyAddress + MyMsg=ServiceMessage(msg,self.ReplyAddress) + #MyMsg.reply_to=self.ReplyAddress self.Request.send(MyMsg) + print("sent") answer=self.Reply.receive(timeout) + print("received or timed out") if (answer!=None): - status={} - try: - if (answer.status!="OK"): - status["state"]=answer.status - status["errmsg"]=answer.errmsg - status["backtrace"]=answer.backtrace - else: - status="OK" - except Exception as e: - status="Malformed return message" - else: - if (self.GenerateExceptions==True): - if (status!="OK"): - raise Exception(status) + if (isinstance(answer,ReplyMessage)): + status={} + exception=None + try: + if (answer.status!="OK"): + status["state"]=answer.status + status["errmsg"]=answer.errmsg + status["backtrace"]=answer.backtrace + if (answer.exception!=""): + exception=pickle.loads(answer.exception) + else: + status="OK" + except Exception as e: + status["state"]="ERROR" + status["errmsg"]="Return state in message not found" + status["backtrace"]="" + else: + if (self.ForwardExceptions==True): + if (exception!=None): + raise exception[0],exception[1],exception[2] try: answer=(answer.content,status) except Exception as e: diff --git a/LCS/Messaging/python/messaging/Service.py b/LCS/Messaging/python/messaging/Service.py index a7d624c5390d4120d2a1091a194de5e561f947d2..921eca9178d41e70f793dc1532a40e24c75790cb 100644 --- a/LCS/Messaging/python/messaging/Service.py +++ b/LCS/Messaging/python/messaging/Service.py @@ -21,12 +21,13 @@ # from lofar.messaging.messagebus import ToBus,FromBus -from lofar.messaging.messages import EventMessage,ServiceMessage +from lofar.messaging.messages import ReplyMessage,ServiceMessage import threading import time import uuid import sys import traceback +import pickle # create service: class Service(): @@ -99,6 +100,7 @@ class Service(): status="unknown" backtrace=None errtxt=None + exception=None # Keep track of number of processed messages self.counter[index]+=1 @@ -114,8 +116,8 @@ class Service(): # Any thrown exceptions either Service exception or unhandled exception # during the execution of the service handler is caught here. self._debug("handling exception") - exc_type, exc_value, exc_traceback = sys.exc_info() - backtrace=traceback.format_exception(exc_type, exc_value, exc_traceback) + exc_info = sys.exc_info() + backtrace=traceback.format_exception(*exc_info) errtxt=backtrace[-1] self._debug(backtrace) del backtrace[1] @@ -129,19 +131,22 @@ class Service(): print errtxt print backtrace replymessage=None + exception=pickle.dumps(exception) self._debug("Done call") # Compile Event message from reply and status. - ToSend=EventMessage(replymessage) + ToSend=ReplyMessage(replymessage,msg.reply_to) ToSend.status=status if (errtxt!=None): ToSend.errmsg=errtxt if (backtrace!=None): ToSend.backtrace=backtrace + if (exception!=None): + ToSend.exception=exception # ensure to deliver at the destination in the reply_to field - ToSend.subject=msg.reply_to + #ToSend.subject=msg.reply_to # show the message content if required by the Verbose flag. if (self.Verbose==True): diff --git a/LCS/Messaging/python/messaging/messages.py b/LCS/Messaging/python/messaging/messages.py index 9526a122007345a5702807986797165fb35c4710..f1a7019f52768da7ca94ffe5b5e04f8b8befb0c5 100644 --- a/LCS/Messaging/python/messaging/messages.py +++ b/LCS/Messaging/python/messaging/messages.py @@ -192,12 +192,14 @@ class LofarMessage(object): :raises: AttributeError """ - #print("Trying to set attribute %s with %s" %(name,value)) + print("Trying to set attribute %s with %s" %(name,value)) if name != 'properties': if name in _QPID_MESSAGE_FIELDS: self.__dict__['_qpid_msg'].__dict__[name] = value + print("set in native QPID") else: self.__dict__['_qpid_msg'].__dict__['properties'][name] = value + print("set in properties map") else: raise AttributeError("%r object has no attribute %r" % (self.__class__.__name__, name)) @@ -269,7 +271,7 @@ class ProgressMessage(LofarMessage): super(ProgressMessage, self).__init__(content) -class ServiceMessage(ApertifMessage): +class ServiceMessage(LofarMessage): """ Message class used for service messages. Service messages are request-reply type of messages. They are typically used to query a @@ -278,10 +280,11 @@ class ServiceMessage(ApertifMessage): def __init__(self, content=None, reply_to=None): super(ServiceMessage, self).__init__(content) - self.reply_to = reply_to + if (reply_to!=None): + self.reply_to = reply_to -class ReplyMessage(ApertifMessage): +class ReplyMessage(LofarMessage): """ Message class used for reply messages. Reply messages are part of the request-reply type of messages. They are typically used as a reply on a service @@ -289,8 +292,9 @@ class ReplyMessage(ApertifMessage): """ def __init__(self, content=None, reply_to=None): - super(ServiceMessage, self).__init__(content) - self.subject = reply_to + super(ReplyMessage, self).__init__(content) + if (reply_to!=None): + self.subject = reply_to