question

Upvotes
Accepted
5 0 0 3

370_MP_Batch example with single-thread does not work

I changed the 370_MP_Batch example to create the OmmConsumer with .operationModel(OmmConsumerConfig::UserDispatchEnum), then called consumer.dispatch(OmmConsumer::InfiniteWaitEnum); after registering the client. The result was that the registered client's onRefreshMsg was not called; the dispatch function returned zero immediately.

I then changed the code to call consumer.dispatch(10) repeatedly, and this worked; the callback's refreshMsg function was called.

This problem does not occur when requesting a single RIC (by invoking ".name(ric)" on the client; it only occurs when invoking ".payload( ... )" on it.

Can anyone tell me why it doesn't work? Below is the code that demonstrates the problem.

OmmConsumer consumer {

OmmConsumerConfig()

.host( host.c_str() )

.username( user.c_str() )

.operationModel(OmmConsumerConfig::UserDispatchEnum)

};

//auto consumer = makeSyncConsumer(host, user);

UInt64 handle = consumer.registerClient( ReqMsg().serviceName( "IDN_SELECTFEED" )

.interestAfterRefresh(false)

//.name("0#BAC*.U")

.payload( ElementList().addArray( ENAME_BATCH_ITEM_LIST, OmmArray().addAscii( "0#BAC*.U" ).addAscii( "0#TEF*.i" ).complete() ).complete() )

, client );

consumer.dispatch(OmmConsumer::InfiniteWaitEnum);



batch-request
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

@Tony Marshall

Thank you for your participation in the forum. Is the reply below satisfactory in resolving your query?
If so please can you click the 'Accept' text next to the appropriate reply? This will guide all community members who have a similar question.

Thanks,
AHS

Upvotes
Accepted
25.3k 87 12 25

Hi @Tony Marshall

Thanks for the update and explanation.

With the 1st snippet above (with the single dispatch call), the example should return once the event for the Batch Request accepted Status msg has been dispatched.

Just to be clear - do you still require assistance - or are you happy with your above answer?

If you are only interested in snapshots and wish to wait till all snapshots have been received, you could set a counter in your onRefresh/onStatusMsg callbacks.

You can then loop until you have received either a snapshot or stream closed response corresponding to the number of RICs in your batch (+1 for the batch accepted response). You would need to count any stream closed Status Msgs as well - in case any of your RICs were rejected (for whatever reason) and therefore you would not expect to receive a refresh for the closed stream RICs.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
25.3k 87 12 25

Hi @Tony Marshall

Calling Dispatch once is not sufficient - otherwise, it will only dispatch once and then move on - which for the 370 example means it will exit.

I tried your scenario with a single name(RIC) and I managed to receive only a single Refresh before the example terminated. If I put the dispatch in a loop then I continue to receive Updates etc for the single RIC.

With a batch request, the single call to dispatch allows me to receive the OnStatusMsg callback which confirms the Batch request was accepted and then the application terminates as expected.

Also, are you interested in streaming updates for your RICs or just a snapshot? If a snapshot, then you can set the interestAfterRefresh flag to false e.g.

ReqMsg().serviceName( "ELEKTRON_DD" ).interestAfterRefresh(false)

This will mean the API will close off the streams for each item in your batch, once a Refresh for each valid RIC (or close stream Status for each invalid RIC) is received.


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 0 0 3

I'm not interested in streaming updates; I just want a snapshot, so I thought I'd do it all on the main thread. My example was poorly formatted and I've included it below, this time in a code block.

OmmConsumer consumer {
    OmmConsumerConfig()
        .host( host.c_str() )
        .username( user.c_str() )
        .operationModel(OmmConsumerConfig::UserDispatchEnum)
    };
UInt64 handle = consumer.registerClient( ReqMsg().serviceName( "IDN_SELECTFEED" ) //"DIRECT_FEED" )
    .interestAfterRefresh(false)
    .payload( ElementList().addArray( ENAME_BATCH_ITEM_LIST, OmmArray().addAscii( "0#BAC*.U" ).addAscii( "0#TEF*.i" ).complete() ).complete() )
    , client );
consumer.dispatch(OmmConsumer::InfiniteWaitEnum);

So the call to dispatch in the above example returns immediately without any call to the onRefreshMsg callback being made.

When I change the call to dispatch to the following, then it works: the onRefreshMsg() is called for both the RICs.

for (size_t i = 0; i < 3; ++i)
{
    consumer.dispatch(1000);
    ::Sleep(1000);
}

The first call to dispatch resulted in the onStatusMsg being called with the Batch request acknowledged state that you mentioned. The second call to dispatch resulted in two calls being made to onRefreshMsg: one for each RIC. The third call to dispatch resulted in no callback being made, as I had set interestAfterRefresh(false) on the request message object.

This is the first time I've used any Refinitiv API so I misunderstood the meaning of the dispatch(InfiniteWaitEnum) function; I thought it would terminate only when all the callbacks for a request message had been made.

This raises the following questions

  1. How does one determine when to stop calling dispatch after having sent a request? In this example, one needs to call it twice; is this also true when requesting 100 RICs in a batch?
  2. If using the asynchronous model (i.e. not calling operationalModel(UserDispatchEnum)), then hows does one determine when the last callback has been made? Do I need to keep track of the RICs for which the callback has been made in order to unblock the main thread that is waiting for onRefreshMsg to be called for all the RICs in the request?


icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 0 0 3

Thanks for your reponse. I got a basic version working before reading it; however, your advice on how to detect the termination of the callbacks is useful and I'll try implementing it. If I have any more questions about your advice, I'll reply here.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.