def call(self, key, data=None, timeout=5, block=None): log.debug('RPC-CALL: execute %s = %s' % (key, data)) if block is None: block = True # @todo: remove consume again afterwards! if not timeout: # tuba - no_ack=True is also an option self.consumerTag = self.ch.basic_consume(self.queue, callback=self._callback) self.response = None self.correlationId = getUuid() # str(uuid.uuid4()) msg = amqp.Message( json.encode(data), content_type='text/json', correlation_id=self.correlationId, # reply_to = self.queue ) self.ch.basic_publish( msg, self.exchange, key, # reply_to = self.queue, # correlation_id = self.correlationId ) if not block: return log.notice('RPC-CALL: wait response') startTime = time.time() while self.response is None: if timeout: msg = self.ch.basic_get(self.queue) if msg: if self._callback(msg): break else: time.sleep(0.01) if (time.time() - startTime) >= timeout: raise TimeoutException('Waited %s sec for rpc call %s' % (timeout, key)) else: self.ch.wait() log.notice('RPC-CALL: finished waiting') try: body = json.decode(self.response.body) except Exception as e: raise Exception("json decoding error: %s - for raw response: %s" % (e, self.response.body)) tmp = self.response.routing_key.split('.') if tmp[0][1] == 'x': # todo: use constants if tmp[0][0] == 'o': d = 'orchestrator' # here too elif tmp[0][0] == 's': d = 'service' elif tmp[0][0] == 'r': d = 'reactor' elif tmp[0][0] == 'm': d = 'manager' e = RemoteException('Error in %s %s when calling %s' % (d,tmp[1],tmp[2])) e.setResponse(body) raise e log.debug('RPC-CALL: respone %s = %s' % (self.response.routing_key, body)) return body
def _callback(self, msg): log.notice('RPC-CALL: callback seen: %s = %s' % (msg.routing_key, msg.body)) res = None if len(msg.routing_key) > 1 and msg.routing_key[1] in ['r','x'] and 'correlation_id' in msg.properties and msg.properties['correlation_id'] == self.correlationId: log.notice('RPC-CALL: callback matched: %s = %s' % (msg.routing_key, msg.body)) self.response = msg res = True else: res = False if not self.noAck and res: self.ch.basic_ack(msg.delivery_tag) return res
def listen(self): log.info('Start listening for messages, topics = %s' % self.getConsumeKeys()) actionPrefix = self.getActionPrefix() heartBeatRequestPrefix = self.getHeartBeatRequestPrefix() while not self._shutdown: log.notice('Waiting for messages') try: topic, data, correlationId = self.consumer.get() except socket.error, e: self.reconnect(e) continue except amqplib.client_0_8.exceptions.AMQPConnectionException, e: self.reconnect(e) continue
def call(self, key, data=None, timeout=5, block=None): log.debug('RPC-CALL: execute %s = %s' % (key, data)) if block == None: block = True # @todo: remove consume again afterwards! if not timeout: # tuba - no_ack=True is also an option self.consumerTag = self.ch.basic_consume(self.queue, callback=self._callback) self.response = None self.correlationId = getUuid() #str(uuid.uuid4()) msg = amqp.Message( json.encode(data), content_type='text/json', correlation_id = self.correlationId, #reply_to = self.queue ) self.ch.basic_publish( msg, self.exchange, key, #reply_to = self.queue, #correlation_id = self.correlationId ) if not block: return log.notice('RPC-CALL: wait response') startTime = time.time() while self.response is None: if timeout: msg = self.ch.basic_get(self.queue) if msg: if self._callback(msg): break else: time.sleep(0.01) if (time.time()-startTime) >= timeout: raise TimeoutException('Waited %s sec for rpc call %s' % (timeout, key)) else: self.ch.wait() log.notice('RPC-CALL: finished waiting') try: body = json.decode(self.response.body) except Exception, e: raise Exception("json decoding error: %s - for raw response: %s" % (e, self.response.body))
def __init__(self, conn, queuePrefix=None): if not queuePrefix: queuePrefix = 'unspecified-rpc' Channel.__init__(self, conn, queuePrefix=queuePrefix) keys = ['#'] self.consumeKeys = keys self.ch.access_request('/data', active=True, read=True, write=True) # False) self.exchange_declare() # these should be exclsive or they don't auto-delete for some reason self.queue_declare(exclusive=True) for key in keys: log.notice('Listen to: %s' % key) self.ch.queue_bind(self.queue, self.exchange, key) self.deliveryTag = None self.correlationId = None self.response = None
def _callback(self, msg): log.notice('RPC-CALL: callback seen: %s = %s' % (msg.routing_key, msg.body)) res = None if len(msg.routing_key) > 1 and msg.routing_key[1] in [ 'r', 'x' ] and 'correlation_id' in msg.properties and msg.properties[ 'correlation_id'] == self.correlationId: log.notice('RPC-CALL: callback matched: %s = %s' % (msg.routing_key, msg.body)) self.response = msg res = True else: res = False if not self.noAck and res: self.ch.basic_ack(msg.delivery_tag) return res
def listen(self): log.info('Start listening for messages, topics = %s' % self.getConsumeKeys()) actionPrefix = self.getActionPrefix() heartBeatRequestPrefix = self.getHeartBeatRequestPrefix() while not self._shutdown: log.notice('Waiting for messages') try: topic, data, correlationId = self.consumer.get() except socket.error as e: self.reconnect(e) continue except amqplib.client_0_8.exceptions.AMQPConnectionException as e: self.reconnect(e) continue except IOError as e: self.reconnect(e) continue except Exception as e: log.error('Caught during consumer.get() in listen: %s' % utils.e2str(e)) raise e try: self.consumer.ack() except Exception as e: log.error('Caught during consumer.ack() in listen: %s' % utils.e2str(e)) raise e if self._shutdown: log.info( 'Not handeling topic: %s because self._shutdown = True' % (topic, )) else: log.notice('Handeling topic: %s' % topic) tmp = topic.split('.') handle = False if tmp[0] == actionPrefix and len( tmp) > 1 and tmp[1] == self.id: pre, src, key = tmp if key == '_shutdown': continue if not data: data = [] try: result = self.runAction(key, data) except Exception as e: self.sendActionError(key, e, correlationId) else: if result is not None or correlationId: self.sendActionResponse(key, result, correlationId) elif tmp[0] == heartBeatRequestPrefix: self.sendHeartBeatResponse() else: self.onMessage(topic, data, correlationId) log.notice('Handeled topic: %s' % topic) log.info('Exited listen() loop - self._shutdown = %s' % self._shutdown)
def listen(self): log.info('Start listening for messages, topics = %s' % self.getConsumeKeys()) actionPrefix = self.getActionPrefix() heartBeatRequestPrefix = self.getHeartBeatRequestPrefix() while not self._shutdown: log.notice('Waiting for messages') try: topic, data, correlationId = self.consumer.get() except socket.error as e: self.reconnect(e) continue except amqplib.client_0_8.exceptions.AMQPConnectionException as e: self.reconnect(e) continue except IOError as e: self.reconnect(e) continue except Exception as e: log.error('Caught during consumer.get() in listen: %s' % utils.e2str(e)) raise e try: self.consumer.ack() except Exception as e: log.error('Caught during consumer.ack() in listen: %s' % utils.e2str(e)) raise e if self._shutdown: log.info('Not handeling topic: %s because self._shutdown = True' % (topic,)) else: log.notice('Handeling topic: %s' % topic) tmp = topic.split('.') handle = False if tmp[0] == actionPrefix and len(tmp) > 1 and tmp[1] == self.id: pre, src, key = tmp if key == '_shutdown': continue if not data: data = [] try: result = self.runAction(key, data) except Exception as e: self.sendActionError(key, e, correlationId) else: if result is not None or correlationId: self.sendActionResponse(key, result, correlationId) elif tmp[0] == heartBeatRequestPrefix: self.sendHeartBeatResponse() else: self.onMessage(topic, data, correlationId) log.notice('Handeled topic: %s' % topic) log.info('Exited listen() loop - self._shutdown = %s' % self._shutdown)
def onEvent(self, event): log.notice("RuleSet: event occurred: %s" % event) for s in self.sets: s.onEvent(event)
def sendHeartBeatEvent(self, data): topic = '%s.%s' % (self.getHeartBeatResponsePrefix(), self.id) log.notice('sendHeartBeat: %s = %s' % (topic, data)) self.producer.put(topic, data)
def call(self, key, data=None, timeout=5, block=None): log.debug('RPC-CALL: execute %s = %s' % (key, data)) if block is None: block = True # @todo: remove consume again afterwards! if not timeout: # tuba - no_ack=True is also an option self.consumerTag = self.ch.basic_consume(self.queue, callback=self._callback) self.response = None self.correlationId = getUuid() # str(uuid.uuid4()) msg = amqp.Message( json.encode(data), content_type='text/json', correlation_id=self.correlationId, # reply_to = self.queue ) self.ch.basic_publish( msg, self.exchange, key, # reply_to = self.queue, # correlation_id = self.correlationId ) if not block: return log.notice('RPC-CALL: wait response') startTime = time.time() while self.response is None: if timeout: msg = self.ch.basic_get(self.queue) if msg: if self._callback(msg): break else: time.sleep(0.01) if (time.time() - startTime) >= timeout: raise TimeoutException( 'Waited %s sec for rpc call %s' % (timeout, key)) else: self.ch.wait() log.notice('RPC-CALL: finished waiting') try: body = json.decode(self.response.body) except Exception as e: raise Exception("json decoding error: %s - for raw response: %s" % (e, self.response.body)) tmp = self.response.routing_key.split('.') if tmp[0][1] == 'x': # todo: use constants if tmp[0][0] == 'o': d = 'orchestrator' # here too elif tmp[0][0] == 's': d = 'service' elif tmp[0][0] == 'r': d = 'reactor' elif tmp[0][0] == 'm': d = 'manager' e = RemoteException('Error in %s %s when calling %s' % (d, tmp[1], tmp[2])) e.setResponse(body) raise e log.debug('RPC-CALL: respone %s = %s' % (self.response.routing_key, body)) return body
continue except IOError, e: self.reconnect(e) continue except Exception, e: log.error('Caught during consumer.get() in listen: %s' % utils.e2str(e)) raise e try: self.consumer.ack() except Exception, e: log.error('Caught during consumer.ack() in listen: %s' % utils.e2str(e)) raise e if self._shutdown: log.info('Not handeling topic: %s because self._shutdown = True' % (topic,)) else: log.notice('Handeling topic: %s' % topic) tmp = topic.split('.') handle = False if tmp[0] == actionPrefix and len(tmp) > 1: pre, src, key = tmp if key == '_shutdown': continue if not data: data = [] try: result = self.runAction(key, data) except Exception, e: self.sendActionError(key, e, correlationId) else: if result != None or correlationId: self.sendActionResponse(key, result, correlationId)