最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

AsyncHttpClient IOExceptionFilter異常過濾器

 更新時(shí)間:2023年12月13日 09:34:57   作者:codecraft  
這篇文章主要為大家介紹了AsyncHttpClient IOExceptionFilter異常過濾器代碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下AsyncHttpClient的IOExceptionFilter

IOExceptionFilter

org/asynchttpclient/filter/IOExceptionFilter.java

/**
 * This filter is invoked when an {@link java.io.IOException} occurs during an http transaction.
 */
public interface IOExceptionFilter {
  /**
   * An {@link org.asynchttpclient.AsyncHttpClient} will invoke {@link IOExceptionFilter#filter} and will
   * use the returned {@link FilterContext} to replay the {@link org.asynchttpclient.Request} or abort the processing.
   *
   * @param ctx a {@link FilterContext}
   * @param <T> the handler result type
   * @return {@link FilterContext}. The {@link FilterContext} instance may not the same as the original one.
   * @throws FilterException to interrupt the filter processing.
   */
  <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException;
}
IOExceptionFilter接口定義了filter方法,在捕獲到IOException的時(shí)候執(zhí)行

ResumableIOExceptionFilter

org/asynchttpclient/handler/resumable/ResumableIOExceptionFilter.java

/**
 * Simple {@link org.asynchttpclient.filter.IOExceptionFilter} that replay the current {@link org.asynchttpclient.Request} using a {@link ResumableAsyncHandler}
 */
public class ResumableIOExceptionFilter implements IOExceptionFilter {
  public <T> FilterContext<T> filter(FilterContext<T> ctx) {
    if (ctx.getIOException() != null && ctx.getAsyncHandler() instanceof ResumableAsyncHandler) {

      Request request = ResumableAsyncHandler.class.cast(ctx.getAsyncHandler()).adjustRequestRange(ctx.getRequest());

      return new FilterContext.FilterContextBuilder<>(ctx).request(request).replayRequest(true).build();
    }
    return ctx;
  }
}
ResumableIOExceptionFilter實(shí)現(xiàn)了IOExceptionFilter接口,它在asyncHandler是ResumableAsyncHandler類型的時(shí)候執(zhí)行adjustRequestRange方法獲取新的request,然后再通過new FilterContext.FilterContextBuilder<>(ctx).request(request).replayRequest(true).build()返回

ResumableAsyncHandler

org/asynchttpclient/handler/resumable/ResumableAsyncHandler.java

/**
   * Invoke this API if you want to set the Range header on your {@link Request} based on the last valid bytes
   * position.
   *
   * @param request {@link Request}
   * @return a {@link Request} with the Range header properly set.
   */
  public Request adjustRequestRange(Request request) {
    Long ri = resumableIndex.get(request.getUrl());
    if (ri != null) {
      byteTransferred.set(ri);
    }
    // The Resumable
    if (resumableListener != null && resumableListener.length() > 0 && byteTransferred.get() != resumableListener.length()) {
      byteTransferred.set(resumableListener.length());
    }
    RequestBuilder builder = new RequestBuilder(request);
    if (request.getHeaders().get(RANGE) == null && byteTransferred.get() != 0) {
      builder.setHeader(RANGE, "bytes=" + byteTransferred.get() + "-");
    }
    return builder.build();
  }
adjustRequestRange方法在byteTransferred不等于resumableListener.length()的時(shí)候會(huì)重置byteTransferred,對(duì)于有range的header則重置其bytes參數(shù)值

ResponseFiltersInterceptor

org/asynchttpclient/netty/handler/intercept/ResponseFiltersInterceptor.java

