Ariticle

How to Run Refinitiv Real-Time SDK C/C++ Warm Standby Examples

Author:

Jirapongse Phuriphanvichai
Developer Advocate Developer Advocate

A warm standby feature was added in the Refinitiv Real-Time C/C++ SDK 2.0.4.L1. This feature allows a consumer to failover to a standby connection when a primary connection fails or a service is down. Because the standby server is already aware of items an application has subscribed for, during a failover APIs don't need to re-subscribe items to the standby server. Therefore, Warm Standby not only reduces overall recovery time but also network traffic by not inducing a “packet storm” with a burst of re-request messages. Moreover, this process is transparent to the application.

Two types of warm standby modes are supported: Login-based Warm Standby, and Service-based Warm Standby. The login-based warm standby uses the connection lost event to switch from a primary server to a standby server from the standby server list while the service-based warm standby uses the service down event or connection lost event to switch all subscribe items from a primary service to a standby service. Therefore, the service-based warm standby mode offers better resiliency than the login-based mode. For more information, please refer to the Introduction to the Refinitiv Real-Time SDK Warm Standby Feature article on the Refinitiv Developer Portal website.

This article demonstrates how to run Refinitiv Real-Time SDK C/C++ examples that utilize a warm standby feature.

Prerequisites

1.      At least two ADS instances that support a warm standby feature. Those ADS instances must provide an identical service (supported domains, quality of service, etc.). The following configuration must be added to the ADS configuration file to enable a Warm Standby feature on the consumer side.

    	
            *ads*supportWarmStandby : True
        
        
    

Note: Refinitiv Real-Time Optimized (RTO) also supports the Warm Standby feature.

2.      Refinitiv Real-Time C/C++ SDK 2.0.4.L1 or above. You can download  Refinitiv Real-Time C/C++ SDK from the Refinitiv Developer Portal website

Enterprise Message API Warm Standby Configurations

The Warm Standby is made available in Enterprise Message API via the following configurations.

You can add these configurations to the EMA configuration file or programmatically create these configurations in an EMA application to use the warm standby feature.

EMA C++ 470_MP_WarmStandby Example

The 470_MP_WarmStandby demonstrates the usage of the warm standby feature that creates two connections to an active server and a standby server in EMA, and then switches between these two servers when the service is down or the connection is lost. It uses the programmatic configuration to enable the warm standby feature.

The createProgramaticConfig method in the Consumer.cpp is used to create the configurations. It creates the Consumer_8 configuration that uses the service-based warm standby mode named WarmStandbyChannel_1 that connects to an active server (Server_Info_1) and a standby server (Server_Info_2). The following picture demonstrates the warm standby configurations created by the createProgramaticConfig method.

To run the example, first, we need to change the Host and Port configurations in the Channel_1 and Channel_2 nodes. The values of the Host and Port configurations in the Channel_1  are the server name and RSSL port of an active server. The values of the Host and Port configurations in the Channel_2  are the server name and RSSL port of a standby server.

Then, change the PerServiceNameSet configuration in the Server_Info_1 node to the subscribed real-time service name. 

Next, if you would like to change the standby mode from SERVICE_BASED to LOGIN_BASED, change the WarmStandbyMode configuration in the WarmStandbyChannel_1 node to 1.

Then, change a service name and item name in the main function.

Finally, run the example. The example will connect to both active and standby servers, notify the servers about their roles in the warm standby group, send item requests to both servers and retrieve updates from the active server. When a connection to the active server or a service on the active server is down, the example will get updates from the standby server instead. For more information, please refer to the Introduction to Refinitiv Real-Time SDK Warm Standby Feature article.

Instead of programmatically creating warm standby configurations, the following EMA configuration file can be used. It configures Consumer_8 to use the warm standby feature. Then, you need to modify the host and port configurations in the Channel_1 and Channel_2 nodes. 

    	
            

<?xml version="1.0" encoding="UTF-8"?>

<EmaConfig>

