def _invoke(self, endpoint, args, coreFunction, doesReturn): ''' Publish or Call. Invokes targetFunction for the given endpoint and handler. :param coreFunction: the intended core function, either Subscribe or Register :param doesReturn: True if this handler can receive results (is a call) ''' d = Deferred() d.canReturn = doesReturn d.mantleDomain = self.mantleDomain self.app.deferreds[d.cb], self.app.deferreds[d.eb] = d, d coreFunction(endpoint, d.cb, d.eb, cumin.marshall(args)) return d
def handle(self, domain): ''' Open connection with the core and begin handling callbacks ''' while True: i, args = json.loads(domain.Receive()) args = [] if args is None else args # When the channel that feeds the Receive function closes, 0 is returned # This is currently automagic and happened to work on accident, but consider # a more explicit close if i == 0: break if i in self.deferreds: d = self.deferreds[i] del self.deferreds[d.cb] del self.deferreds[d.eb] # Special Python case-- if this is an errback construct an excepction if i == d.eb: args = utils.Error(*args) # Deferreds are always emitted by async methods. If the user called .wait() # then the deferred instantiates a greenlet as .green. Resume that greenlet. # If that greenlet emits another deferred the user has called .wait() again. if d.green is not None: d = d.green.switch(args) if d is not None: self.deferreds[d.cb], self.deferreds[d.eb] = d, d elif i in self.handlers: handler, canReturn = self.handlers[i] if canReturn: resultID = args.pop(0) # Consolidated handlers into one try: ret = handler(*args) except Exception as error: # TODO: Differentiate Riffle errors vs. other exceptions, # maybe reraise other exceptions. if canReturn: domain.YieldError(resultID, "wamp.error.runtime_error", json.dumps([str(error)])) else: print "An exception occured: ", error else: if canReturn: if ret is None: ret = [] elif isinstance(ret, tuple): ret = list(ret) else: ret = [ret] domain.Yield(resultID, cumin.marshall(ret)) # Control messages. These should really just be deferreds, but not implemented yet if i in self.control: d = greenlet(self.control[i]).switch(*args) # If user code called .wait(), this deferred is emitted, waiting on the results of some operation if d is not None: self.deferreds[d.cb], self.deferreds[d.eb] = d, d