20210623深化思考service的解耦问题(3) - ziyouzy/2021blog GitHub Wiki

如果是service包内部的事件交互(如EventsBox产生了Error从而将这个error通过管道发送给ErrorsBox;再比如IO01,IO02,ErrorsBox产生了event发送给EventsBox) 在这里明确态度: 这是允许的但是要注意不要影响析构逻辑
并不存在这样的事件必须只能进行简单的log录入这一硬性规则(想象处理IO01,IO02的时候)
另一方面,EventsBox需要作为最后一个析构的对象是绝对的了,因为他需要最终接受诸如ERRORS_CLOSE这样的事件

而针对EventsBox与ErrorsBox交互是否会造成send to close chan1这一问题,其实原则是这样的:
对于这三个管道的close操作都是main层负责的,同时只有当这三个管道的wg都顺利返回后才会进行,因此不会发生这个panic,但是依然存在卡死的可能性

比如ErrorsBox先析构后,有新的event被放入Errors管道,于是这个“放入的操作”就会被卡死了,
但是其实这是个只有一条命的机会,任何容量为0的管道都有一次可以不卡的机会
(也就是管道里没东西的时候“放入了东西”是不会卡住的,但是第二次就不行了)

再比如,ErrorsBox先析构后EventsBox产生了个错误,然后DatesBox又产生了一个错误,那么DatesBox就会妥妥的被卡死了

似乎“逻辑思路”上稳妥的解决方式只有两种:
一种是让ErrorsBox与DatesBox只与EventsBox进行单向通信,同时再却把奥EventsBox在最后析构
另一种则是三者之间完全不去进行数据交互,这样一来不但可以解决当前问题,析构顺序也变得不再重要了

于是引入了这个新问题:是否应该把log在逻辑思路定义成一种“中性的存在意义”呢?

也就是说不该把log分成(赋予)event与error这两种“属性”
而是说,在最后的最后
Errors们会要么转化为pr,要么转化为log
Events们则要么转化为ps,要么转化为log
Dates们本质也是如此(ps)
在逻辑上,从始至终一切都是信息的单向转换,而并不存在双向转换

再从另一个侧面分析,如Errors
他是所有rn.Error的聚合体,而单独一个rn.Error对象所拥有的属性是error+pr+log
同时单独一个rn.Event对象所拥有的属性则是event+ps+log
但是经过了ErrorsBox后,每一个rn.Error都会被剥离成一个error+pr和一个log
rn.Event则被剥离成了一个event+ps和一个log
另另一个侧面:pr是error的唯一特性,ps是event的唯一特性

这些的真正意义在于,当log被改为了“纯粹的中性”意义后
就会发现,如一些Errors所产生的“Events”不需要再去发给EventsBox了,而是直接原地log即可
不再需要去“仅仅因为ErrorsBox内部产生了一个只需要被log而不需要pub的event”而刻意的将这个event通过Events管道发送给EventsBox了

只有当产生了需要被pub的event才有通过events管道发送给EventsBox的必要,如IO01,IO02

于是似乎service包需要一个utils.go,从而实现“log工具”供所有box来使用
更重要的是进行最为合理的“属性剥离”后,就不会再存在rn.Event,rn.Error以及Date了,而是他们三者都被转化成为了pub(ps或pr)与log

其实最直观的体现(举例)依然是在于ERRORS_CLOSE,原地“中性”log即可