Beispiel #1
0
 def set_path(self, path: str, value: JSONTYPES):
     # To improve performance, don't use set_jsonpath if the key is easily accessible using dotted path syntax (e.g. "path.to.my.key")
     is_dotted_path = True if re.match("^([\w]+[.]?)+$", path) else False
     if is_dotted_path:
         self._update_dict_by_path(self.dict, path, value)
     else:
         set_jsonpath(self.dict, path, value)
Beispiel #2
0
    def loop(self, client_socket: socket.socket, address: Tuple[str, str]):
        """Main ioloop for reranking server results to the client. Exceptions
        raised in the http parser must be reraised from __context__ because
        they are caught by the MagicStack implementation"""
        buffer = bytearray()
        server_socket = self.set_socket()
        request = {}
        response = {}

        try:
            self.server_connect(server_socket)

            with HttpParserContext():
                # receive and buffer the client request
                self.client_recv(client_socket, request, buffer)
                self.logger.debug('Request (%s:%s): search.', *address)

                # combine runtime configs and preset configs
                configs = {**self.config, **request['body'].get('nboost', {})}

                query, topk, true_cids = self.get_request_paths(
                    request, configs)

                # magnify the size of the request to the server
                new_topk = topk * configs['multiplier']
                set_jsonpath(request, configs['topk_path'], new_topk)

                # send the magnified request to the upstream server
                self.server_send(server_socket, request)
                self.server_recv(server_socket, response)

            if response['status'] < 300:
                choices, cids, cvalues = self.get_response_paths(
                    response, configs)

                self.record_topk_and_choices(topk=topk, choices=choices)

                # use the model to rerank the choices
                ranks = self.model_rank(query, cvalues)[:topk]
                reranked = [choices[rank] for rank in ranks]
                set_jsonpath(response, configs['choices_path'], reranked)

                # if the "nboost" param was sent, calculate MRRs
                if true_cids is not None:
                    self.calculate_mrrs(true_cids, cids, ranks)

                response['body']['nboost'] = {}

                if self.qa and len(cvalues) > 0:
                    answer, offsets, score = self.qa_model.get_answer(
                        query, cvalues[ranks.index(min(ranks))])
                    response['body']['nboost']['qa_model'] = answer
                    response['body']['nboost']['qa_model_offsets'] = offsets
                    response['body']['nboost']['qa_model_score'] = score

            self.client_send(request, response, client_socket)

        except FrontendRequest:
            self.logger.info('Request (%s:%s): frontend request', *address)
            self.frontend_send(client_socket, request)

        except StatusRequest:
            self.logger.info('Request (%s:%s): status request', *address)
            self.status_send(client_socket, request)

        except UnknownRequest:
            self.logger.info('Request (%s:%s): unknown path "%s"', *address,
                             request['url']['path'])
            self.proxy_send(client_socket, server_socket, buffer)
            self.proxy_recv(client_socket, server_socket)

        except MissingQuery:
            self.logger.warning('Request (%s:%s): missing query', *address)
            self.proxy_send(client_socket, server_socket, buffer)
            self.proxy_recv(client_socket, server_socket)

        except InvalidChoices as exc:
            self.logger.warning('Request (%s:%s): %s', *address, *exc.args)
            self.proxy_send(client_socket, server_socket, buffer)
            self.proxy_recv(client_socket, server_socket)

        except Exception as exc:
            # for misc errors, send back json error msg
            self.logger.error('Request (%s:%s): %s.',
                              *address,
                              exc,
                              exc_info=True)
            self.error_send(client_socket, exc)

        finally:
            client_socket.close()
            server_socket.close()
Beispiel #3
0
 def set_request_path(self, path: str, value):
     return set_jsonpath(self.request, path, value)
Beispiel #4
0
 def set_response_path(self, path: str, value):
     return set_jsonpath(self.response, path, value)
Beispiel #5
0
 def set_path(self, path: str, value: JSONTYPES):
     set_jsonpath(self.dict, path, value)