我们有如下设计,我想获得意见或协议指南 对于以下错误情况。
Layer1
---------------
| ^ ^
| (1) |(4) |(6)
v | | Remote entity
---------------- ---------------
Layer0-----------------(2)------------------------------->Layer0
Layer0<----------------(3)--------------------------------Layer0
Layer0<----------------(5)--------------------------------Layer0
1. New session request to remote entity.
2. Establish link + data(session request)
3. Link Establishment ongoing
4. Link Establishment pending
5. Link Established + data (session accepted)
6. session accepted.
如果第1层在第4步和第6步之间决定它不需要远程实体服务,即收到事件4,由于某些错误,尚未收到事件6。
1)是否应该等待事件6发生并启动会话释放或
2)Layer1应指示第0层终止连接建立过程
立即
哪种方法正确?
(1)的问题是,即使我们知道由于错误我们将要终止会话,我们需要在event6进入之前处理其他事件。
答案 0 :(得分:7)
我是fail fast设计的粉丝。一旦你知道你无法继续,你应该通知对方,然后退出。
如果由于某种原因您需要验证对方是否收到了您的退出消息,我更愿意使用UNABLE_TO_COMPLY
消息回复请求,或者完全丢弃事件。问题是你可以处于半开状态。
在您已经发送失败消息之后,处理另一方等待来自其他请求的响应的情况的一种方法是使用优先级队列。您可以指示某些消息无论何时收到,都可以立即处理,而不是按接收顺序处理请求。优先级较高的消息会插入队列的前面,因此quit_on_failure
事件不会被您知道无法真正处理的其他请求阻止。
我通常也不喜欢基于时间的监视器(因为开发人员选择的时间长度在所有情况下都不正确),但是对于这些类型的协议,您经常需要定义最坏情况,而另一方从不响应你的fail
消息。在这些情况下,可配置的超时通常是清理的唯一方法。超时应该永远是最后的手段,永远不是第一个。
答案 1 :(得分:1)
您应该在协议中添加某种(非)确认消息以及适当的超时。然后,第1层取消待处理会话的请求可以通过nack来实现来自远程会话的下一条消息,或者只是客户端无法响应来自远程会话和远程会话时间的响应由于不活动而退出。
正如之前的海报正确指出的那样,没有超时处理就无法拥有完整的协议,因为这是捕获底层传输失败的好方法。您是否选择仅依靠超时作为发出“协议终止”信号的方式是一个设计决策。我通常会尝试在协议中发送一个nack或取消,以至少尝试在两端及时完成协议。但是你也需要超时。
答案 2 :(得分:0)
在没有来自接收方的任何确认的情况下,一个方向(通过层)连续有4条消息吗? 让客户端发送确认消息,如TCP中的SYN-ACK / RST数据包,将自动处理相关场景,并帮助解决其他错误模式(当客户端或网络出现故障时)。
答案 3 :(得分:0)
1)是否应该等待事件6发生并启动会话释放
恕我直言,你不应该在终止请求中阻止客户端。可能是应用程序需要关闭,因为系统正在关闭。无论如何,你无法在现实中做到这一点,管理员可以控制最低级别的电源开关。不接受这种现实将使基于你的协议的产品成为烦人的声誉。
2)Layer1应该指示第0层终止连接建立过程
是
我注意到第1层可能还需要在步骤1之后的任何时间取消,而不是仅在步骤4之后取消。
看起来在第2步之后的任何时间,可能需要一定程度的“解除”才能终止。
本地和远程实体之间存在网络延迟,并且可能对任何给定时间的状态都有不同的看法。例如,本地您可能已完成步骤2,而远程实体认为他已完成步骤5.如果消息可以无序到达(例如,UDP),则会出现更多可能性。
'终止'可能会或可能不会在不同程度上取得成功。如果您发送步骤2,然后终止,但从未收到远程实体的回复,会发生什么?
高级客户可能会施加额外要求。例如,在步骤5之后取消是否与步骤2之后不同?步骤3和5是否代表远程实体的持久修改(如数据库提交)?更高级别的客户端是否需要知道在终止请求处理之前实际进展的程度?
制定出所有可能的组合,并做出正确的决定,让自己置身于用户之中。这里的用户可能是一名工程师,他试图建立自己的协议,使其“适合自己的用户”。完成后,请考虑每条消息在此过程中丢失或延迟时会发生什么,特别是在展开过程中。
然后从远程实体的角度考虑它。他的管理员有时需要能够关闭他,因此需要一种方法来有效地终止每个州的连接。
答案 4 :(得分:0)
你能告诉我等待有什么好处吗?你已经指出这种方法存在问题,听起来像你已经发现选项2实际上是最好的方法。正确性只是一个意见问题,但我会说选项2。
第1层应该指示第0层结束连接过程。该过程还应该指示第0层它不再对接收事件感兴趣。然后,第1层可以在断开状态下继续运行。
对我来说,这是最简单,最明显的事情,而且问题最少。正如您已经说过的那样,您不需要在第1层处理任何更多状态,因为当您已经关闭连接时,您不会期望这些其他消息。