Beispiel #1
0
 def testUnmaskedDataFrame(self):
     parser = FrameParser(kind=2)
     f = parser.encode('Hello')
     self.assertEqual(f.opcode, 0x1)
     self.assertEqual(f.payload_length, 5)
     self.assertFalse(f.masked)
     self.assertEqual(len(f.msg), 7)
     self.assertEqual(int2bytes(0x81,0x05,0x48,0x65,0x6c,0x6c,0x6f), f.msg)
     f1 = parser.encode('Hel', final=False)
     f2 = parser.continuation('lo', final=True)
     self.assertEqual(int2bytes(0x01,0x03,0x48,0x65,0x6c), f1.msg)
     self.assertEqual(int2bytes(0x80,0x02,0x6c,0x6f), f2.msg)
Beispiel #2
0
 def testUnmaskedDataFrame(self):
     parser = FrameParser(kind=2)
     f = parser.encode('Hello')
     self.assertEqual(f.opcode, 0x1)
     self.assertEqual(f.payload_length, 5)
     self.assertFalse(f.masked)
     self.assertEqual(len(f.msg), 7)
     self.assertEqual(int2bytes(0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f),
                      f.msg)
     f1 = parser.encode('Hel', final=False)
     f2 = parser.continuation('lo', final=True)
     self.assertEqual(int2bytes(0x01, 0x03, 0x48, 0x65, 0x6c), f1.msg)
     self.assertEqual(int2bytes(0x80, 0x02, 0x6c, 0x6f), f2.msg)
Beispiel #3
0
class MailboxConsumer(ProtocolConsumer):
    '''The :class:`pulsar.ProtocolConsumer` for internal message passing
between actors. Encoding and decoding uses the unmasked websocket
protocol.'''
    def connection_made(self, connection):
        self._pending_responses = {}
        self._parser = FrameParser(kind=2)
        actor = get_actor()
        if actor.is_arbiter():
            self.connection.bind_event('connection_lost', None,
                                       self._connection_lost)

    def request(self, command, sender, target, args, kwargs):
        '''Used by the server to send messages to the client.'''
        req = Message.command(command, sender, target, args, kwargs)
        self.start_request(req)
        return req.future

    #######################################################################
    ##    PROTOCOL CONSUMER IMPLEMENTATION
    def data_received(self, data):
        # Feed data into the parser
        msg = self._parser.decode(data)
        while msg:
            try:
                message = pickle.loads(msg.body)
            except Exception as e:
                raise ProtocolError('Could not decode message body: %s' % e)
            maybe_async(self._responde(message), event_loop=self.event_loop)
            msg = self._parser.decode()

    def start_request(self, req=None):
        if req:
            if req.future and 'ack' in req.data:
                self._pending_responses[req.data['ack']] = req.future
                try:
                    self._write(req)
                except Exception as e:
                    req.future.callback(e)
            else:
                self._write(req)
    start = start_request

    ########################################################################
    ##    INTERNALS
    def _connection_lost(self, failure):
        actor = get_actor()
        if actor.is_running():
            failure.log(msg='Connection lost with actor.', level='warning')
        else:
            failure.mute()
        return failure

    def _responde(self, message):
        actor = get_actor()
        command = message.get('command')
        #actor.logger.debug('handling %s', command)
        if command == 'callback':
            # this is a callback
            self._callback(message.get('ack'), message.get('result'))
        else:
            try:
                target = actor.get_actor(message['target'])
                if target is None:
                    raise CommandError('Cannot execute "%s" in %s. Unknown '
                                       'actor %s' % (command, actor,
                                                     message['target']))
                # Get the caller proxy without throwing
                caller = get_proxy(actor.get_actor(message['sender']),
                                   safe=True)
                if isinstance(target, ActorProxy):
                    # route the message to the actor proxy
                    if caller is None:
                        raise CommandError(
                            "'%s' got message from unknown '%s'"
                            % (actor, message['sender']))
                    result = yield actor.send(target, command,
                                              *message['args'],
                                              **message['kwargs'])
                else:
                    actor = target
                    command = get_command(command)
                    req = CommandRequest(target, caller, self.connection)
                    result = yield command(req, message['args'],
                                           message['kwargs'])
            except Exception:
                result = Failure(sys.exc_info())
            if message.get('ack'):
                req = Message.callback(result, message['ack'])
                self.start_request(req)

    def _callback(self, ack, result):
        if not ack:
            raise ProtocolError('A callback without id')
        try:
            pending = self._pending_responses.pop(ack)
        except KeyError:
            raise KeyError('Callback %s not in pending callbacks' % ack)
        pending.callback(result)

    def _write(self, req):
        obj = pickle.dumps(req.data, protocol=2)
        data = self._parser.encode(obj, opcode=0x2).msg
        try:
            self.transport.write(data)
        except IOError:
            actor = get_actor()
            if actor.is_running():
                raise