Package org.asynchttpclient.providers.netty.request

Source Code of org.asynchttpclient.providers.netty.request.ProgressListener

/*
* Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at
*     http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package org.asynchttpclient.providers.netty.request;

import io.netty.channel.Channel;
import io.netty.channel.ChannelProgressiveFuture;
import io.netty.channel.ChannelProgressiveFutureListener;

import java.nio.channels.ClosedChannelException;

import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.ProgressAsyncHandler;
import org.asynchttpclient.Realm;
import org.asynchttpclient.providers.netty.channel.Channels;
import org.asynchttpclient.providers.netty.future.NettyResponseFuture;
import org.asynchttpclient.providers.netty.future.StackTraceInspector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ProgressListener implements ChannelProgressiveFutureListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProgressListener.class);

    private final AsyncHttpClientConfig config;
    private final AsyncHandler<?> asyncHandler;
    private final NettyResponseFuture<?> future;
    private final boolean notifyHeaders;
    private final long expectedTotal;
    private long lastProgress = 0L;

    public ProgressListener(AsyncHttpClientConfig config,//
            AsyncHandler<?> asyncHandler,//
            NettyResponseFuture<?> future,//
            boolean notifyHeaders,//
            long expectedTotal) {
        this.config = config;
        this.asyncHandler = asyncHandler;
        this.future = future;
        this.notifyHeaders = notifyHeaders;
        this.expectedTotal = expectedTotal;
    }

    private boolean abortOnThrowable(Throwable cause, Channel channel) {

        if (cause != null && future.getState() != NettyResponseFuture.STATE.NEW) {
            if (cause instanceof IllegalStateException) {
                LOGGER.debug(cause.getMessage(), cause);
                Channels.silentlyCloseChannel(channel);

            } else if (cause instanceof ClosedChannelException || StackTraceInspector.abortOnReadOrWriteException(cause)) {
                LOGGER.debug(cause.getMessage(), cause);
                Channels.silentlyCloseChannel(channel);
               
            } else {
                future.abort(cause);
            }
            return true;
        }

        return false;
    }

    @Override
    public void operationComplete(ChannelProgressiveFuture cf) {
        // The write operation failed. If the channel was cached, it means it got asynchronously closed.
        // Let's retry a second time.
        if (!abortOnThrowable(cf.cause(), cf.channel())) {

            future.touch();

            /**
             * We need to make sure we aren't in the middle of an authorization
             * process before publishing events as we will re-publish again the
             * same event after the authorization, causing unpredictable
             * behavior.
             */
            Realm realm = future.getRequest().getRealm() != null ? future.getRequest().getRealm() : config.getRealm();
            boolean startPublishing = future.isInAuth() || realm == null || realm.getUsePreemptiveAuth();

            if (startPublishing && asyncHandler instanceof ProgressAsyncHandler) {
                ProgressAsyncHandler<?> progressAsyncHandler = (ProgressAsyncHandler<?>) asyncHandler;
                if (notifyHeaders) {
                    progressAsyncHandler.onHeaderWriteCompleted();
                } else {
                    progressAsyncHandler.onContentWriteCompleted();
                }
            }
        }
    }

    @Override
    public void operationProgressed(ChannelProgressiveFuture f, long progress, long total) {
        future.touch();
        if (!notifyHeaders && asyncHandler instanceof ProgressAsyncHandler) {
            long lastLastProgress = lastProgress;
            lastProgress = progress;
            if (total < 0)
                total = expectedTotal;
            ProgressAsyncHandler.class.cast(asyncHandler).onContentWriteProgress(progress - lastLastProgress, progress, total);
        }
    }
}
TOP

Related Classes of org.asynchttpclient.providers.netty.request.ProgressListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.