This sample demonstrates the throttling of incoming messages on the acceptor's side.
Source code
Listener.h
{
public:
Listener();
bool failed() const;
void onInboundApplicationMsg(OnixS::FIX::Message & msg, OnixS::FIX::Session * sn) final;
void onInboundSessionMsg(OnixS::FIX::Message & msg, OnixS::FIX::Session * sn) final;
OnixS::FIX::Throttler throttler_;
size_t totalOrdersHandled_;
size_t totalMessagesRejected_;
private:
void recordFailure();
int ordersCounter_;
mutable OnixS::Threading::Mutex failureMutex_;
bool failed_;
};
Listener.cpp
#include "Listener.h"
#include "../../Common/Settings.h"
#include "../../Common/Helpers.h"
using namespace Settings;
using namespace OnixS::FIX::FIX44;
using namespace OnixS::FIX::FIX44::Values;
Listener::Listener() :
throttler_(1), totalOrdersHandled_(0), totalMessagesRejected_(0), ordersCounter_(0), failed_(false)
{
}
bool Listener::failed() const
{
return failed_;
}
void Listener::recordFailure()
{
failed_ = true;
}
{
std::clog << "\nIncoming application-level message:\n" << msg << std::endl;
try
{
if(throttler_.tryThrottle())
{
sn->
sendReject(msg.
seqNum(),
"The message is rejected due to throttling limit exhausting");
++totalMessagesRejected_;
std::clog <<
"Rejection " << totalMessagesRejected_ <<
": message " << msg.
seqNum() <<
" rejected due to throttling limit exhausting." << std::endl;
return;
}
if(msg.
type() == MsgType::NewOrderSingle)
{
Message execReport(MsgType::ExecutionReport, FixProtocolVersion);
execReport.set(Tags::OrderID, order.
get(Tags::ClOrdID).
toString());
const int EXEC_ID_SIZE = 128;
char execID[EXEC_ID_SIZE];
xsnprintf(execID, EXEC_ID_SIZE - 1, "ExecID_%d", ++ordersCounter_);
execReport.set(Tags::ExecID, execID)
.set(Tags::ExecType, "0")
.set(Tags::ExecTransType, "0")
.set(Tags::OrdStatus, "0")
.set(Tags::OrderQty, order.
get(Tags::OrderQty).
toString())
.set(Tags::CumQty, order.
get(Tags::OrderQty).
toString())
.set(Tags::AvgPx, 100.0)
.set(Tags::LastPx, 0)
.set(Tags::LeavesQty, order.
get(Tags::OrderQty).
toString());
++totalOrdersHandled_;
}
}
catch(const std::exception & ex)
{
recordFailure();
std::clog << "Exception during the processing of incoming message: " << ex.what() << std::endl;
}
}
{
std::clog << "\nIncoming session-level message:\n" << msg << std::endl;
}
{
}
{
recordFailure();
std::cerr << "\nSession-level error:" << description << std::endl;
}
{
std::cerr << "\nSession-level warning:" << description << std::endl;
}
ThrottlingSellSide.cpp
#include "Listener.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
int main()
{
std::clog << "ThrottlingSellSide sample." << std::endl << std::endl;
try
{
EngineShutdownGuard engineShutdownGuard;
Listener listener;
Session session(TargetCompId, SenderCompId, FixProtocolVersion, &listener);
const size_t MessagesPerSecondLimit = 10;
const size_t ThrottlingIntervalMillisecond = 1000;
listener.throttler_.reset(MessagesPerSecondLimit, ThrottlingIntervalMillisecond);
session.logonAsAcceptor();
std::clog <<
"Awaiting session-initiator on port " << settings.
listenPort() <<
"..." << std::endl;
std::clog << "Press any key to disconnect the session and terminate the application." << std::endl;
waitForAnyKey();
session.logout().shutdown();
std::clog << "Orders handled: " << listener.totalOrdersHandled_ << ", messages rejected: " << listener.totalMessagesRejected_ << std::endl;
if(listener.failed())
return 1;
}
catch(const std::exception & ex)
{
processSampleException(ex.what());
return 1;
}
return 0;
}