老师,您好,非常感动于精彩的讲解。我有个问题想要提问,是关于使用HookStarter优雅的停止服务,并触发其余Starter的Stop方法。
在app.go文件中,我只启用了4个基本的Starter,分别对四个Starter的Stop方法只写了一个fmt.Println的方法,但是在手动Ctrl-C停止服务时,却发现执行了四次针对IrisServerStarter函数的Stop方法的执行。

上述现象发生之后,我感觉这个现象好像是函数在异步执行,于是做了如下改造:
将callbacks中的函数通过闭包函数的形式执行,同时使用WaitGroup控制等待完成执行。可是结果居然还是一样的。
于是我继续折腾
这次我把WaitGroup废掉,改用了1个缓冲区的channel,结合闭包传递函数执行,结果干脆不打印所要停止的Starter的Stop函数中的fmt.Println的内容了,而且还报了一个错误,尝试用recover忽略也不行,貌似又一个问题。
有点黔驴技穷,所以没办法,只能求助一下偶像神老师了!
今天按照评论里面的思路,尝试的对代码进行了改写,发现这样是可以的了。
先看下执行效果,我在validator和props中增加了一个Start函数,在这个函数的最后增加一行调用ListenStopSig函数。该函数其实就是监听context.Context的Cancel函数被调用,从而触发调用当前Starter的Stop函数,以便达到资源回收的效果。这里的ListenStopSig最好原样不动的从BaseStarter中复制过来,如若在这里不写,则默认就会调用到BaseStarter中的Stop函数,就无法达到回收当前Starter的资源的效果了。这是由于go的组合调用策略导致的,也是和java、python等其他面向对象的差别。go就是go,不一样的烟火。我用的是go1.13.8,兴许以后google修改调用策略呢,也难说!
下面是把StarterContext改为了context.Context,并将原来的map[string]interface{}放到了context的value中。同时SetProps函数也将starterCancel函数对外暴露一个函数。
在hook的init函数中,接到signal信号,则通过该函数执行来触发所有需要回收资源的Starter。(注意这里是两对儿括号)
这样优雅就相对舒服了~!:)