예제 #1
0
    def test_worker_with_task_with_no_result_exeption(self):
        config = mock.Mock()

        exeption = DatabaseError("test exeption")

        task = mock.MagicMock()
        task.task_id = 123
        task.ack = mock.Mock(side_effect=exeption)

        input_tube = mock.MagicMock()
        input_tube.take = mock.Mock(return_value=task)

        output_tube = mock.MagicMock()

        parent_pid = 12345

        logger = mock.Mock()
        logger.exeption = mock.Mock()
        with mock.patch('source.lib.worker.get_tube',
                        mock.Mock(side_effect=[input_tube, output_tube])):
            with mock.patch('source.lib.worker.logger', logger):
                with mock.patch('os.path.exists',
                                mock.Mock(side_effect=[True, False])):
                    with mock.patch(
                            'source.lib.worker.get_redirect_history_from_task',
                            mock.Mock(return_value=None)):
                        worker.worker(config, parent_pid)
        logger.exception.assert_called_once_with(exeption)
        pass
예제 #2
0
    def __init__(self, conn, response):
        '''
        Create an instance of `Response` using data received from the server.

        __init__() itself reads data from the socket, parses response body and
        sets appropriate instance attributes.

        :param body: body of the response
        :type body: array of bytes
        '''

        # This is not necessary, because underlying list data structures are
        # created in the __new__().
        # super(Response, self).__init__()

        if msgpack.version >= (0, 5, 2) and conn.encoding == 'utf-8':
            # Get rid of the following warning.
            # > PendingDeprecationWarning: encoding is deprecated,
            # > Use raw=False instead.
            unpacker = msgpack.Unpacker(use_list=True, raw=False)
        elif conn.encoding is not None:
            unpacker = msgpack.Unpacker(use_list=True, encoding=conn.encoding)
        else:
            unpacker = msgpack.Unpacker(use_list=True)

        unpacker.feed(response)
        header = unpacker.unpack()

        self.conn = conn
        self._sync = header.get(IPROTO_SYNC, 0)
        self._code = header[IPROTO_CODE]
        self._body = {}
        self._schema_version = header.get(IPROTO_SCHEMA_ID, None)
        try:
            self._body = unpacker.unpack()
        except msgpack.OutOfData:
            pass

        if self._code < REQUEST_TYPE_ERROR:
            self._return_code = 0
            self._schema_version = header.get(IPROTO_SCHEMA_ID, None)
            self._data = self._body.get(IPROTO_DATA, None)
            if (not isinstance(self._data, (list, tuple))
                    and self._data is not None):
                self._data = [self._data]
            # # Backward-compatibility
            # if isinstance(self._data, (list, tuple)):
            #     self.extend(self._data)
            # else:
            #     self.append(self._data)
        else:
            # Separate return_code and completion_code
            self._return_message = self._body.get(IPROTO_ERROR, "")
            self._return_code = self._code & (REQUEST_TYPE_ERROR - 1)
            self._data = []
            if self._return_code == 109:
                raise SchemaReloadException(self._return_message,
                                            self._schema_version)
            if self.conn.error:
                raise DatabaseError(self._return_code, self._return_message)
예제 #3
0
    def __init__(self, conn, response):
        '''
        Create an instance of `Response` using data received from the server.

        __init__() itself reads data from the socket, parses response body and
        sets appropriate instance attributes.

        :param body: body of the response
        :type body: array of bytes
        '''

        # This is not necessary, because underlying list data structures are
        # created in the __new__(). But let it be.
        super(Response, self).__init__()

        if conn.encoding is not None:
            unpacker = msgpack.Unpacker(use_list=True, encoding=conn.encoding)
        else:
            unpacker = msgpack.Unpacker(use_list=True)

        unpacker.feed(response)
        header = unpacker.unpack()

        self._sync = header.get(IPROTO_SYNC, 0)
        self.conn = conn
        self._code = header[IPROTO_CODE]
        self._body = {}
        try:
            self._body = unpacker.unpack()
        except msgpack.OutOfData:
            pass

        if self._code < REQUEST_TYPE_ERROR:
            self._return_code = 0
            self._completion_status = 0
            self._data = self._body.get(IPROTO_DATA, None)
            # Backward-compatibility
            if isinstance(self._data, (list, tuple)):
                self.extend(self._data)
            else:
                self.append(self._data)
        else:
            # Separate return_code and completion_code
            self._return_message = self._body.get(IPROTO_ERROR, "")
            self._return_code = self._code & (REQUEST_TYPE_ERROR - 1)
            self._completion_status = 2
            self._data = None
            if self.conn.error:
                raise DatabaseError(self._return_code, self._return_message)