public boolean exitAfterProcessingFilters(Channel channel,
                                            NettyResponseFuture<?> future,
                                            AsyncHandler<?> handler,
                                            HttpResponseStatus status,
                                            HttpHeaders responseHeaders) {
    FilterContext fc = new FilterContext.FilterContextBuilder().asyncHandler(handler).request(future.getCurrentRequest()).responseStatus(status)
            .responseHeaders(responseHeaders).build();
    for (ResponseFilter asyncFilter : config.getResponseFilters()) {
      try {
        fc = asyncFilter.filter(fc);
        // FIXME Is it worth protecting against this?
        assertNotNull("fc", "filterContext");
      } catch (FilterException efe) {
        requestSender.abort(channel, future, efe);
      }
    }
    // The handler may have been wrapped.
    future.setAsyncHandler(fc.getAsyncHandler());
    // The request has changed
    if (fc.replayRequest()) {
      requestSender.replayRequest(future, fc, channel);
      return true;
    }
    return false;
  }
ResponseFiltersInterceptor的exitAfterProcessingFilters方法,對(duì)于fc.replayRequest()為true則執(zhí)行requestSender.replayRequest(future, fc, channel)

replayRequest

org/asynchttpclient/netty/request/NettyRequestSender.java

public void replayRequest(final NettyResponseFuture<?> future, FilterContext fc, Channel channel) {

    Request newRequest = fc.getRequest();
    future.setAsyncHandler(fc.getAsyncHandler());
    future.setChannelState(ChannelState.NEW);
    future.touch();

    LOGGER.debug("\n\nReplaying Request {}\n for Future {}\n", newRequest, future);
    try {
      future.getAsyncHandler().onRetry();
    } catch (Exception e) {
      LOGGER.error("onRetry crashed", e);
      abort(channel, future, e);
      return;
    }

    channelManager.drainChannelAndOffer(channel, future);
    sendNextRequest(newRequest, future);
  }
NettyRequestSender的replayRequest方法會(huì)觸發(fā)future.getAsyncHandler().onRetry()回調(diào),然后執(zhí)行channelManager.drainChannelAndOffer(channel, future)及sendNextRequest

applyIoExceptionFiltersAndReplayRequest

org/asynchttpclient/netty/request/NettyRequestSender.java

public boolean applyIoExceptionFiltersAndReplayRequest(NettyResponseFuture<?> future, IOException e,
                                                         Channel channel) {
    boolean replayed = false;
    @SuppressWarnings({"unchecked", "rawtypes"})
    FilterContext<?> fc = new FilterContext.FilterContextBuilder().asyncHandler(future.getAsyncHandler())
            .request(future.getCurrentRequest()).ioException(e).build();
    for (IOExceptionFilter asyncFilter : config.getIoExceptionFilters()) {
      try {
        fc = asyncFilter.filter(fc);
        assertNotNull(fc, "filterContext");
      } catch (FilterException efe) {
        abort(channel, future, efe);
      }
    }
    if (fc.replayRequest() && future.incrementRetryAndCheck() && future.isReplayPossible()) {
      future.setKeepAlive(false);
      replayRequest(future, fc, channel);
      replayed = true;
    }
    return replayed;
  }
NettyRequestSender的applyIoExceptionFiltersAndReplayRequest方法會(huì)遍歷config.getIoExceptionFilters(),然后挨個(gè)執(zhí)行fc = asyncFilter.filter(fc)

小結(jié)

AsyncHttpClient的IOExceptionFilter接口定義了filter方法,在捕獲到IOException的時(shí)候執(zhí)行;

ResumableIOExceptionFilter實(shí)現(xiàn)了IOExceptionFilter接口,它在asyncHandler是ResumableAsyncHandler類型的時(shí)候執(zhí)行adjustRequestRange方法獲取新的request,然后再通過new FilterContext.FilterContextBuilder<>(ctx).request(request).replayRequest(true).build()返回;

NettyRequestSender的replayRequest方法會(huì)觸發(fā)future.getAsyncHandler().onRetry()回調(diào),然后執(zhí)行channelManager.drainChannelAndOffer(channel, future)及sendNextRequest。

