我有一个应用程序可能会在收到ExecutionReport(35 = 8)消息时发生错误。 此错误在应用程序级别引发,而不是在修复引擎级别引发。 修复引擎将消息记录为已显示,因此不会发送ResendRequest(35 = 2)。但是,应用程序尚未处理它,我想手动触发错过的ExecutionReport的重新处理。
强制ResendRequest(35 = 2)不起作用,因为它需要修改预期的下一个序列号。
我很想知道FIX是否支持重放消息但不需要重置序列号?
答案 0 :(得分:3)
处理执行报告时,不应抛出任何异常并期望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序列号的问题),或者使用其他一些正确处理这个问题的库。
答案 1 :(得分:2)
这是错误的做法。
ResendRequest告诉对方有一些传输错误。在你的情况下,没有,所以你不应该这样做。您滥用协议来弥补应用程序的错误。这是错的。 (另外,正如Vlad Lazarenko在his answer中指出的那样,如果他们确实重新发送了它,那说你不会再犯错误了?)
如果您的消息处理程序中发生错误,那么您的问题,您需要找到并修复它,或者您需要捕获自己的异常并相应地处理它。
(根据过去的问题,我打赌你将ExecutionReports存储到数据库存储或其他东西,并且你想使用重新发送来补偿数据库存储异常。不好主意。你需要提出自己的冗余解决方案。)