<ConsumerGroup>          

               <DefaultConsumer value="Consumer_8"/>

               <ConsumerList>

                              <!-- Consumer for warm standby feature -->

                              <Consumer>

                                             <Name value="Consumer_8"/>

                                             <WarmStandbyChannelSet value="WarmStandbyChannel_1"/>

                                             <Logger value="Logger_1"/>

                                             <Dictionary value="Dictionary_2"/>

                              </Consumer>

               </ConsumerList>

</ConsumerGroup>

<ChannelGroup>

               <ChannelList>

                              <Channel>

                                             <Name value="Channel_1"/>

                                             <ChannelType value="ChannelType::RSSL_SOCKET"/>

                                             <CompressionType value="CompressionType::None"/>

                                             <GuaranteedOutputBuffers value="5000"/>

                                             <Host value="localhost"/>

                                             <Port value="14002"/>

                                             <ObjectName value=""/>

                              </Channel>

                              <Channel>

                                             <Name value="Channel_2"/>

                                             <ChannelType value="ChannelType::RSSL_SOCKET"/>

                                             <CompressionType value="CompressionType::None"/>

                                             <GuaranteedOutputBuffers value="5000"/>

                                             <Host value="localhost"/>

                                             <Port value="14003"/>

                                             <ObjectName value=""/>

                              </Channel>

               </ChannelList>

</ChannelGroup>

<WarmStandbyServerInfoGroup>

               <WarmStandbyServerInfoList>

                              <WarmStandbyServerInfo>

                                             <Name value="Server_Info_1"/>

                                             <Channel value="Channel_1"/>

                                             <PerServiceNameSet value="ELEKTRON_DD"/>

                              </WarmStandbyServerInfo>

                              <WarmStandbyServerInfo>

                                             <Name value="Server_Info_2"/>

                                             <Channel value="Channel_2"/>

                                             <PerServiceNameSet value="ELEKTRON_DD"/>

                              </WarmStandbyServerInfo>

               </WarmStandbyServerInfoList>

</WarmStandbyServerInfoGroup>

<WarmStandbyGroup>

               <WarmStandbyList>

                              <WarmStandbyChannel>

                                             <Name value="WarmStandbyChannel_1"/>

                                             <StartingActiveServer value="Server_Info_1"/>

                                             <StandbyServerSet value="Server_Info_2"/>

                                             <WarmStandbyMode value="WarmStandbyMode::SERVICE_BASED"/>

                              </WarmStandbyChannel>

               </WarmStandbyList>

</WarmStandbyGroup>

<LoggerGroup>

               <LoggerList>

                              <Logger>

                                             <Name value="Logger_1"/>                                                                                                                                                                             

                                             <LoggerType value="LoggerType::Stdout"/>                                                                                    

                                             <LoggerSeverity value="LoggerSeverity::Success"/>

                              </Logger>

                              <Logger>

                                             <Name value="Logger_2"/>

                                             <LoggerType value="LoggerType::File"/>                                                                                         

                                             <FileName value="emaLog"/>

                                             <LoggerSeverity value="LoggerSeverity::Success"/>

                              </Logger>

               </LoggerList>

</LoggerGroup>

<DictionaryGroup>

               <DictionaryList>

                              <Dictionary>

                                             <Name value="Dictionary_1"/>

                                             <DictionaryType value="DictionaryType::ChannelDictionary"/>

                              </Dictionary>

                              <Dictionary>

                                             <Name value="Dictionary_2"/>

                                             <DictionaryType value="DictionaryType::FileDictionary"/>                            

                                             <RdmFieldDictionaryFileName value="./RDMFieldDictionary"/>

                                             <EnumTypeDefFileName value="./enumtype.def"/>

                              </Dictionary>    

               </DictionaryList>

</DictionaryGroup>

</EmaConfig>

Enterprise Transport API Warm Standby Settings

