Search in sources :

Example 1 with BaseResponse

use of com.facebook.presto.server.smile.BaseResponse in project presto by prestodb.

the class RemoteNodeMemory method asyncRefresh.

public void asyncRefresh(MemoryPoolAssignmentsRequest assignments) {
    Duration sinceUpdate = nanosSince(lastUpdateNanos.get());
    if (nanosSince(lastWarningLogged.get()).toMillis() > 1_000 && sinceUpdate.toMillis() > 10_000 && future.get() != null) {
        log.warn("Memory info update request to %s has not returned in %s", memoryInfoUri, sinceUpdate.toString(SECONDS));
        lastWarningLogged.set(System.nanoTime());
    }
    if (sinceUpdate.toMillis() > 1_000 && future.get() == null) {
        Request request = setContentTypeHeaders(isBinaryTransportEnabled, preparePost()).setUri(memoryInfoUri).setBodyGenerator(createBodyGenerator(assignments)).build();
        ResponseHandler responseHandler;
        if (isBinaryTransportEnabled) {
            responseHandler = createFullSmileResponseHandler((SmileCodec<MemoryInfo>) memoryInfoCodec);
        } else {
            responseHandler = createAdaptingJsonResponseHandler((JsonCodec<MemoryInfo>) memoryInfoCodec);
        }
        HttpResponseFuture<BaseResponse<MemoryInfo>> responseFuture = httpClient.executeAsync(request, responseHandler);
        future.compareAndSet(null, responseFuture);
        Futures.addCallback(responseFuture, new FutureCallback<BaseResponse<MemoryInfo>>() {

            @Override
            public void onSuccess(@Nullable BaseResponse<MemoryInfo> result) {
                lastUpdateNanos.set(System.nanoTime());
                future.compareAndSet(responseFuture, null);
                long version = currentAssignmentVersion.get();
                if (result != null) {
                    if (result.hasValue()) {
                        memoryInfo.set(Optional.ofNullable(result.getValue()));
                    }
                    if (result.getStatusCode() != OK.code()) {
                        log.warn("Error fetching memory info from %s returned status %d: %s", memoryInfoUri, result.getStatusCode(), result.getStatusMessage());
                        return;
                    }
                }
                currentAssignmentVersion.compareAndSet(version, assignments.getVersion());
            }

            @Override
            public void onFailure(Throwable t) {
                log.warn("Error fetching memory info from %s: %s", memoryInfoUri, t.getMessage());
                lastUpdateNanos.set(System.nanoTime());
                future.compareAndSet(responseFuture, null);
            }
        }, directExecutor());
    }
}
Also used : BaseResponse(com.facebook.presto.server.smile.BaseResponse) SmileCodec(com.facebook.airlift.json.smile.SmileCodec) JsonCodec(com.facebook.airlift.json.JsonCodec) FullSmileResponseHandler.createFullSmileResponseHandler(com.facebook.presto.server.smile.FullSmileResponseHandler.createFullSmileResponseHandler) ResponseHandler(com.facebook.airlift.http.client.ResponseHandler) AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler(com.facebook.presto.server.smile.AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler) Request(com.facebook.airlift.http.client.Request) Duration(io.airlift.units.Duration)

Example 2 with BaseResponse

use of com.facebook.presto.server.smile.BaseResponse in project presto by prestodb.

the class HttpRemoteTask method sendUpdate.

