netty系列(五)IdleStateHandler和IdleStateHandlerEventState

笔记:IdleStateHandler是netty自带的,而idleStateHandlerEventState是我们自己实现的一个inboundHandler,任何一个实现了userTriggerEvent事件的InBound都可以接收和处理IdleStateHandler事件。

简单概括IdleStateHandler的流程:很简单,就是ctx包含了channel对应的eventloop,所以在IdleStateHandler就是在handlerAdded事件或者channelActive事件中往channel对应的eventloop中丢几个scheduledTask即定时任务,当定时任务运行的时候一旦检测到超时时间,就通过ctx.fireUserEventTrigger函数往pipeline丢一个UserEventTrigger事件。这个定时任务的检测也比较简单:对于读超时,idleStateHandler初始化时记录一次状态,然后运行时会在channelRead函数中记录一个原子变量ReadIng表示当前正在读,然后在ChannelReadComplete中记录一个变量:lastReadTime表示最后一次读操作完成的时间,然后定时任务就是检测当前时间-lastReadTime是否超过了阈值,如果超过了就通过fireUserEventTrigger往pipeline丢一个userEventTrigger事件。对于写超时,也是一样的流程,只不过略有区别:读操作是有一个专门的读完成事件即ChannelReadComplete,但是写没有,因为写是异步的,所以他会返回一个promise而promise可以添加Listener即监听operatorComplete事件,在责怪listener里面就可以设置当前的事件为lastWriteTime,然后写超时定时任务执行的时候就会检测是否超时了,如果超时就会发送超时事件(即userEventTrigger)到pipeline。因为不管是读还是写还是all,超时任务运行一次就结束了,所以运行结束之前还要再往scheduledTaskQueue里面塞下一个超时任务,

换个方式解释下:

每个channel都对应一条流水线,不同的channel使用不同的流水线(即channel继承了AbstractChannel基类,然后AbstractChannel内部含有一个pipeline变量,所以每创建一个channel,都会创建pipeline对象,即),也就是说不同的channel使用不同的idlestatehandler,每个channel都含有一个ctx,每个channel建立的时候都会调用一遍IdleStateHandler的handleAdded方法,handleAdded方法中又调用了initialize方法,然后initialize方法就会针对这个channel创建一个定时任务,这个定时任务包含了这个channel对应的ctx对象,然后把这个定时任务丢到idleHandler的异步线程去,这样这个异步线程一旦检查到超时事件,就会fireUserEvent到流水线

代码流程:

直接从handlerAdded或者channelActive开始。如果handlerAdded时channel还没准备好,那么就在channelActive事件中处理

broker 复制代码
1:channelReadComplete事件
IdleStateHandler.handlerAdded                #第一步是向eventLoop添加定时任务
  IdleStateHandler.initialize                #添加任务到eventloop的scheduledTaskQueue(定时任务队列)
    lastReadTime=lastWriteTime=now()         #初始化lastReadTime和lastWriteTime为当前时间
    if readTimeOut>0:                        #如果设置了读超时时间
      rtask=new ReaderIdleTimeoutTask        #创建一个读超时任务
        ReaderIdleTimeOutTask.run   
          nextDelay -= ticksInNanos() - lastReadTime #nextDelay<0表示超时
          IdleStateHandler.schedule          #往eventloop的定时任务队列塞进去下一次的超时任务
          if nextDelay<0:                    #如果本次超时任务检测到了超时 
            pipeline.fireUserEventTrigger    #把超时事件丢到pipeline,由对应的handler的UserEventTrigger进行处理
      IdleStateHandler.schedule(rtask)       #把读超时任务丢到eventloop的scheduledTaskQueue

    if writeTimeOut>0:                       #如果设置了写超时时间
      wtask=new WriterIdleTimeoutTask        #创建一个写超时任务
        WriterIdleTimeoutTask.run
          change=WriterIdleTimeoutTask.hasOutputChanged #检测输出缓冲区是否发生了变化
            1:检测是否有write操作
            2:检测是否有flush操作
            3:检测输出缓冲区是否发生了变化。就是对缓冲区做一次hash
          if nextDealy<0&&change:            #如果检测到了写空闲超时时间就发送UserEventTrigger
            pipeline.fireUserEvetnTrigger    #!!不同的event有不同的类型,所以UserEventTriggerHandler可以
          IdleStateHandler.schedule            #往eventloop的定时任务队列塞进去下一次的超时任务
      IdleStateHandler.schedule(wtask)   #把写超时任务丢到eventloop的scheduledTaskQueue

    if allTimeOut>0:                     #如果设置了all超时时间即读写
      alltask=new AllIdleTimeoutTask     #创建一个all超时任务
        AllIdleTimeoutTask.run           #就是既检测读也检测写
      IdleStateHandler.schedule(alltask) #把all超时任务丢到eventloop的scheduledTaskQueue

2:channelReadComplete
IdleStateHandler.channelReadComplete
  lastReadTime = time.now                #重置lastReadTime
  reading = false;                       #重置reading,reading=true表示读取流程还没处理完
  ctx.fireChannelReadComplete();         #继续传递readComplete事件


3:write。write/connect这些都是由外到内的动作,所以都是异步,通过promise来处理
IdleStateHandler.write
  ChannelFuture promise=ctx.write   
  ChannelFuture.addListener              #在operationComplete事件中重置写超时变量即lastWriteTime
相关推荐
WZTTMoon5 分钟前
Spring 配置解析与 @Value 注入核心流程详解
java·spring boot·spring
程序定小飞35 分钟前
基于springboot的健身房管理系统开发与设计
java·spring boot·后端
wxin_VXbishe1 小时前
springboot在线课堂教学辅助系统-计算机毕业设计源码07741
java·c++·spring boot·python·spring·django·php
信仰_2739932431 小时前
RedisCluster客户端路由智能缓存
java·spring·缓存
兰雪簪轩1 小时前
仓颉语言内存布局优化技巧:从字节对齐到缓存友好的深度实践
java·spring·缓存
CaracalTiger1 小时前
本地部署 Stable Diffusion3.5!cpolar让远程访问很简单!
java·linux·运维·开发语言·python·微信·stable diffusion
okjohn2 小时前
《架构师修炼之路》——②对架构的基本认识
java·架构·系统架构·软件工程·团队开发
落笔映浮华丶2 小时前
蓝桥杯零基础到获奖-第4章 C++ 变量和常量
java·c++·蓝桥杯
合作小小程序员小小店2 小时前
web网页开发,在线%就业信息管理%系统,基于idea,html,layui,java,springboot,mysql。
java·前端·spring boot·后端·intellij-idea
陈果然DeepVersion2 小时前
Java大厂面试真题:从Spring Boot到AI微服务的三轮技术拷问(一)
java·spring boot·redis·微服务·kafka·面试题·oauth2