以上就是AsyncHttpClient IOExceptionFilter異常過濾器的詳細(xì)內(nèi)容,更多關(guān)于AsyncHttpClient IOExceptionFilter的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot中使用Filter實(shí)現(xiàn)Header認(rèn)證詳解

    Springboot中使用Filter實(shí)現(xiàn)Header認(rèn)證詳解

    這篇文章主要介紹了Springboot中使用Filter實(shí)現(xiàn)Header認(rèn)證詳解,當(dāng)在?web.xml?注冊(cè)了一個(gè)?Filter?來對(duì)某個(gè)?Servlet?程序進(jìn)行攔截處理時(shí),它可以決定是否將請(qǐng)求繼續(xù)傳遞給?Servlet?程序,以及對(duì)請(qǐng)求和響應(yīng)消息是否進(jìn)行修改,需要的朋友可以參考下
    2023-08-08
  • jar命令的用法詳解

    jar命令的用法詳解

    這篇文章主要介紹了jar命令的用法,非常實(shí)用,需要的朋友可以參考下
    2014-08-08
  • 關(guān)于分布式鎖(Redisson)的原理分析

    關(guān)于分布式鎖(Redisson)的原理分析

    這篇文章主要介紹了關(guān)于分布式鎖(Redisson)的原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 詳解Spring中singleton?bean如何同時(shí)服務(wù)多個(gè)請(qǐng)求

    詳解Spring中singleton?bean如何同時(shí)服務(wù)多個(gè)請(qǐng)求

    這篇文章主要介紹了詳解Spring中singleton?bean如何同時(shí)服務(wù)多個(gè)請(qǐng)求
    2023-02-02
  • java實(shí)現(xiàn)2048小游戲

    java實(shí)現(xiàn)2048小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)2048小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • Java多線程Callable和Future接口區(qū)別

    Java多線程Callable和Future接口區(qū)別

    這篇文章主要介紹了Java多線程Callable和Future接口區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)

    深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)

    這篇文章主要介紹了Jdk8中Stream流的使用,讓你脫離for循環(huán),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • EasyExcel工具讀取Excel空數(shù)據(jù)行問題的解決辦法

    EasyExcel工具讀取Excel空數(shù)據(jù)行問題的解決辦法

    EasyExcel是阿里巴巴開源的一個(gè)excel處理框架,以使用簡(jiǎn)單,節(jié)省內(nèi)存著稱,下面這篇文章主要給大家介紹了關(guān)于EasyExcel工具讀取Excel空數(shù)據(jù)行問題的解決辦法,需要的朋友可以參考下
    2022-08-08
  • java異步編程CompletableFuture使用示例詳解

    java異步編程CompletableFuture使用示例詳解

    這篇文章主要為大家介紹了java異步編程CompletableFuture使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • MyBatis入門學(xué)習(xí)教程(一)-MyBatis快速入門

    MyBatis入門學(xué)習(xí)教程(一)-MyBatis快速入門

    MyBatis是一個(gè)支持普通SQL查詢,存儲(chǔ)過程和高級(jí)映射的優(yōu)秀持久層框架,這篇文章主要給大家分享MyBatis入門學(xué)習(xí)教程(一)-MyBatis快速入門,需要的朋友可以參考下
    2015-08-08

最新評(píng)論

鄂州市| 富民县| 陇川县| 竹山县| 丹巴县| 秦皇岛市| 宜君县| 平武县| 筠连县| 霞浦县| 固镇县| 江华| 黎城县| 景宁| 肇源县| 阳西县| 巴南区| 腾冲县| 咸宁市| 长治县| 池州市| 营山县| 新乡县| 高唐县| 威远县| 财经| 泽州县| 博兴县| 宝坻区| 汉源县| 南部县| 饶河县| 天门市| 阜新| 保定市| 萨迦县| 茶陵县| 丰城市| 富裕县| 开封市| 平果县|