예제 #4
0
    def _response_reader(self):
        # handshake
        greeting = yield from self._reader.read(IPROTO_GREETING_SIZE)
        self._salt = base64.decodestring(greeting[64:])[:20]
        self._greeting_event.set()

        buf = b""
        while not self._reader.at_eof():
            tmp_buf = yield from self._reader.read(self.aiobuffer_size)
            if not tmp_buf:
                yield from self._do_close(
                    NetworkError(socket.error(errno.ECONNRESET, "Lost connection to server during query")))

            buf += tmp_buf
            len_buf = len(buf)
            curr = 0

            while len_buf - curr >= 5:
                length_pack = buf[curr:curr + 5]
                length = msgpack.unpackb(length_pack)

                if len_buf - curr < 5 + length:
                    break

                body = buf[curr + 5:curr + 5 + length]
                curr += 5 + length

                response = Response(self, body)  # unpack response

                sync = response.sync
                if sync not in self._waiters:
                    logger.error("aio git happens: {r}", response)
                    continue

                waiter = self._waiters[sync]
                if not waiter.cancelled():
                    if response.return_code != 0:
                        waiter.set_exception(DatabaseError(response.return_code, response.return_message))
                    else:
                        waiter.set_result(response)

                del self._waiters[sync]

            # one cut for buffer
            if curr:
                buf = buf[curr:]

        yield from self._do_close(None)
예제 #5
0
 def _send_request_no_check_connected(self, request):
     sync = request.sync
     for attempt in range(RETRY_MAX_ATTEMPTS):
         waiter = self._waiters[sync]
     
         # self._writer.write(bytes(request))
         self._write_buf += bytes(request)
         self._write_event.set()
     
         # read response
         response = yield from waiter
         if response.completion_status != 1:
             return response
     
         self._waiters[sync] = asyncio.Future(loop=self.loop)
         warn(response.return_message, RetryWarning)
 
     # Raise an error if the maximum number of attempts have been made
     raise DatabaseError(response.return_code, response.return_message)
예제 #6
0
    def _send_request_wo_reconnect(self, request):
        '''
        :rtype: `Response` instance

        :raise: NetworkError
        '''
        assert isinstance(request, Request)

        # Repeat request in a loop if the server returns completion_status == 1
        # (try again)
        for attempt in xrange(RETRY_MAX_ATTEMPTS):  # pylint: disable=W0612
            self._socket.sendall(bytes(request))
            response = Response(self, self._read_response())

            if response.completion_status != 1:
                return response
            warn(response.return_message, RetryWarning)

        # Raise an error if the maximum number of attempts have been made
        raise DatabaseError(response.return_code, response.return_message)
