ITQuants blog

Fusion Capital Sophis v7: how to listen to coherency events in a batch/server mode?

Feb 2

Written by:
2/2/2016 1:49 PM  RssIcon

Some days ago, I talked about the possibility to use the Sophis.Core.Data, Sophis.Event.Core and Sophis.Event.Risque assemblies, in order to listen to specific events for toolkit columns performance optimizations. I've tried to use the same mechanism in a batch, using the following code :

class Program
{
static void ProcessEvent(Sophis.Event.IEvent myEvent, ref bool bProcess)
{
}
static void Main(string[] args)
{
CSMApi _api = new CSMApi();
try
{
_api.Initialise();
}
catch (Exception e)
{
return;
}
Sophis.Event.SophisEventHandler _handler = new Sophis.Event.SophisEventHandler(ProcessEvent);
Sophis.Event.SophisEventManager.Instance.AddHandler(_handler, Sophis.Event.Thread.MainProcess, Sophis.Event.Layer.Model);
bool _stop = false;
while (!_stop)
{
Sophis.Event.SophisEventManager.Instance.Dispatch();
System.Threading.Thread.Sleep(500);
}

 

Unfortunately, this code does not work as is. Putting a break point in the ProcessEvents method shows that it is never called, even if messages are received and processed. The goal of this post is to explain how it works and what it is missing.

First, in order to resolve it, I took a look at the disassembly code. I've found that for some reason, the handler was not called due to some key not found in a map.  After some investigation, I've decided to test the code in C++. I knew that the Event Manager was exported in C++, whith the EventHandler callback, in the low level toolkit. I've tried first the following code:

class EventHandlerImpl : public sophis::event::ISEventHandler
{
public:
    EventHandlerImpl()
    {
    }
    // Return the name of the handler. Used for log purpose.
    virtual _STL::string GetName() const
    {
        return "ITQuants::EventHandler";
    }
 
    // Called each time an event is received.
    // If deleteEvent is set to true, the event is deleted
    // and other handlers won't be called for this event.
    virtual void HandleEvent(const sophis::event::ISEvent & event, bool & deleteEvent)
    {
        try
        {
            Sophis::Event::IEvent^ _event = Sophis::Event::EventModel::CreateSophisEvent(event);
            ITQuants::EventHandler::Global::HandleEvent(_event,deleteEvent);
        }
        catch(System::Exception^ e)
        {
            System::String^ _msg = e->Message;
        }
    }
};
 
static EventHandlerImpl* m_handler = NULL;
 
 
void NativeGlobal::Register()
{
    if(m_handler==NULL)
    {
        m_handler = new EventHandlerImpl();
        sophis::event::gEvtMgr.AddHandler(*m_handler,sophis::event::eThread_MainProcess,sophis::event::eLayer_Model);
    }
}

 

Putting a breakpoint in the C++ HandleEvent method, I've seen that the callback was right called during the call of the Dispatch method. Unfortunately, the EventModel::CreateSophisEvent method fails, with an exception indicating that the key was not found. Taking a look at the content of this method, I've found a method AddEventType, that permits to link the what to the Type of class. Such a dictionary is initialized in some Initialize method. Finally, I've found the missing calls: Sophis.Event.EventModelRisque.Initialize and EventModelDRT.Initialize.

The following code works finally right:

class Program
{
    static void ProcessEvent(Sophis.Event.IEvent myEvent, ref bool bProcess)
    {
    }
    static void Main(string[] args)
    {
        CSMApi _api = new CSMApi();
        try
        {
            _api.Initialise();
        }
        catch (Exception e)
        {
            return;
        }
 
        Sophis.Event.EventModelRisque.Initialize();
        Sophis.Event.EventModelDRT.Initialize();
 
        Sophis.Event.SophisEventHandler _handler = new Sophis.Event.SophisEventHandler(ProcessEvent);
        Sophis.Event.SophisEventManager.Instance.AddHandler(_handler, Sophis.Event.Thread.MainProcess, Sophis.Event.Layer.Model);
        bool _stop = false;
        while (!_stop)
        {
            Sophis.Event.SophisEventManager.Instance.Dispatch();
            System.Threading.Thread.Sleep(500);
        }
        try
        {
            _api.Dispose();
        }
        catch (Exception e)
        {
        }

 

 

Tags: events , Risque , ITQuant
Categories: Sophis, C++, C#

Search blog