00:02
China pipeline调度handler的源码剖析,前面呢,我们讲了一下China paperline的相关的内容,那现在呢?我们来看一下chinaline,它到底是怎么样把我们这个handler进行一个调度的。从源码的这个角度,并且呢,从debug的这样一个过程,我们来看看他到底是怎么一步一步执行handle的调度的,我们先来看。源码剖析的目的当一个请求进来的时候,China制排on呢?是如何调用内部的这些handle handle的呢?我们来一起分析一下。首先。当一个请求进来的时候,会第一个调用pipe相关的方法。如果是入战的事件。那么这些方法是用fire开头,就是同学们只要看到是入站的这个事件啊,就是fire开头的表示,开始管道的流动,让后面的handler继续处理。
01:03
那我们来看一个具体案例,待会儿呢,我们这样做,当浏览器输入这样一个地址的时候,就可以看到会执行这些行,在那我会下接断点。那么我们可以从哪里下呢?我们可以将断点下载debt China。呃,拍这个。这个位置开始下,就是fair China active就开始执行,我们也可以从这开始执行呢,我们也可以从这个fire China read方法执行,这个呢,看根据你的这个实际情况,都可以去进行一个进行一个debug的测试,好的,那现在呢,我们来一起看一下吧。首先我们要明白第一点,大家首先要明白的是我们这一个pipeline。就是China pipeline,它真实的数据类型其实是default China pipeline,我们来下一个断点看一下。我在这里呢,各位同学,我就把断点下在这个位置好不好,然后呢,我们DEBUG1把,调到老师思路。
02:06
Debug一下。OK。现在呢,我们打开浏览器,发出一个请求,断点就会下载。我们这个位置没问题吧。好,那同学,我们来看一下此时此刻这个China pipeline真实的类型是什么?啊,还没到这来哈,我们让一下再让一下,再让一下好到这来了。那现在呢,我们看一下ctx里面,通过ctx我们可以找到pipeline的真实类型。我们可以找到China拍on的真实类型。我们从这找。大家可以看到pipeline是devot China pipeline,所以说我们待会儿要去追源码呢,应该找到deat China pipeline。好,那现在我们打开它的源码。来分析下。我们输入default。
03:02
China。拍烂就他了。那现在我们看一下这头它的结构。好同学们,我们可以看到这个强制拍呢,它有相关的一些方法,很多方法哈,方法特别多,那现在我们没有办法一个一个的去看,那现在呢,我已经把这些。第八个流程已经整理好了,我们看一下。在我们default强制排判断里面呢。我们可以看到有这样一些相关的方法,叫FIRE2打头的。The fair active fair inac。Fair exception catch等等吧,还有fair user event triggered,还有fair China。这个我就不一个看了,可以看出这些方法都是英镑的方法,也就是它是入站的方法,它调用静态方法传入的也是英镑的类型的hide。Handle,那有些同说你你这些怎么来理解呢?我给大家追一下源代码,我就以这个为例。
04:06
我以fair China read方法为例给大家追一下。大人人听哈。发尔,就他吧。我们往这里面去追一下,它会调用invoke channel进去,大家看到它第一个传入的。他在进行这个处理的时候,他第一个传入的是head。OK,那怎么说明它下面掉的都是入站的handler呢,进到这里面去。大家可以看到在这里。它调用invoke read,那我们。往这面去走啊,大家看到这里面呢,他会拿到这一个一个执行器,就next拿到拿到这个执行器ex那判断。In loop在不在我们这个loop里面,在的话呢,它就进到这里面去,我们继续往里面追,大家可以看到它在这里面会调用我们handler contact的invoke China read,这个read方法大家看到非常非常清晰的说明了它的一个流程干什么,它是一个inbound handler。
05:12
OK。如果说他这地方转换有问题的话呢,它会抛出一个异常。对吧,那么我们来接着看,他拿到这个handle德尔过后,当这个handle德尔肯定就是返回一个handle德尔的嘛,这个很好,很好理解,那再来看德尔成read,诶大家现在理解了吗?为什么为什么当事件读取的事件,那就是当我们有读取事件发生的时候,你这个你写的China read的方法会被调用。大家还记不记得,我们看这里。你这个方法。就是比如说我们这有一个。我们自己写的echo server handle,它这个方法会被调用呢?为什么它会被调用,其实它的底层要恢复到这里,它的底层是在这儿。来给调用的,他会拿到你这个handleler在它底层哈,就是由这个contact拿到你这个handler,然后调用。
06:04
China read,并且把当前这个大家看这边,把当前这个呢再传给你。看到没有,所以说它是这样来调用的。好,接着继续往下看。那么我们可以看到这些静态方法会调用hide的China inbound invo的接口的方法,然后调用handler的,真正的那个方法就是在这体现出来的。是不是这边是调用真正的我们handler的相关的方法呀,那。接着继续分析,下面呢,我们再来看pipeline的outbound的fire相关方法。那它还有哪些呢?大家可以看到它还有这样一些方法,Band connect。Connect,还有。的。还有close这些方法呢,大家可以看到我直接因为方法很多,我就不一个念了,这些都是跟我们出战相关的,大家注意出战的时候呢,你们往我,我们待会注意一个源码,你们会发现它是从这一个T开始执行的。
07:07
为什么呢?因为你出战首先执行的是ta,我们来看一下源码是不写的,打开这里我就随便找一个方法。还回到我们depot China。我找一个band吧。找一个bad方法。OK。这还不太好找啊,方法太多了。我给同学们找一下。Be在哪去了?还不好找这么多方法。没找错吧?可在这。好,我们来看一下band话,Band方法呢,其实它本身是属于一种出战的,那现在我们看大家一看就已经看明看看明白了,看到这里面他马上掉的是tell。对不对,所以说从这里我们可以看出来。这样一个结论。出站是从T开始的,入站是从head开始的,因为出站是从内部向外面写,少了一个字。
08:07
向外面写。从T儿开始就是出站呢,是从内部向外面写,所以说从T儿开始能够让前面的handle德ler进行处理,防止有handler有。有handler啊,这么这个写错了就就防止吧,防止handler被遗漏,比如编码,编码是不是就是我们的出战,反之入站当然是从hi向内部输入。让后面的handler能够处理这些输入的数据,比如解码。因此hi headde呢,它也实现了outb的接口,但不是从hide开始执行出站,而是从我们跳开始执行出站的,这个原因就理解清楚了。那现在呢,我们看一张特别重要的图,待会老师呢再给大家debug一下,就看的很清楚了。我们说整个这个调度流程哈,就是拍过滤器的调度过程,他先找到我们pipeline的一个file,什么什么方法从head开始,待会呢我也以hi当时代表入战了。
09:12
我待会儿呢也给大家动态的DEBUG1本。从这开始记hadde,那他这个headde走了过后,他先干什么呢?他去调用我们这个invoke什么什么方法把这个contact传进去,对吧,然后呢,找到next,就是下一个的contact的invoer方法。然后把next传进去,然后呢,再去调用我们handle的真实的方法。然后这个方法执行完毕过后又怎么办呢?好的,他再去找contact fire的某某方法,这个参数是寻找下一个节点的ctx及我们的context,然后这个做完了过后呢,继续调用下个节点,在这进行一个循环。直到我们整个pipeline的入战。
10:02
的整个这个就是我们所说的什么呀,入战的汉德被全部调完,然后再退出。好,那这个呢,就是它的一个流程图,那现在同学们。为了让大家对它有一个比较深刻的认识,我们怎么办呢?我们来一个debug,我们让大家看到这个流程,那现在为了看到这个流程呢,我需要先下一个断点。在哪下个断点呢?来朋友们,我们我们在这个地方吧。找一个比较熟悉的,大家fire train吧,Fire。从这开始走。好吧,我们在这儿下个断点。没问题吧,这是下个断点,然后呢,代码呢,我我把其他不必要的断点先给他拿掉。我们直接就定位到这里。Default。是这儿吗?这就不要了啊,这个这个我这个端点我就不要。
11:01
保留了一个断点,这个断点就是。在该文件的943行下面的两动。那待会儿呢,我们执行的时候就会由这个地方开始我们的发圈read,待会呢,我们看看整个这个流程跟我们画的这个图是否能够对应。来,现在已经到fire成read了,那现在呢,我们把这个停下来。停下来过后呢,我们回到。这个项目里面。运行对吧,开始跟上老师思路。好,运营起来了,运营起来功能大家可以看到这边已经处理到China active就是被激活状态了,那现在呢,我们打开浏览器输入。Go ahead。大家看到代码已经到这来了啊,也就是说此时此刻已经到哪到哪一步了呢?根据我们这个图已经到这个file了,现在我们开始往下走,进入到这个代码里面去,已经到invoke channel read了,也就是说现在大家可以理解理解我们这已经到这个位置了。
12:02
Fair里面的invoke某某某方法。好的,那接着继续追。最进去。大家看到在这追的时候呢,往下走来了,大家看这个时候我问大家一个问题,Next线是什么。现在现在是什么?是不是就是我们的hi的context?因为他是第一个执行的嘛,说了半天嘛,就是第一个执行的好,第一个执行呢,接着他就往下继续来执行走。好,大家看next。对吧,那是我们的headde context,那现在呢,调用invoke Cha read还没有调到这里,还没有调到我们真实的handler的那个Cha read啊,所以说相当于已经到哪一步了呢。明白。到这儿,到这儿进去,来,朋友们追进去,朋友们看,往这儿走。大家看到这时。他就从这个那往里面追的话,它会进入到head这个这个handle方法,那么我们追一下,也也就是说现在已经到哪一步了呢?相当于你你你可以理解到这这一步了,就是handler的什么什么方法。
13:15
那现在我追进去给大家搂一眼。哎,大家看是不是返回了这个handlera。就是当前这一个,呃,Contact关联的这个handle。那么我再退出来,返回来,返回来过后是不是又去执行它的China read了?好,我们追进去,我们追进去。追进去。大家看是不是追到这里面过后,就是就是相当于说刚才呢,他已经把这个方法给执行了,执行完毕以后,执行完,因为我我这。我这这这个地方已经相当相当于执行到我们这个China。Read的方法了,Read方法过后,是不是又到这个fire turn read了,于是我们又往下面执行。
14:04
接着走。大家可以看到。哎哟,这个地方不好意思,我应该追进去,我应该追进去啊,所以如果我不追进去的话呢,这个就马上就结束了,不行我还重新来一下,不好意思,因为我没有追进去,就没有没有办法让大家看到它的一个循环的过程,稍等我马上再追一下。这个断裂还留在这儿,我们再重新来一下。这次呢,我们稍微快点走一下,认真听。好来,刚才我直接跳过了,那就看不到这个流程了。好,来了,继续追进去,跑进去了,好下一步下一步。下一步到我们的invoke追进去。好,往下追。好,同学们看这个地方你不能退出来,退出来他就他他就不跑了,所以说我们要干什么呢?追进去,返回来再追到我们China追进去。
15:06
好,就到这里面,看到是不是又来一个发read了。是不是又来一个好,再追进去,是不是又invoke read了,看懂了没有再追进去。是不是来,诶,大家看到这个地方来干什么了?他是不是要尝试着取出下一个ctx?是不是相当于说又回到了。下一个流程。是不是来到下一个,继续调用下一个节点的什么什么invoke方法。那当然,它在调用之前,它首先先要find contact inbound,因为现在我是入站对不对,我接着往下走走返回。走起来是不是?又来了吧,因为他刚才已经执行了半contactbo返回来了,然后呢,再去调我们invoke read,好,接着继续执行,注意精确。看到是不是又得到我们VO,然后又像刚才这个流程来了一遍,走走走,是不是又来了同学们看到又到这个invoke,再追进去。
16:07
是不是又来了,往下走,诶是不是这个流程好像刚才走过一圈了。又来到这里,又读取我们这一个handle的read。对,再追进去。返回。返回。然后再追进去。看到没有,好,这个就是到下一个了,看这是这追到我们logging handler了。这是我们这个程序里面的一个logging。对吧,然后呢,接着往下继续走。对吧,又往下跑,以此类推,最后呢,经过你一番折腾对吧,整个代码到这里,他肯定就会把你这个整个入站的事情全部给你处理完毕,因此这张图同学们看这张图其实就把我们整个。Pipeline的整个对他的就是handle的调度的一个循环的过程,说清楚了。那么我们在这再给他做一个小结,太论呢?首先会调用context的静态方法file什么什么方法,并传入context,然后静态方法调用context invoke方法,而invo方法内部又会调用该所包含的handle真正的什么什么方法,比如刚才我们写的read channel read的方法,那么调用结束过后呢?如果还需要继续向后传递,就调用contact fire。
17:29
下一个方法,然后循环往复,直到整个这条链,就是我们拍拍烂这条链,全部执行完毕。同学们,经过这个分析,是不是面试官如果再来问你的话,你就知道这个图怎么去表达了,也就是说如果面试官问题的话呢,你只要把这个给他讲清楚就行了,因为刚才我们已经用debug的方式把它走了一圈。同学们可以自己呢,呃,写,多写几个汉字。来调用一下,效果就会更好,好同学们,那关于China pipeline如何调用handle的这个源码级的分析,我们就到这里。
我来说两句