private synchronized void sendUpdate() {
    TaskStatus taskStatus = getTaskStatus();
    // don't update if the task hasn't been started yet or if it is already finished
    if (!started.get() || !needsUpdate.get() || taskStatus.getState().isDone()) {
        return;
    }
    // if there is a request already running, wait for it to complete
    if (this.currentRequest != null && !this.currentRequest.isDone()) {
        return;
    }
    // if throttled due to error, asynchronously wait for timeout and try again
    ListenableFuture<?> errorRateLimit = updateErrorTracker.acquireRequestPermit();
    if (!errorRateLimit.isDone()) {
        errorRateLimit.addListener(this::sendUpdate, executor);
        return;
    }
    List<TaskSource> sources = getSources();
    Optional<byte[]> fragment = sendPlan.get() ? Optional.of(planFragment.toBytes(planFragmentCodec)) : Optional.empty();
    Optional<TableWriteInfo> writeInfo = sendPlan.get() ? Optional.of(tableWriteInfo) : Optional.empty();
    TaskUpdateRequest updateRequest = new TaskUpdateRequest(session.toSessionRepresentation(), session.getIdentity().getExtraCredentials(), fragment, sources, outputBuffers.get(), writeInfo);
    byte[] taskUpdateRequestJson = taskUpdateRequestCodec.toBytes(updateRequest);
    taskUpdateRequestSize.add(taskUpdateRequestJson.length);
    if (taskUpdateRequestJson.length > maxTaskUpdateSizeInBytes) {
        failTask(new PrestoException(EXCEEDED_TASK_UPDATE_SIZE_LIMIT, format("TaskUpdate size of %d Bytes has exceeded the limit of %d Bytes", taskUpdateRequestJson.length, maxTaskUpdateSizeInBytes)));
    }
    if (fragment.isPresent()) {
        stats.updateWithPlanSize(taskUpdateRequestJson.length);
    } else {
        if (ThreadLocalRandom.current().nextDouble() < UPDATE_WITHOUT_PLAN_STATS_SAMPLE_RATE) {
            // This is to keep track of the task update size even when the plan fragment is NOT present
            stats.updateWithoutPlanSize(taskUpdateRequestJson.length);
        }
    }
    HttpUriBuilder uriBuilder = getHttpUriBuilder(taskStatus);
    Request request = setContentTypeHeaders(binaryTransportEnabled, preparePost()).setUri(uriBuilder.build()).setBodyGenerator(createStaticBodyGenerator(taskUpdateRequestJson)).build();
    ResponseHandler responseHandler;
    if (binaryTransportEnabled) {
        responseHandler = createFullSmileResponseHandler((SmileCodec<TaskInfo>) taskInfoCodec);
    } else {
        responseHandler = createAdaptingJsonResponseHandler((JsonCodec<TaskInfo>) taskInfoCodec);
    }
    updateErrorTracker.startRequest();
    ListenableFuture<BaseResponse<TaskInfo>> future = httpClient.executeAsync(request, responseHandler);
    currentRequest = future;
    currentRequestStartNanos = System.nanoTime();
    // The needsUpdate flag needs to be set to false BEFORE adding the Future callback since callback might change the flag value
    // and does so without grabbing the instance lock.
    needsUpdate.set(false);
    Futures.addCallback(future, new SimpleHttpResponseHandler<>(new UpdateResponseHandler(sources), request.getUri(), stats.getHttpResponseStats(), REMOTE_TASK_ERROR), executor);
}
Also used : SmileCodec(com.facebook.airlift.json.smile.SmileCodec) TableWriteInfo(com.facebook.presto.execution.scheduler.TableWriteInfo) SimpleHttpResponseHandler(com.facebook.presto.server.SimpleHttpResponseHandler) StatusResponseHandler.createStatusResponseHandler(com.facebook.airlift.http.client.StatusResponseHandler.createStatusResponseHandler) FullSmileResponseHandler.createFullSmileResponseHandler(com.facebook.presto.server.smile.FullSmileResponseHandler.createFullSmileResponseHandler) ResponseHandler(com.facebook.airlift.http.client.ResponseHandler) AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler(com.facebook.presto.server.smile.AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler) TaskUpdateRequest(com.facebook.presto.server.TaskUpdateRequest) TaskUpdateRequest(com.facebook.presto.server.TaskUpdateRequest) Request(com.facebook.airlift.http.client.Request) PrestoException(com.facebook.presto.spi.PrestoException) TaskStatus(com.facebook.presto.execution.TaskStatus) BaseResponse(com.facebook.presto.server.smile.BaseResponse) JsonCodec(com.facebook.airlift.json.JsonCodec) HttpUriBuilder(com.facebook.airlift.http.client.HttpUriBuilder) TaskSource(com.facebook.presto.execution.TaskSource)

Example 3 with BaseResponse

use of com.facebook.presto.server.smile.BaseResponse in project presto by prestodb.

the class HttpRemoteTask method doScheduleAsyncCleanupRequest.