예제 #7
0
    def __init__(self, conn, response):
        '''
        Create an instance of `Response` using data received from the server.

        __init__() itself reads data from the socket, parses response body and
        sets appropriate instance attributes.

        :param body: body of the response
        :type body: array of bytes
        '''

        # This is not necessary, because underlying list data structures are
        # created in the __new__().
        # super(Response, self).__init__()

        unpacker_kwargs = dict()

        # Decode msgpack arrays into Python lists by default (not tuples).
        # Can be configured in the Connection init
        unpacker_kwargs['use_list'] = conn.use_list

        # Use raw=False instead of encoding='utf-8'.
        if msgpack.version >= (0, 5, 2) and conn.encoding == 'utf-8':
            # Get rid of the following warning.
            # > PendingDeprecationWarning: encoding is deprecated,
            # > Use raw=False instead.
            unpacker_kwargs['raw'] = False
        elif conn.encoding is not None:
            unpacker_kwargs['encoding'] = conn.encoding

        # raw=False is default since msgpack-1.0.0.
        #
        # The option decodes mp_str to bytes, not a Unicode
        # string (when True).
        if msgpack.version >= (1, 0, 0) and conn.encoding is None:
            unpacker_kwargs['raw'] = True

        # encoding option is not supported since msgpack-1.0.0,
        # but it is handled in the Connection constructor.
        assert(msgpack.version < (1, 0, 0) or conn.encoding in (None, 'utf-8'))

        # strict_map_key=True is default since msgpack-1.0.0.
        #
        # The option forbids non-string keys in a map (when True).
        if msgpack.version >= (1, 0, 0):
            unpacker_kwargs['strict_map_key'] = False

        unpacker = msgpack.Unpacker(**unpacker_kwargs)

        unpacker.feed(response)
        header = unpacker.unpack()

        self.conn = conn
        self._sync = header.get(IPROTO_SYNC, 0)
        self._code = header[IPROTO_CODE]
        self._body = {}
        self._schema_version = header.get(IPROTO_SCHEMA_ID, None)
        try:
            self._body = unpacker.unpack()
        except msgpack.OutOfData:
            pass

        if self._code < REQUEST_TYPE_ERROR:
            self._return_code = 0
            self._schema_version = header.get(IPROTO_SCHEMA_ID, None)
            self._data = self._body.get(IPROTO_DATA, None)
            if (not isinstance(self._data, (list, tuple)) and
                    self._data is not None):
                self._data = [self._data]
            # # Backward-compatibility
            # if isinstance(self._data, (list, tuple)):
            #     self.extend(self._data)
            # else:
            #     self.append(self._data)
        else:
            # Separate return_code and completion_code
            self._return_message = self._body.get(IPROTO_ERROR, "")
            self._return_code = self._code & (REQUEST_TYPE_ERROR - 1)
            self._data = []
            if self._return_code == 109:
                raise SchemaReloadException(self._return_message,
                                            self._schema_version)
            if self.conn.error:
                raise DatabaseError(self._return_code, self._return_message)
예제 #8
0
    async def _response_reader(self):
        # handshake
        greeting = await self._reader.read(IPROTO_GREETING_SIZE)
        self._salt = base64.decodestring(greeting[64:])[:20]
        self._greeting_event.set()

        buf = b""
        while not self._reader.at_eof():
            tmp_buf = await self._reader.read(self.aiobuffer_size)
            if not tmp_buf:
                await self._do_close(
                    NetworkError(
                        socket.error(errno.ECONNRESET,
                                     "Lost connection to server during query"))
                )

            buf += tmp_buf
            len_buf = len(buf)
            curr = 0

            while len_buf - curr >= 5:
                length_pack = buf[curr:curr + 5]
                length = msgpack.unpackb(length_pack)

                if len_buf - curr < 5 + length:
                    break

                body = buf[curr + 5:curr + 5 + length]
                curr += 5 + length
                try:
                    response = Response(self, body)  # unpack response
                except SchemaReloadException as exp:
                    if self.encoding is not None:
                        unpacker = msgpack.Unpacker(use_list=True,
                                                    encoding=self.encoding)
                    else:
                        unpacker = msgpack.Unpacker(use_list=True)

                    unpacker.feed(body)
                    header = unpacker.unpack()
                    sync = header.get(IPROTO_SYNC, 0)

                    waiter = self._waiters[sync]
                    if not waiter.cancelled():
                        waiter.set_exception(exp)

                    del self._waiters[sync]

                    self.schema.flush()
                    self.schema_version = exp.schema_version
                    continue

                sync = response.sync
                if sync not in self._waiters:
                    logger.error("aio git happens: {r}", response)
                    continue

                waiter = self._waiters[sync]
                if not waiter.cancelled():
                    if response.return_code != 0:
                        waiter.set_exception(
                            DatabaseError(response.return_code,
                                          response.return_message))
                    else:
                        waiter.set_result(response)

                del self._waiters[sync]

            # one cut for buffer
            if curr:
                buf = buf[curr:]

        await self._do_close(None)