presto源码分析(结果获取)

来源:互联网 发布:java开源软件开发平台 编辑:程序博客网 时间:2024/04/27 21:57

  • 结果获取入口

1.结果获取入口

结果获取的入口是在StatementResource中,客户端发送http请求,由getQueryResult方法响应,代码如下:

 @GET    @Path("{queryId}/{token}")    @Produces(MediaType.APPLICATION_JSON)    public Response getQueryResults(            @PathParam("queryId") QueryId queryId,            @PathParam("token") long token,            @QueryParam("maxWait") Duration maxWait,            @Context UriInfo uriInfo)            throws InterruptedException    {        Query query = queries.get(queryId);        if (query == null) {            return Response.status(Status.NOT_FOUND).build();        }        Duration wait = WAIT_ORDERING.min(MAX_WAIT_TIME, maxWait);        return getQueryResults(query, Optional.of(token), uriInfo, wait);//在该方法中获取到一个QueryResults对象,使用Response的ok方法构造一个ResponseBuilder对象,进行请求结果的返回    }

调用栈如下:
这里写图片描述

重点是StatementResource的getData方法,代码如下:

       private synchronized Iterable<List<Object>> getData(Duration maxWait)                throws InterruptedException        {            // wait for query to start            QueryInfo queryInfo = queryManager.getQueryInfo(queryId);            while (maxWait.toMillis() > 1 && !isQueryStarted(queryInfo)) {                queryManager.recordHeartbeat(queryId);                maxWait = queryManager.waitForStateChange(queryId, queryInfo.getState(), maxWait);                queryInfo = queryManager.getQueryInfo(queryId);            }            StageInfo outputStage = queryInfo.getOutputStage().orElse(null);            // if query did not finish starting or does not have output, just return            if (!isQueryStarted(queryInfo) || outputStage == null) {                return null;            }            if (columns == null) {                columns = createColumnsList(queryInfo);            }            List<Type> types = outputStage.getTypes();            updateExchangeClient(outputStage);            ImmutableList.Builder<RowIterable> pages = ImmutableList.builder();            // wait up to max wait for data to arrive; then try to return at least DESIRED_RESULT_BYTES            long bytes = 0;            while (bytes < DESIRED_RESULT_BYTES) {                Page page = exchangeClient.getNextPage(maxWait);//调用client获取下一个page数据                if (page == null) {                    break;                }                bytes += page.getSizeInBytes();                pages.add(new RowIterable(session.toConnectorSession(), types, page));                // only wait on first call                maxWait = new Duration(0, MILLISECONDS);            }            if (bytes == 0) {                return null;            }            return Iterables.concat(pages.build());        }

来看看exchangeClient是如何获取page数据的,代码如下,这部分代码还没有分析,需要好好分析一下:

 public Page getNextPage(Duration maxWaitTime)            throws InterruptedException    {        checkState(!Thread.holdsLock(this), "Can not get next page while holding a lock on this");        throwIfFailed();        if (closed.get()) {            return null;        }        scheduleRequestIfNecessary();        Page page = pageBuffer.poll();        // only wait for a page if we have remote clients        if (page == null && maxWaitTime.toMillis() >= 1 && !allClients.isEmpty()) {            page = pageBuffer.poll(maxWaitTime.toMillis(), TimeUnit.MILLISECONDS);        }        page = postProcessPage(page);        return page;    }
0 0
原创粉丝点击