我有一个应用程序可能会在接收到 ExecutionReport (35=8) 消息时引发错误。此错误是在应用程序级别而不是在修复引擎级别引发的。修复引擎记录所见消息,因此不会发送 ResendRequest (35=2)。但是应用程序尚未处理它,我想手动触发对错过的 ExecutionReport 的重新处理。
强制 ResendRequest (35=2) 不起作用,因为它需要修改预期的下一个序列号。
我想知道 FIX 是否支持重播消息但不需要重置序列号?
我有一个应用程序可能会在接收到 ExecutionReport (35=8) 消息时引发错误。此错误是在应用程序级别而不是在修复引擎级别引发的。修复引擎记录所见消息,因此不会发送 ResendRequest (35=2)。但是应用程序尚未处理它,我想手动触发对错过的 ExecutionReport 的重新处理。
强制 ResendRequest (35=2) 不起作用,因为它需要修改预期的下一个序列号。
我想知道 FIX 是否支持重播消息但不需要重置序列号?
在处理执行报告时,您不应该抛出任何异常并期望 FIX 库来处理它。您要么处理报告,要么遇到系统故障(即调用abort()
)。因此,如果您处理执行报告的代码抛出异常并且您知道如何处理它,那么在同一个函数中捕获它,消除问题的原因并再次尝试处理。例如(伪代码):
// This function is called by FIX library. No exceptions must be thrown because
// FIX library has no idea what to do with them.
void on_exec_report(const fix::msg &msg)
{
for (;;) {
try {
// Handle the execution report however you want.
handle_exec_report(msg);
} catch(const try_again_exception &) {
// Oh, some resource was temporarily unavailable? Try again!
continue;
} catch(const std::exception &) {
// This should never happen, but it did. Call 911.
abort();
}
}
}
当然,如果抛出异常,可以让 FIX 库执行重新传输请求并再次向您传递该消息。但是,这根本没有任何意义,因为要求发件人(通过网络,使用 TCP/IP)重新发送您已经拥有的消息(在您的堆栈上 :))并且只需要过程。就算发生了,又有什么保证不会再发生呢?在这种情况下重新传输不仅在逻辑上听起来不正确,另一方(即交换)可能会打电话给您并要求停止做这种废话,因为您在他们的服务器上施加了过多的负载而不必要的重新传输(因为IRL TCP/IP 不会丢失消息,FIX 序列同步过程仅在连接时发生,除非当然使用了一些不可靠的传输,这在理论上是可能的,但没有
然而,当中止时,FIX 库有责任不增加 RX 序列,除非它确定用户已经处理了消息。这样下次应用程序启动时,它实际上会执行同步并接收丢失的消息。如果 QuickFIX 没有这样做,那么您需要修复此问题,手动处理此问题(即,搞砸存储 RX/TX 序列号的文件),或使用其他一些可以正确处理此问题的库。
这是错误的做法。
ResendRequest 告诉对方有一些传输错误。在你的情况下,没有,所以你不应该这样做。您滥用协议来掩盖您的应用程序的错误。这是错误的。(另外,正如弗拉德·拉扎连科在他的回答中指出的那样,如果他们确实重新发送了它,那说明你不会再有错误了?)
如果您的消息处理程序中发生错误,那么这就是您的问题,您需要找到它并修复它,或者您需要捕获自己的异常并相应地处理它。
(根据过去的问题,我敢打赌您正在将 ExecutionReports 存储到数据库存储或其他东西,并且您想使用重新发送来补偿数据库存储异常。坏主意。您需要提出自己的冗余解决方案。)