In ETA, the Warm Standby feature is implemented at the Value Add Watchlist layer. It provides the RsslReactorWarmStandbyGroup and RsslReactorWarmStandbyServerInfo data structures to create a Warm Standby group and a Warm Standby server information. Then, the RsslReactorWarmStandbyGroup will be assigned to the RsslReactorConnectOptions instance. The following picture shows the relations of ETA data structures that are used to set a warm standby group. 

The following code can be used to configure a warm standby group.

    	
            

RsslReactorWarmStandbyGroup reactorWarmStandbyGroup;
RsslReactorWarmStandbyServerInfo standbyServerInfo;
RsslReactorConnectOptions reactorConnectOpts;

//Configure an active server in RsslReactorWarmStandbyGroup
reactorWarmStandbyGroup.startingActiveServer.reactorConnectInfo.rsslConnectOptions.connectionType = RSSL_CONN_TYPE_SOCKET;
reactorWarmStandbyGroup.startingActiveServer.reactorConnectInfo.rsslConnectOptions.connectionInfo.unified.address = “dataserver1”;
reactorWarmStandbyGroup.startingActiveServer.reactorConnectInfo.rsslConnectOptions.connectionInfo.unified.serviceName = “14002”;

//Configure a standby server
standbyServerInfo.reactorConnectInfo.rsslConnectOptions.connectionType = RSSL_CONN_TYPE_SOCKET;
standbyServerInfo.reactorConnectInfo.rsslConnectOptions.connectionInfo.unified.address = “dataserver2”;
standbyServerInfo.reactorConnectInfo.rsslConnectOptions.connectionInfo.unified.serviceName = “14002;

 

//Configure a warm standby group
reactorWarmStandbyGroup.standbyServerCount = 1;
reactorWarmStandbyGroup.standbyServerList = &standbyServerInfo; reactorWarmStandbyGroup.warmStandbyMode = RSSL_RWSB_MODE_SERVICE_BASED; reactorConnectOpts.warmStandbyGroupCount = 1;
reactorConnectOpts.reactorWarmStandbyGroupList = &reactorWarmStandbyGroup

ETA C WatchlistConsumer Example

The purpose of this example is to demonstrate consuming data from an ADS device, OMM Provider application, or Refinitiv Real-Time - Optimized using ValueAdd components.  It is a single-threaded client application. It leverages the consumer watchlist feature provided by the RsslReactor to provide recovery and aggregation of items. Since Refinitiv Real-Time C/C++ SDK 2.0.4.L1 (EMA/ETA 3.6.4.L1), this example supports a warm standby feature via the following parameters.

For instance, run the example with the following parameters.

    	
            WatchlistConsumer -startingHostName server1 -startingPort 14002 -standbyHostName server2 -standbyPort 14002 -warmStandbyMode service -s ELEKTRON_DD -mp JPY=
        
        
    

The example will use the service-based Warm Standby to connect to both active and standby servers, notify the servers about their roles in the warm standby group, send item requests to both servers and retrieve updates from the active server. When a connection to the active server or a service on the active server is down, the example will get updates from the standby server instead. For more information, please refer to the Introduction to Refinitiv Real-Time SDK Warm Standby Feature article.

Summary

The warm standby feature is now available in the Refinitiv Real-Time C/C++ SDK 2.0.4.L1. It is implemented in the ETA Reactor with watchlist enabled and made available in EMA via configurations. This feature provides a capability for consumers to failover from an active to one or more standby server(s) when the active server fails. Because the standby server is already aware of items subscribed by a consumer, during a failover, APIs don't need to re-subscribe items to the standby server. Therefore, Warm Standby can reduce overall recovery time and network traffic for item resubscriptions.

Refinitiv Real-Time C/C++ SDK 2.0.4.L1 provides both EMA C++ and ETA C examples that demonstrate the usage of the warm standby feature. The 470_MP_WarmStandby is an EMA example using the programmatic configuration to enable the warm standby feature and the WatchlistConsumer is an ETA example initializing the RsslReactorWarmStandbyGroup and RsslReactorWarmStandbyServerInfo data structures to enable the warm standby feature in the Value Add Watchlist layer. 

RTDS, RTSDK, EMA, ETA