private void doScheduleAsyncCleanupRequest(Backoff cleanupBackoff, Request request, String action) {
    ResponseHandler responseHandler;
    if (binaryTransportEnabled) {
        responseHandler = createFullSmileResponseHandler((SmileCodec<TaskInfo>) taskInfoCodec);
    } else {
        responseHandler = createAdaptingJsonResponseHandler((JsonCodec<TaskInfo>) taskInfoCodec);
    }
    Futures.addCallback(httpClient.executeAsync(request, responseHandler), new FutureCallback<BaseResponse<TaskInfo>>() {

        @Override
        public void onSuccess(BaseResponse<TaskInfo> result) {
            try {
                updateTaskInfo(result.getValue());
            } finally {
                if (!getTaskInfo().getTaskStatus().getState().isDone()) {
                    cleanUpLocally();
                }
            }
        }

        @Override
        public void onFailure(Throwable t) {
            if (t instanceof RejectedExecutionException && httpClient.isClosed()) {
                logError(t, "Unable to %s task at %s. HTTP client is closed.", action, request.getUri());
                cleanUpLocally();
                return;
            }
            // record failure
            if (cleanupBackoff.failure()) {
                logError(t, "Unable to %s task at %s. Back off depleted.", action, request.getUri());
                cleanUpLocally();
                return;
            }
            // reschedule
            long delayNanos = cleanupBackoff.getBackoffDelayNanos();
            if (delayNanos == 0) {
                doScheduleAsyncCleanupRequest(cleanupBackoff, request, action);
            } else {
                errorScheduledExecutor.schedule(() -> doScheduleAsyncCleanupRequest(cleanupBackoff, request, action), delayNanos, NANOSECONDS);
            }
        }

        private void cleanUpLocally() {
            // Update the taskInfo with the new taskStatus.
            // Generally, we send a cleanup request to the worker, and update the TaskInfo on
            // the coordinator based on what we fetched from the worker. If we somehow cannot
            // get the cleanup request to the worker, the TaskInfo that we fetch for the worker
            // likely will not say the task is done however many times we try. In this case,
            // we have to set the local query info directly so that we stop trying to fetch
            // updated TaskInfo from the worker. This way, the task on the worker eventually
            // expires due to lack of activity.
            // This is required because the query state machine depends on TaskInfo (instead of task status)
            // to transition its own state.
            // TODO: Update the query state machine and stage state machine to depend on TaskStatus instead
            // Since this TaskInfo is updated in the client the "complete" flag will not be set,
            // indicating that the stats may not reflect the final stats on the worker.
            updateTaskInfo(getTaskInfo().withTaskStatus(getTaskStatus()));
        }
    }, executor);
}
Also used : TaskInfo(com.facebook.presto.execution.TaskInfo) BaseResponse(com.facebook.presto.server.smile.BaseResponse) SmileCodec(com.facebook.airlift.json.smile.SmileCodec) JsonCodec(com.facebook.airlift.json.JsonCodec) SimpleHttpResponseHandler(com.facebook.presto.server.SimpleHttpResponseHandler) StatusResponseHandler.createStatusResponseHandler(com.facebook.airlift.http.client.StatusResponseHandler.createStatusResponseHandler) FullSmileResponseHandler.createFullSmileResponseHandler(com.facebook.presto.server.smile.FullSmileResponseHandler.createFullSmileResponseHandler) ResponseHandler(com.facebook.airlift.http.client.ResponseHandler) AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler(com.facebook.presto.server.smile.AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Aggregations

ResponseHandler (com.facebook.airlift.http.client.ResponseHandler)3 JsonCodec (com.facebook.airlift.json.JsonCodec)3 SmileCodec (com.facebook.airlift.json.smile.SmileCodec)3 AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler (com.facebook.presto.server.smile.AdaptingJsonResponseHandler.createAdaptingJsonResponseHandler)3 BaseResponse (com.facebook.presto.server.smile.BaseResponse)3 FullSmileResponseHandler.createFullSmileResponseHandler (com.facebook.presto.server.smile.FullSmileResponseHandler.createFullSmileResponseHandler)3 Request (com.facebook.airlift.http.client.Request)2 StatusResponseHandler.createStatusResponseHandler (com.facebook.airlift.http.client.StatusResponseHandler.createStatusResponseHandler)2 SimpleHttpResponseHandler (com.facebook.presto.server.SimpleHttpResponseHandler)2 HttpUriBuilder (com.facebook.airlift.http.client.HttpUriBuilder)1 TaskInfo (com.facebook.presto.execution.TaskInfo)1 TaskSource (com.facebook.presto.execution.TaskSource)1 TaskStatus (com.facebook.presto.execution.TaskStatus)1 TableWriteInfo (com.facebook.presto.execution.scheduler.TableWriteInfo)1 TaskUpdateRequest (com.facebook.presto.server.TaskUpdateRequest)1 PrestoException (com.facebook.presto.spi.PrestoException)1 Duration (io.airlift.units.Duration)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1