Top Banner
SFC Developer’s Guide Release 4.5.X 23 November 2007 Doc ID: SDK453UMC++.070
423
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: sfc

SFC Developer’s Guide

Release 4.5.X

23 November 2007

Doc ID: SDK453UMC++.070

Page 2: sfc

Copyright © 1995, 1996, 1998, 2000-2007 Reuters Group plc. All rights reserved. Except as permitted by law no part of this document may be reproduced or transmitted by any process or means without the prior consent of Reuters Group plc.

Reuters, by publishing this document, does not guarantee that any information contained herein is and will remain accurate or that use of the information will ensure correct and faultless operation of the relevant service or equipment. Reuters, its agents and employees shall not be held liable to or through any user for any loss or damage whatsoever resulting from reliance on the information contained herein.

This document refers to the products and trademarks of manufacturers. Acknowledgment is made of all trademarks, registered trademarks and trading names that are referred to in the text.

TIB is a registered trademark and TIBCO and TIBCO Rendezvous are trademarks of TIBCO Software Inc.

REUTERS, the Sphere Logo, Triarch, and Reuters SSL are trademarks of the Reuters Group of Companies round the world.

This SOFTWARE, including but not limited to, the code, screen, structure, sequence, and organization thereof, and DOCUMENTATION are protected by United States copyright laws and international treaty provisions.

This manual is subject to U.S. export regulations.

Page 3: sfc

TABLE OF CONTENTS

1 OVERVIEW 11.1 What are the System Foundation Classes? 11.2 Audience 11.3 Organization of the SFC Documents 11.4 Conventions 3

1.4.1 Typographic 31.4.2 Programming 31.4.3 Naming 4

1.5 The SFC Development Process and Change Management Policies 51.6 Scope and Availability 6

2 DESIGN PHILOSOPHY 72.1 Modeling Principles 72.2 Design by Contract 82.3 Component Design 92.4 Application Design 10

3 THE SFC APPLICATION FRAMEWORK 113.1 Market Data Items and Services 113.2 Market Data Clients 123.3 Application Structure 12

3.3.1 Data and State Events 123.3.2 System Events 13

3.4 Threading and Exceptions 14

4 SFC MODELS 154.1 Record Subscription 15

4.1.1 Overview 154.1.1.1 Record Items 154.1.1.2 Real-time Records 164.1.1.3 Snapshot Records 164.1.1.4 Record Chains 174.1.1.5 Record Services 174.1.1.6 Record Service Pools 18

SFC Developer’s Guide iii

Page 4: sfc

Contents

4.1.1.7 Client Classes 194.1.2 Design 19

4.1.2.1 Real-time Record State 194.1.2.2 Snapshot Record State 224.1.2.3 Record Chain State 244.1.2.4 Service State 284.1.2.5 Record Client Management 294.1.2.6 Record Clients 314.1.2.7 Access to Fields 334.1.2.8 Field Updates 34

4.1.3 Implementation 354.1.3.1 Multiple Services 36

4.1.4 Class Summaries 364.1.4.1 Real-time Record Class Summary 374.1.4.2 Snapshot Record Class Summary 384.1.4.3 Record Chain Class Summary 394.1.4.4 Summary of Other Classes in the Record Cluster 39

4.1.5 Examples 404.1.6 Record Snapshot Client 41

4.1.6.1 Declaration of RecordSnapshotClient 424.1.6.2 Definition of RecordSnapshotClient 434.1.6.3 RecSnap Application 46

4.1.7 Real-time Record Client 474.1.7.1 Declaration of RecordUpdateClient 484.1.7.2 Definition of RecordUpdateClient 494.1.7.3 RecUpd Application 52

4.1.8 Field Client 534.1.9 Pool Client 53

4.1.9.1 Declaration for TickerMonitor (tickmon.h) 534.1.9.2 Definition of TickerMonitor (tickmon.C) 55

4.1.10 Chain Client 584.1.10.1 ChainElementRecordClient 59

4.2 Record Publication 614.2.1 Overview 61

4.2.1.1 Published Records 61

SFC Developer’s Guide iv

Page 5: sfc

Contents

4.2.1.2 Publishing Service 624.2.2 Design 63

4.2.2.1 Record Creation 634.2.2.2 Record State Diagram 654.2.2.3 Record State Change Events 664.2.2.4 Record Data Change Events 684.2.2.5 Record Initialization 694.2.2.6 Updating Fields in a Published Record 714.2.2.7 Changing Record State 724.2.2.8 Resynchronizing Record Data 734.2.2.9 Access to Published Records 734.2.2.10 Publishing Service State Changes 744.2.2.11 Publishing Entitlement Data 774.2.2.12 Managing Record Resources 79

4.2.3 Class Summary 804.2.4 Implementation 82

4.2.4.1 SSL Publishing Service 834.2.4.2 TIB Publishing Service 854.2.4.3 In-Process RTRRTRecordService Publisher 86

4.2.5 Examples 874.2.6 Simulator Program 90

4.2.6.1 Requirements 904.2.6.2 Design and Implementation 914.2.6.3 SimulatedService Class Declaration 924.2.6.4 SimulatedService Class Definition 934.2.6.5 FullCacheSimulatedService Class 954.2.6.6 SimulatedRecord Publisher Class Declaration 974.2.6.7 SimulatedRecord Class Definition 994.2.6.8 Creating an Application 111

4.2.7 Gateway Example 1184.2.7.1 Requirements 1184.2.7.2 Design and Implementation 1184.2.7.3 GatewayService Class Declaration 1194.2.7.4 GatewayService Class Definition 1214.2.7.5 SinkDrivenGatewayService Class Declaration 124

SFC Developer’s Guide v

Page 6: sfc

Contents

4.2.7.6 SinkDrivenGatewayService Class Definition 1254.2.7.7 SourceDrivenGatewayService Class Declaration 1274.2.7.8 SourceDrivenGatewayService Class Definition 1284.2.7.9 GatewayRecord Class Declaration 1304.2.7.10 GatewayRecord Class Definition 132

4.3 Page Subscription 1414.3.1 Overview 141

4.3.1.1 Pages 1414.3.1.2 Logical Pages 1414.3.1.3 Attributes 1424.3.1.4 Services and Service Pools 143

4.3.2 Design 1434.3.2.1 Page State 1434.3.2.2 Service State 144

4.3.3 Class Summary 1444.3.4 Implementation 146

4.3.4.1 Character Sets 1464.3.4.2 Attribute Mapping 1464.3.4.3 Configuration 1474.3.4.4 Multiple Services 147

4.3.5 Examples 1474.3.6 Page Client 148

4.3.6.1 Declaration of PageUpdClient (pageupdclient.h) 1494.3.6.2 Definition of PageUpdClient (pageupdclient.C) 1504.3.6.3 Creating Page Service and PageUpdClient 152

4.3.7 Region Client 1534.3.7.1 Definition of RegionUpdClient (regionupdclient.C) 153

4.3.8 Attribute Examples 1544.4 Page Stream Subscription 156

4.4.1 Overview 1564.4.1.1 Page Streams 1564.4.1.2 Services 1564.4.1.3 Service Pools 157

4.4.2 Design 1574.4.2.1 Page State 157

SFC Developer’s Guide vi

Page 7: sfc

Contents

4.4.2.2 Service State 1584.4.3 Class Summary 1584.4.4 Implementation 1594.4.5 Examples 1594.4.6 Example Class — Simple Page Client 160

4.4.6.1 Declaration of AnsiPageSnapshotClient (ansipagesnapclient.h) 1614.4.6.2 Definition of AnsiPageSnapshotClient (ansipagesnapclient.C) 162

4.4.7 Example Application — ANSI Page Snapshot 1654.4.8 Example Class — ANSI Page Updates 167

4.4.8.1 Declaration of AnsiPageUpdClient (ansipageupdclient.h) 1674.4.8.2 Definition of AnsiPageUpdClient (pageupdclient.C) 169

4.5 Time-Series 1724.5.1 Overview 172

4.5.1.1 Time-Series 1724.5.1.2 Time-Series Services 1734.5.1.3 Simple Series 173

4.5.2 Time-Series State Diagram 1734.5.3 Class Summary 1754.5.4 Implementation 176

4.5.4.1 Multiple Services 1774.5.5 Examples 1774.5.6 TSDump Example 178

4.5.6.1 Declaration of TSClientByCount (tsbycount.h) 1794.5.6.2 Definition of TSClientByCount (tsbycount.C) 1804.5.6.3 Example Application — Time-Series 1824.5.6.4 Example Code — ostream Output Methods 184

4.5.7 TSDates Example 1864.5.7.1 Declaration of TSClientByDate (tsbydate.h) 1864.5.7.2 Definition of TSClientByDate (tsbydate.C) 187

4.5.8 TSAvg Example 1894.5.8.1 Declaration of SimpleSeriesClient (simpleclient.h) 1904.5.8.2 Definition of SimpleSeriesClient (simpleclient.C) 191

4.6 Inserts 1934.6.1 Overview 1934.6.2 Insert Items 193

SFC Developer’s Guide vii

Page 8: sfc

Contents

4.6.3 Insert Services 1944.6.3.1 Insert Service Pools 194

4.6.4 Insert Request Server 1944.6.5 Example Class — Insert Server 195

4.6.5.1 Creating an Application 1954.6.5.2 Example Class — Insert Client 1964.6.5.3 Declaration for SimpleInsertExample (siminsrt.h) 1964.6.5.4 Definition for SimpleInsertExample (siminsrt.C) 198

4.6.6 Example Application — Inserts 2014.7 Session 203

4.7.1 Message Session 2034.7.1.1 The Model 2034.7.1.2 Message Session Abstraction 204

4.7.2 Example — Simple Message Session Clients 2054.7.2.1 Basic Requirements for Reply Class 2054.7.2.2 Declaration for Reply (reply.h) 2064.7.2.3 Definition for Reply (reply.C) 207

4.7.3 Example — Another Simple Message Session Client 2114.7.3.1 Declaration for Request (request.h) 2114.7.3.2 Definition for Request (request.C) 213

4.7.4 TCP/IP Socket Implementation of Message Session 2174.7.4.1 The Model 2174.7.4.2 TCP Session Server Event Client Types 218

4.7.5 Example — A Simple TCP Session Server Client 2194.7.5.1 Declaration for Reply Server (replysvr.h) 2194.7.5.2 Definition for Reply Server (replysvr.C) 221

4.7.6 Example — A Simple Application Using ReplyServer 2224.7.7 Example — A Simple Application Using a TCP Client Session 223

4.8 Support 2264.8.1 Connection 226

4.8.1.1 Overview 2264.8.1.2 Implementation 2274.8.1.3 Examples 227

4.8.2 Service Pool Factory 2284.8.2.1 Overview 228

SFC Developer’s Guide viii

Page 9: sfc

Contents

4.8.2.2 Implementation 2294.8.2.3 Examples 229

4.8.3 Event Loop 2354.8.3.1 I/O Events 2364.8.3.2 Timer Events 2364.8.3.3 Custom Event Loop 237

4.8.4 Example — I/O and Timing 2374.8.4.1 Declaration of IOTimerClient (iotimerclient.h) 2384.8.4.2 Definition of IOTimerClient (iotimerclient.C) 2394.8.4.3 Example Application - Select based (selecttest.C) 2404.8.4.4 Example Application - Xt based (xttest.C) 2414.8.4.5 Example Application - XView based (xvtest.C) 243

4.8.5 Configuration 2444.8.5.1 Overview 2444.8.5.2 Assigning Class Identifiers 2454.8.5.3 Assigning Instance Identifiers 2464.8.5.4 An Implementation Using X-Window Resource Files 2474.8.5.5 RTRXFileDb Example 2474.8.5.6 An Implementation Using the Microsoft Windows NT Registry 2494.8.5.7 RTRRegistryDb Example 2504.8.5.8 Global Access using RTRConfig 252

4.8.6 Event Logging 2534.8.6.1 Overview 2534.8.6.2 Implementation Classes 2544.8.6.3 Simple Example 2544.8.6.4 Configuration Examples 255

4.8.7 Command Line 2574.8.7.1 Overview 2574.8.7.2 Usage 258

4.8.8 Class Summary 2594.8.8.1 Connection 2594.8.8.2 Service Pool Factory 2604.8.8.3 Control Loop 2604.8.8.4 Configuration 2614.8.8.5 Event Logging 262

SFC Developer’s Guide ix

Page 10: sfc

Contents

4.8.8.6 Command Line 2624.8.8.7 International Characters 263

5 SFC IMPLEMENTATION DETAILS 2645.1 SSL and TIB Implementations 2645.2 Implementation Classes 2655.3 Entitlements 266

5.3.1 Supported Configurations 2675.3.2 Enabling Data Entitlements in SFC 2685.3.3 Setting the Username 2705.3.4 Publishing DACS Access Locks 2725.3.5 DACS Implementation Details 273

5.3.5.1 DACS Thread Aware Option 2755.3.6 Entitlements Configuration 276

5.4 Performance Tuning and Tracing 2785.4.1 General Guidelines 278

5.4.1.1 Use Libraries Without Assertion 2785.4.1.2 Disable Tracing 278

5.4.2 Optimizing Code 2795.4.2.1 Accessing a Market Data Item from a Service 2795.4.2.2 Accessing a Field from a Record 2805.4.2.3 Setting the Contents of a Field 2805.4.2.4 Sending an Image or an Update 282

5.4.3 Reducing Memory Usage 2825.4.3.1 Use SFC’s Cache 2825.4.3.2 Reducing Consumer Memory 2835.4.3.3 Reducing Publisher Memory 283

5.4.4 Request Queueing and Timing 2835.4.4.1 Request Queue 2845.4.4.2 Request Timing 2855.4.4.3 Configuration 285

5.4.5 Image Publishing 2865.4.5.1 Relationship between SFC and Source Distributor Cache Size 2865.4.5.2 Source-Driven Publishers 2875.4.5.3 Image Pacing 287

SFC Developer’s Guide x

Page 11: sfc

Contents

5.4.5.4 Performance and Record Templates 2885.4.6 Tracing 288

5.4.6.1 RMDS/TIB/SSL Publishing and RMDS/TIB Subscription 2885.4.6.2 SSL Subscription 289

5.4.7 Low-level Tracing and Error Messages 2895.5 Implementation Issues 291

5.5.1 Cross-infrastructure Compatibility 2915.5.2 Data Format 292

5.5.2.1 Enumerations 2935.5.2.2 Hint 296

5.5.3 Record Templates 3005.5.4 Data Dictionary 301

5.5.4.1 Sharing a Data Dictionary 3025.5.4.2 Infrastructure Issues 3035.5.4.3 Examples 3045.5.4.4 Configuration 306

5.5.5 Data and Connection Status 3075.5.5.1 Data Status with TIC and RTIC 3075.5.5.2 Rendezvous Advisory Messages 3085.5.5.3 SSL Warning Messages 3095.5.5.4 Status Event Normalization 310

5.5.6 Discovery 3105.5.6.1 Service Pool Factory 3105.5.6.2 Service Provider Discovery 311

5.5.7 Market Data Item Names and TIB Subject Names 3125.5.7.1 RIC to Subject Mapping 3145.5.7.2 Default Customizers 3165.5.7.3 Setting defaultSector to "." 3175.5.7.4 Overriding the TIB Customizer 3185.5.7.5 Next and Previous Page Names 3205.5.7.6 News Headlines 3205.5.7.7 Configuration 321

5.5.8 Page Services 3225.5.8.1 Page Records 3225.5.8.2 Effects Page Attribute Encoding 323

SFC Developer’s Guide xi

Page 12: sfc

Contents

5.5.8.3 ANSI Page Sizes 3235.5.9 Inserts and Contributions 324

5.5.9.1 Inserts and Triarch 3245.5.9.2 Inserts and RMDS (SASS3) 3245.5.9.3 Inserts and Classic TIB (SASS2 and SASS3) 324

5.5.10 Connection Parameters 3255.5.10.1 TIB 3255.5.10.2 SSL 327

5.5.11 Using Rendezvous 6 Library with the SFC 3285.5.12 Using Rendezvous 5 Library with the SFC 328

5.6 Configuration 3305.6.1 SSL Library Configuration 3305.6.2 SFC Configuration Summary 330

APPENDIX A: GLOSSARY 339

APPENDIX B: TRIARCH INFRASTRUCTURE 348B.1 Overview 348B.2 The SSL Interface 348B.3 SSL Sink Components 350

B.3.1 The Sink Application 350B.3.2 Sink Distributor 351

B.4 Design Goals and System Features 352B.4.1 Triarch System Design Goals 352B.4.2 Reliable Data Communications 352B.4.3 Flexibility and Scalability 353B.4.4 Optimal Resource Usage 353B.4.5 Fault Tolerance and Resiliency 354B.4.6 Single Item Open Request 355B.4.7 Management and Monitoring of Status 355B.4.8 Data Access Control 355

B.5 Request Routing and Resource Optimization 355B.5.1 Basic Request Routing without the Optional Service Distributor 355B.5.2 Full Resource Management and Request Routing with the

Service Distributor 358

SFC Developer’s Guide xii

Page 13: sfc

Contents

B.5.3 System Resiliency (“Failover”) 359B.6 SSL Library Configuration 361

B.6.1 Overview 361B.6.2 File Entry Rules and Formats 361

B.6.2.1 Location of the File 361B.6.2.2 Special Configuration File Entry Characters 361B.6.2.3 Configuration File Entry Format 361B.6.2.4 Binding of Configuration Entries 362B.6.2.5 Order of Precedence 363B.6.2.6 Updating the Configuration File 363

B.6.3 Valid Configuration File Parameters 363B.6.3.1 eventLogging 363B.6.3.2 functionLogging 364B.6.3.3 ipcConnectionTimeout 364B.6.3.4 ipcRoute 364B.6.3.5 ipcRouteName 365B.6.3.6 ipcServer 366B.6.3.7 maxMounts 366B.6.3.8 maxProcessBuffers 367B.6.3.9 maxRemountDelay 367B.6.3.10 maxUnconfirmedMsgs 367B.6.3.11 messageTracing 368B.6.3.12 messageTracingFlags 368B.6.3.13 minRemountDelay 368B.6.3.14 msgMountDelimiter 369B.6.3.15 numInputBuffers 369B.6.3.16 numOutputBuffers 369B.6.3.17 pingInterval 370B.6.3.18 serviceId 370B.6.3.19 snkResponseThrottle 371B.6.3.20 tcpQuickAck 371

B.6.4 Sample Configuration File 372

APPENDIX C: TIB INFRASTRUCTURE - SASS2 374C.1 Overview 374

SFC Developer’s Guide xiii

Page 14: sfc

Contents

C.2 Architecture 374C.2.1 TIC-based Publish/Subscribe 374C.2.2 Publishing to Support ciServer Subscribers 375C.2.3 Configuration 376

APPENDIX D: TIB INFRASTRUCTURE - SASS3 378D.1 Overview 378D.2 Architecture 378

D.2.1 TIB-Based Publisher 379D.2.2 TIB-Based Consumer 379

D.3 TMF 379D.4 Configuration 380

APPENDIX E: RMDS INFRASTRUCTURE 383E.1 Overview 383E.2 Architecture 383

E.2.1 SSL-Based Publisher 385E.2.2 TIB-Based Publisher 385E.2.3 TIB-Based Consumer 385

E.3 TMF 386E.4 Configuration 388

APPENDIX G: DACS LIBRARY FUNCTIONS 391G.1 DACS_CsLock() 391G.2 DACS_GetLock() 394G.3 DACS_CmpLock() 397G.4 DACS_perror() 399

SFC Developer’s Guide xiv

Page 15: sfc

1 OVERVIEW

1.1 What are the System Foundation Classes?

The System Foundation Class (SFC) Library is a collection of C++ classes which model the problem domain of financial information systems. The purpose of the SFC is to provide a suite of clearly defined, easy to use conceptual models, or abstractions. These abstractions represent the fundamental data types of interest to applications and also the infrastructure necessary to create both libraries and applications. By using SFC abstractions, applications can easily be written to work on more than one type of market data infrastructure.

NOTE: The TIB Legacy products are no longer supported by SFC v.4.5.1.L3 onwards.

1.2 Audience

Users of the SFC Library should have working knowledge of the C++ language and a general understanding of the concepts of object-oriented analysis and design.

Some useful books for learning C++ are:

[1] Object-Oriented Programming using C++ by Ira Pohl, ISBN #:0-8053-5382-8

[2] Effective C++ by Scott Meyers, ISBN #: 0-201-56364-9

[3] Advanced C++ - Programming Styles and Idioms by James O. Coplien, ISBN# 0-204-54855-0

Some useful books for learning object-orientated concepts are:

[4] Object-Oriented Software Construction by Bertrand Meyer, ISBN #: 0-13-629049-3

[5] Object-Oriented Analysis and Design by Grady Booch, ISBN #:0-8053-5340-2

[6] Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, ISBN #0-201-65561-2

1.3 Organization of the SFC Documents

The SFC documentation is divided into three manuals, this Developer’s Guide, a Migration Guide and a Reference Manual. The purpose of the Developer’s Guide is to provide an introduction to the SFC, to convey to the developer a sense of the philosophy behind the SFC, and to provide details on the primary SFC models.

SFC Developer’s Guide 1

Page 16: sfc

1 OVERVIEW

The remaining sections in this chapter discuss the conventions used in the manual, the SFC development process, and the current scope of the product.

The SFC Migration Guide details the differences between the SFC in SSL Developers Kit - Classic Edition 4.0.x and this release of SFC. It also describes what changes will need to be made when migrating programs.

Chapter 2 Design Philosophy Gives an overview of the object-oriented principles which have a bearing on library design and application structure.

Chapter 3 SFC Application Framework

Describes how these principles are applied in the SFC and introduces the SFC application framework.

Chapter 4 SFC Models Presents cluster overviews of the various SFC models. These overviews describe each of the primary models which comprise the SFC, identifying the essential classes and giving one or more examples of their usage.

Chapter 5 SFC Implementation Details

Discusses some of the differences between the infra-structures and details some important implementation and usage issues.

Appendix A Glossary Defines key terms used in this manual.

Appendix B Triarch Infrastructure Provides overview of Triarch/SSL infrastructure.

Appendix C TIB Infrastructure - SASS2 Provides overview of TIB infrastructure configured to use SASS2 protocol..

Appendix D TIB Infrastructure - SASS3 Provides overview of TIB infrastructure configured to use SASS3 protocol.

Appendix E RMDS Infrastructure Provides overview of RMDS infrastructure.

Appendix G DACS Library Functions Contains the DACS-specific function calls needed for DACS-compliant sources to perform subservice and compound permissioning.

SFC Developer’s Guide 2

Page 17: sfc

1 OVERVIEW

The SFC Reference Manual contains a class reference with detailed descriptions of each class in the SFC.

Also included with the SFC documentation is the Reuters Marketfeed Reference Manual which defines the syntax of those Marketfeed messages that may be sent by source applications or received by sink applications.

The SFC documentation does not cover the installation and configuration of the Triarch and RMDS market data infrastructures. Consult the product documentation of those infrastructures for information on market data components, including RVD, and Sink, Source and Service Distributors.

1.4 Conventions

1.4.1 Typographic• Important notes and tips are marked off with a box.

• Function names appear in a bold text font; e.g.

addClient()

• Samples of code appear in a typewriter font; e.g.

RTRRTField *trdprc1; RTRRTField *volume; char *value;

• File names appear in a bold italic font; e.g.

filename

1.4.2 Programming• All class names start with the letters “RTR” (for ReuTeR classes; e.g. RTRString).

NOTE: These tips can be helpful.

NOTE: Most files referenced in this document with a .C extension will have a .cpp extension in the win32 load.

SFC Developer’s Guide 3

Page 18: sfc

1 OVERVIEW

• All function names start with lower case letters, but subsequent words are capitalized (e.g., append() and lastString()).

• In order to make function names easy to understand, abbreviations are used sparingly. Some class names may seem rather long, but these names should be easier to understand than abbreviated names. On the technical side, it is important that class names do not clash with other class libraries or client defined classes. The combination of the “RTR” prefix and the long name format will avoid name collisions with classes from other libraries.

• To provide consistent, easy to learn class interfaces, function names are assigned such that functions are given the same name in different classes if they have the same use. Application developers will be able to understand new classes more quickly when the naming is consistent. For instance, the addClient() function is used throughout the real-time classes as the mechanism that allows components to register for events.

• The SFC uses a common boolean type RTRBOOL, which can have either RTRTRUE or RTRFALSE as its value.

• Where class methods return a pointer, the return value may be null. In circumstances where returned values will never be null, an object reference will be returned.

• The SFC uses the following memory management guideline: “If you allocated the object, you delete it. If you didn’t allocate the object, don’t delete it.” Any exceptions to the guideline will be explicitly highlighted in the appropriate section(s) of the SFC Reference Manual. When possible, objects should be deleted in the reverse order from which they were allocated.

1.4.3 NamingSFC originally only included an implementation for the Triarch (SSL) infrastructure. While the SFC name originates from SSL Foundation Classes, the core part of SFC, the abstract models, is generic for any market data infrastructure. So even though SFC now includes a TIB implementation for TIC-based TIB and Reuters Market Data System (RMDS) infrastructures, the name “SFC” applies to the abstract models of both implementations.

The class names for Triarch and RMDS (P2PS, MDH) implementation included “SSL” and “Default.” These classes retain those names for backwards compatibility. The class names for the TIB implementation include “TIB.” Through the rest of this document, “SSL” refers to the implementation for the Triarch infrastructure and RMDS (P2PS, MDH), and “TIB” refers to the implementation for the RTIC-based RMDS infrastructure. “TSA” is used in implementations that work only with the RMDS Distribution Layer.

SFC Developer’s Guide 4

Page 19: sfc

1 OVERVIEW

SFC’s TIB implementation should be used when consuming data from RMDS. Both the SSL and the TIB record publishing implementations can be used with an RMDS infrastructure. The TSA insert implementation can be used to contribute to an RMDS infrastructure. See Figure E.1 for more information.

The TIB implementation is designed to work with TIBCO Rendezvous, so it is used with the Rendezvous Distribution Layer of RMDS. However, due to subtle differences in the infrastructures, SFC must be told which infrastructure it is using. See section 4.8.1 and section 4.8.2 for information on how to do this.

1.5 The SFC Development Process and Change Management Policies

SFC models and classes are developed under the assumption that they are not correctly defined until proven useful in practical applications. Development is based on an iterative life-cycle. Validation of a new model requires both multiple uses of the library and multiple implementations. The latter ensures that the abstract interfaces are sufficiently independent of implementation details. The former ensures that the library is useful as well as abstract. Not all implementations which result from this process are part of the delivered product.

Often, much of the required iteration is the result of internal usage. However, it is usually the case that external clients provide the final validation of a new library component prior to release of the product. Several of the models in the current product have been through several generations, others are much newer.

Users of the SFC should be prepared for some degree of change especially when using the newer models. Every effort is made to ensure that, where possible, changes are backwards compatible with existing software, but such compatibility is not always possible. When the interface of a model changes, its old methods are marked “OBSOLETE.” These methods could be obsolete because they did not function correctly in all circumstances or just because the naming has been changed for model consistency. In the later case, the obsolete methods may still be used in legacy code. To ensure backwards compatibility, they remain implemented and should be implemented in new subclasses.

NOTES:

• When this document, the SFC Reference Manual, or the example programs refer to “TSA” (Trading Solution Architecture) they are referring to RMDS. In that context, the terms TSA and RMDS are interchangeable.

• The TIB implementation is designed to work with the RTIC-based RMDS infrastructure.

SFC Developer’s Guide 5

Page 20: sfc

1 OVERVIEW

Users of the SFC are strongly encouraged to provide feedback on both the conceptual models and the implementation.

1.6 Scope and Availability

Currently, the SFC provides abstractions for:

• subscribing to and publishing real-time record data

• subscribing to real-time page data

• retrieving historical (time-series) data

• contributions

• session-based communication

• various supporting models, including: the application control loop, configuration, event logging, service pool management, and peer-to-peer interprocess communication facilities.

New models will be added in the future.

The SFC is available on Win32 and Solaris. Additional platforms will be supported on the basis of demand. Please contact your Reuters representative for exact details on current availability.

SFC Developer’s Guide 6

Page 21: sfc

2 DESIGN PHILOSOPHY

2.1 Modeling Principles

The SFC Library is based on a conceptual model of the problem domain which comprises financial market data.

The purpose of developing an abstract model is to ensure that software components are properly isolated from non-essential characteristics of their suppliers. The effect of this approach is to de-couple the various parts of an application or system and provide simpler, more intuitive programmatic interfaces. In practice, it also means that components can be more easily maintained (they can be re-worked with no impact on other parts of the system), and they can also be readily exchanged with “like” components making systems more adaptable to changing requirements.

Effective models provide abstraction and encapsulation, and exhibit modularity. Booch [5] defines these terms as follows:

Abstraction - “An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of object and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer.”

Encapsulation - “Encapsulation is the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation.”

Modularity - “Modularity is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules.”

How is a model developed? Development of a model starts with an analysis of the problem domain. If expertise is not available, knowledge must be gained through experimentation. Regardless of the technique used, analysis yields a complete theoretical model of the components to be found in the problem domain and is represented by a set of abstract data types.

Conceptual models are rarely correct the first time. Through trial and error a model evolves over time, gradually becoming stable. Stability is achieved through practical application of the model in building systems, both through using the interface defined by the model and by implementing the data types required by the model.

A model can be defined by English text (or some other natural language mechanism), by a formal modeling language, by a programmatic interface, or by some combination of these techniques. All of these techniques have advantages and disadvantages. What is important is to have a comprehensive description of the model which can then be used to provide programmatic implementations.

SFC Developer’s Guide 7

Page 22: sfc

2 DESIGN PHILOSOPHY

Ultimately, application programming interfaces (APIs) are required. When using an object-oriented programming environment, the result is a set of class libraries. A given model may have more than one implementation. The models which comprise a class library must be modular in their design and implementation. That is, it must be possible to add and remove both models and implementations thereof. This allows the scope of the library to grow and change over time in a manageable fashion.

Why go to all the trouble of developing abstract data types, iterating through prototypes, and building components? Clearly, the production of a reusable component requires high standards of design and implementation, and, perhaps, imposes restrictions on the way in which software can be implemented.

Perhaps the most important benefit of building components is the flexibility it affords. Components can be swapped out, enhanced, maintained, and interchanged. Monolithic software systems inhibit maintenance and enhancement.

Additionally, a well conceived conceptual model affords a much friendlier, more intuitive programming environment, letting programmers concentrate on problems specific to their particular domain rather than having to master the details of many different domains and implementations.

2.2 Design by Contract

In many of the class function descriptions, you will notice the terms “REQUIRE” and/or “ENSURE” along with some conditional code. These statements, or assertions, suggest a contract between the client (caller) and supplier such that if the client fulfills the required preconditions, then the supplier will ensure that the postconditions will be true upon return from the function.

This method of programming is more commonly known as “design by contract” and is used not only in the abstract interfaces described in the manuals but is also used extensively throughout the SFC implementation.

Assertions are programmed into the library code using macros that are based on the standard “assert” mechanism. The SFC distribution provides two versions of each library—one with assertions, one without. Client programmers have the option to link their applications with either version. There is some performance penalty for using the version with assertions. Typically users of the library will link with assertions while developing and debugging their code, then use the non-assertion version for their finished product.

If an assertion statement fails during execution, the program will exit and print out the condition that failed, the name of the file the assertion failed in and the line number of the assertion in the file. This typically provides a good starting point for tracing back to determine where the problem originated.

SFC Developer’s Guide 8

Page 23: sfc

2 DESIGN PHILOSOPHY

The following is an example of the use of assertions:

RTRBOOL hasClient(RTRRTRecordClient&) const; Is the given client registered to receive events?

void addClient(RTRRTRecordClient& newClient); Register the given client to receive events. !hasClient(newClient) hasClient(newClient)

In this example, the addClient() is used to register a new client. The assertions explain that a given client may register only once (REQUIRE: !hasClient) and that following the call to addClient(), the given client will be registered (ENSURE: hasClient).

One more example:

RTRBOOL hasFieldByname(const char *name) const; Does this record contain a field with the given name?

RTRRTField *fieldByName(const char *name) const; The field with the given name. (result == 0) == (hasFieldByName(name)) (result == 0) || result->name() == name

In the postconditions, the term “result” means the value returned from the function. Therefore, the assertions explain that if the record contains the field with the given name, fieldByName() will return a pointer to that field, otherwise, it will return a null pointer.

2.3 Component Design

Components are pieces of software which are designed to be reusable. As such, they must be independent of context. In other words, components must be independent of application specific assumptions. In particular, components should rely on the abstract interfaces of other software suppliers and be as independent as possible of implementation details.

In general, components should be single purpose. This means that they tend to be simple and modular. The SFC market data abstractions and other models support this philosophy and are themselves implemented in accordance with it.

One example of a component which might be constructed using the SFC is a quote display. An application-independent quote display component would use the abstract interfaces to the SFC real-

SFC Developer’s Guide 9

Page 24: sfc

2 DESIGN PHILOSOPHY

time record model to retrieve a record item. It would need access to formatting information specifying which fields to display, where to display them, and which presentation attributes to use in doing so. Ideally, this component is independent of the particular user interface being used and also independent of the display technology.

Another example is a limit minding component which monitors fields from a record and tests whether those fields exceed predefined limits. Ideally, this kind of capability is implemented so that it is independent of display and user interface.

2.4 Application Design

Applications are collections of components which together provide the required functionality. Application designers decide which components are necessary and also, either at compile time or link time, which implementations of abstract models to use. In contrast to components, which are implementation independent, applications tend to be implementation specific.

SFC Developer’s Guide 10

Page 25: sfc

3 THE SFC APPLICATION FRAMEWORK

3.1 Market Data Items and Services

Financial information systems represent a complex problem domain. Applications in this domain must potentially process many different types of market data. The data is often available in several different formats. Not only are there many types and formats of data, there are also many data suppliers. The semantics and format of the raw data must be understood by the application developer.

In addition, applications often must operate as part of a distributed system. This further increases the complexity and means that the developer must learn network protocols or the APIs which provide access to network based services.

The purpose of most applications developed for this environment is to manipulate and/or present the underlying market data. The purpose of the SFC is to make this task easier by providing intuitive, easy-to-use, and implementation-independent interfaces to market data.

The SFC does this by providing a number of different models corresponding to the fundamental data types of interest to applications. These models capture semantics of the underlying data types but shield applications from the details of retrieving the data.

The primary component of SFC market data models is the data item. Data items correspond to the underlying units of financial information which are of interest to application programmers. Typical SFC applications are concerned primarily with abstract representations of item state, events, and data content, rather than implementation-specific issues such as network messages and encoding syntax.

Data items represent a particular financial instrument or collection of data, and are retrieved from a service (e.g., Reuters Selectserver) by a name (e.g., DEM=) which is unique in the context of that service.

• Items are typically pages or records, but the system does not preclude other data types.

• Items may be in different states (e.g., OK, STALE) and may undergo changes in state. The state of a data item from the perspective of a particular sink application can be thought of as a logical connection.

• Items may have priority relative to other items.

• Items may be permissioned to control access.

A secondary concept in the SFC market data models is the provider of data items, usually referred to as a service. Services are the abstraction which encompass the distributed nature of the problem

SFC Developer’s Guide 11

Page 26: sfc

3 THE SFC APPLICATION FRAMEWORK

domain. Distributed systems often offer multiple services or data providers. Again, the purpose of the service abstraction is to shield applications from the details of system implementation.

• Services are uniquely identified by name.

• Services have state and undergo state changes which may be indicated by explanatory textual information.

• Services may provide alerts, e.g., data items worthy of special notice.

• Services may be permissioned to control access to their data.

3.2 Market Data Clients

Application developers provide non-SFC components of an application. These can be loosely referred to as market data clients, or just clients. Clients are the consumers of the services offered by the SFC market data models.

Clients use market data, process data and state events, and provide all the application specific processing within an application.

3.3 Application Structure

3.3.1 Data and State EventsIn general, the SFC employs an event-driven paradigm. SFC models encompass real-time data which results in asynchronous events that must be processed by both the library and the client components. Other events may be generated by implementation-specific components within the library.

Where fundamental to the problem domain, events are incorporated into the abstract models provided by the SFC. There are several event generating components within the various SFC models. The events which can be generated by a given type of component and the semantics of those events are defined by the particular abstraction which that component represents.

As recipients of market data related events, clients must provide the interface by which events are propagated through the application. This is accomplished by means of abstract base classes and the use of the C++ virtual function mechanism. For each type of event generating component, there is an abstract base class which defines the clients eligible to receive those events. These base classes declare public virtual functions which are invoked by the event generating components. Developers of new components create specializations of the client base classes. These specialized classes provide

SFC Developer’s Guide 12

Page 27: sfc

3 THE SFC APPLICATION FRAMEWORK

application specific processing of the events generated by the SFC Libraries. An application consists of one or more instances of various specialized client types which register with instances of market data items to receive events relating to those items.

Clients register to receive events with individual data items (or other event generating components) in which they have interest. The implementation of the model is responsible for managing this client registration and for delivering the appropriate events to registered clients.

3.3.2 System EventsThe SFC Library provides a large number of building blocks, or components, which can be used as the basis for creating additional components and, ultimately, applications. Cooperation among SFC Library components and other parts of an application is essential. In particular, it is important that components which need access to timers and I/O do so in a “fair” manner. In general, event driven systems solve this problem by providing a control loop which dispatches events as required.

Because the SFC components must accommodate many different kinds of application environments, they interact with the control loop through a generic interface, an abstraction. Application designers are free to choose whatever kind of control loop is most appropriate for their application. All that is required by the SFC is that the designer provide a “glue” layer between the SFC interface and the control loop implementation. The SFC makes this easier by providing a number of pre-defined glue layers for the standard control loops provided by most GUI development environments. In addition, the SFC provides a control loop implementation based on the select() system call. It is useful for non-GUI applications. As an alternative, application developers can create their own implementations and glue.

The SFC abstraction for a control loop is represented by a C++ class called RTREventNotifier. This class is described in more detail in section 4.8.3 and in the alphabetical class listing. Most of the example applications in this manual make use of an RTREventNotifier implementation called RTRSelectNotifier. It is an implementation (descendant) of RTREventNotifier which uses a select() system call as the basis for a control loop. It is important to note that the components used in the example applications will work just as well in other application contexts and with other implementations of RTREventNotifier.

In addition to the RTRSelectNotifier, the SFC provides implementations of RTREventNotifier for X-Window environments (RTRXtNotifier and RTRXViewNotifer) and for MS Windows (RTRWindowsNotifier).

Use of the SFC Library does not mandate that application designers use the RTREventNotifier interface. They may prefer to write components which interact directly with the control loop

SFC Developer’s Guide 13

Page 28: sfc

3 THE SFC APPLICATION FRAMEWORK

implementation of their choice. Where portability is of concern, designers may find that they can use the RTREventNotifier interface to their advantage.

3.4 Threading and Exceptions

SFC is not designed to work in a multi-threaded environment. Most threaded applications can be re-written to use timers, such as the RTRTimerCmd. However if an SFC application requires thread, make sure:

• only one thread ever accesses SFC

OR

• all uses of SFC objects should be locked with a single external lock to ensure that SFC is only accessed by one thread at at time.

Also, SFC does not use exceptions and is not exception-aware. If an SFC application uses exceptions, make sure that all SFC objects are cleaned up properly in the reverse order from which they were created. Also, throwing an exception from an SFC event call-back should be avoided.

SFC Developer’s Guide 14

Page 29: sfc

4 SFC MODELS

4.1 Record Subscription

4.1.1 Overview

4.1.1.1 Record ItemsA record represents an item of market data as a collection of fields. Record clients are application components which are interested in the events associated with a particular record. This interest is expressed by the act of registering a client with a record.

The data represented by a record can be characterized by its condition. The condition of the data may affect the way in which it is used by a client. For example, if data is suspect or stale, a display application might indicate this by using a different color to display that data. Data condition is expressed in the model by state variables associated with a record. Changes in the condition of the data result in changes to record state.

Record data is represented by fields. A record is a collection of such fields, although not all records contain the same fields. The content of a record is determined by the underlying market data. For example, a record representing an equity instrument traded on an exchange will not contain the same fields as a record representing the spot market for a currency. Fields are unique within a record. I.e, no two fields in any given record will have the same identifier. Records provide both sequential (iterative) and random (keyed) access to their constituent fields, and support queries regarding the presence of fields within the record.

The set of field identifiers which might be found in a record is defined by the provider of that record. The set of all field definitions used by a provider of records (a service) is contained in a database associated with that service. In the SFC, field definitions are represented by the class RTRFidDefinition.

Each field has a value, the semantics of which is determined by that field’s identifier. A field identifier has two forms:

• an integer value (FID)

• a sequence of characters (name)

Associated with a given FID (or name) are, among other things, the type of field and its storage requirements. Together, the identifier, type, and storage requirements of a field comprise a field

SFC Developer’s Guide 15

Page 30: sfc

4.1 SFC MODELS

definition. The identifier also implicitly defines the semantics of the field. For example there are many different kinds of price fields, but a BID price and an ASK price have very different semantics.

Clients may use fields in their "generic" form or interpret their contents according to their type. For example, while a date can be represented as the string "MAR 11 1994", it may be useful to use the numeric equivalent where day=11, month=3, year=1994. A price may be represented as the string "29 2/8" or as the floating point value 29.25. Type-specific fields are represented in the SFC for alphanumeric, date-time, enumerated, integer, numeric, and price values. These type-specific fields provide the capability to interpret the string value according to the rules associated with its particular type.

4.1.1.2 Real-time RecordsThe value of individual fields within a record may change over time. When a record can change over time, it is considered "real-time." Changes occur in aggregates which are known as updates or ticks. Updates occur for a number of different reasons. They constitute distinct events which must be conveyed to the "clients" of any given record. As with updates, record state changes are generally of interest to clients, requiring timely propagation of these events to individual clients of the record. The SFC class which represents real-time record items is RTRRTRecord. Real-time record clients are represented by the class RTRRTRecordClient.

The fields which comprise real-time records also have real-time characteristics, meaning that they change over time. Application components which are interested in the value of a field may also be interested in updates to the field's value. Fields are responsible for notifying clients of changes in the field's value and therefore provide mechanisms by which clients may register interest in field events. When the field's value changes, an event is sent to each of its clients. The base type for real-time fields in the SFC is the class RTRRTField.

4.1.1.3 Snapshot RecordsSometimes clients do not care if a record’s data updates or if its state changes. The client is only interested in non-updating data or a "snapshot" of updating data at one point in time. In this circumstance, record requests can be optimized and network bandwidth usage can be reduced by using the class RTRSnapshotRecord. Snapshot record clients are represented by the class RTRSnapshotRecordClient. The underlying data of snapshot records is never updated, so snapshot record clients will never receive update events.

The base type for fields in a snapshot record is RTRSnapshotField. Since snapshot fields never update, they do not accept clients.

SFC Developer’s Guide 16

Page 31: sfc

4.1 SFC MODELS

4.1.1.4 Record ChainsIn the IDN domain, some records are grouped together forming "chains" of records. Indexes (0#.FTSE, 0#.DJI) and most active volume lists (.AV.L, .AV.O) are two examples of where chains are used. A record chain is an abstract model for this kind of record collection.

A record chain is a sequential list of records. Chains are considered "real-time" in nature. The list of records may update or change in real-time. Specifically, a chain could re-sort causing a record to be moved up, down, or out of the list. Therefore chains are implemented on top of the real-time record model rather than the snapshot record model.

In the SFC, record chains are represented by the class RTRRecordChain. The names of individual positions in a chain are represented by the class RTRRecordChainElement. A record chain can notify its client when the chain has completely retrieved all of its elements. It also has events indicating errors and state changes. A record chain element can notify its client when it updates. Clients of record chains and record chain elements are represented by the classes RTRRecordChainClient and RTRRecordChainElementClient, respectively.

4.1.1.5 Record ServicesRecord services are an abstraction for providers of record items. While nothing in the previous description of records necessitates an associated service abstraction, the concept of a service is useful in providing practical implementations of the real-time record model. A record service provides access to records and is responsible for managing the allocation of resources (e.g., memory, I/O bandwidth, etc.) necessary to provide the underlying data. Resource allocation is based on the priority assigned to the record by all of the record’s clients.

Like records, record services exist in one of several states, where service state is essentially a global condition for all data provided by that service. For example, if a service is in a stale state, all data items provided by that service are stale. Services are responsible for notifying interested clients of changes in their state.

A record service will always provide access to a requested record. Where a service is unable (or unwilling) to provide data for a requested record, the record will be in an inactive state. For example, an application may request a record which does not exist in the implementation domain (i.e., there is

NOTE: Record chain elements correspond to positions in a chain, not records in a chain. If the val-ues in the third and fourth positions of a chain swap, chain element clients for the third and fourth chain elements will each receive an update event.

SFC Developer’s Guide 17

Page 32: sfc

4.1 SFC MODELS

no corresponding item of market data with the same name) or the application may not have permission to access the underlying data. The text of an inactive record explains the reason that data will not be provided. Once in an inactive state, a record will never transition to the active state; it is in an unrecoverable error state. Applications should not maintain references (pointers) to inactive items. This rule is based on practical considerations, e.g., memory management. When items are inactive, the resources they use (memory, etc.) are eligible to be reclaimed.

4.1.1.6 Record Service PoolsIdeally, there would only be a need for one instance of a real-time record service in an application. However, in many practical applications access to multiple services is required. Many distributed systems provide access to several different services. These services correspond to data services offered by different vendors or to local applications which publish data. These services may come and go over time. Usually the decision to use a given service is made by an administrator or a user.

The RTRRTRecordService is the abstract base class for providers of real-time record data. Often services are implemented as "proxies" for remote entities in a distributed system. For example, RTIC based services provide access to the services available on RMDS. Services could also be implemented to communicate directly with a datafeed, or they may be implemented locally. For example a record service could be implemented to take page oriented data and "shred" it into records for use within an application. An implementation of a RTRRTRecordService which is a simulator might extract data from files. Within a given application there may be more than one implementation of the RTRRTRecordService class. For example, RMDS-based services and a "shredder" service could coexist within the application.

How are services created and made available to other application components? The objective is to make as much of the application software as independent as possible of the service implementations and particularly the creation of services.

What is required is a mechanism that allows most of the application to be independent of the details of the service creation process. The record service pool, represented by the class RTRRTRecordServicePool, provides the necessary level of abstraction. It represents a set containing all available services and generates events corresponding to the "arrival" (and departure) of services. The contents of the pool can be accessed sequentially (by iteration) or randomly (by service name). Pool clients are represented by the class RTRRTRecordServicePoolClient.

The manner in which the pool gets populated is implementation specific. Ultimately, some part of the application creates services and puts them in the pool. This results in an event being propagated to interested clients from the pool. Clients may then obtain a reference to the new service.

SFC Developer’s Guide 18

Page 33: sfc

4.1 SFC MODELS

4.1.1.7 Client ClassesThe preceding description of record-oriented real-time data introduced several client classes (e.g., RTRRTRecordClient, RTRRTFieldClient, and RTRRTRecordServicePoolClient). These classes define the abstract types for those application components which wish to process the various market data related events generated by real-time records, services, and pools. In order to receive event notifications, application specific classes inherit from one or more of these client classes and define appropriate actions to be taken for each event of interest. All event generating classes in the real-time model provide addClient() and dropClient() methods, which allow clients of the appropriate type to register and un-register for events. Collectively, the behavior of the clients which comprise an application defines the functionality of that application.

Record chains and record chain elements are limited to one client per object. The client classes are RTRRecordChainClient and RTRRecordChainElementClient. Due to the one client limitation, RTRRecordChain and RTRRecordChainElement provide setClient() and clearClient() methods for registering and un-registering for events.

4.1.2 DesignThis section provides more detail concerning the analysis and design of the real-time record model. The purpose of this section is to show how the abstract analysis translates into specific class features. Not all features of all classes are described. Please refer to the SFC Reference Manual for full details.

4.1.2.1 Real-time Record StateRecord state is defined by the values of three record attributes: hasData, stale, and active. The four real-time record states are defined as follows:

State RecordAttributes Description

Active_noData hasData = False stale = True active = True

Records in this state cannot provide any fields. The initial "image" of the record is not yet available. Records in this state may transition to any of the other three states. Once out of this state, a record instance will never return to it.

Table 4.1: Record States

SFC Developer’s Guide 19

Page 34: sfc

4.1 SFC MODELS

State transitions are propagated to clients as events. The events triggered by state transitions are described as follows:

• Sync - This event indicates the availability of an initial "image". This event will only occur once for a given record instance. The event triggers a transition to either the Active_valid state or the Active_stale state. Record clients will receive a processRecordSync() event.

• Resync - This event indicates the availability of a subsequence "image". It also indicates a change in state between Active_stale and Active_valid. When a resync occurs, the state of the record must be examined. Record clients will receive a pair of events, processRecordResync() and processResyncComplete(), to indicate data change. In case there is a change in state, record clients will receive an additional event, processRecordStale() or processRecordNotStale() event to indicate a state change from Active_Valid to Active_Stale or Active_Stale to Active_Valid respectively.

• Stale - This event indicates a transition from the Active_valid state to the Active_stale state. Record clients will receive a processRecordStale() event.

• NotStale - This event indicates a transition from the Active_stale state to the Active_valid state. Record clients will receive a processRecordNotStale() event.

Active_valid hasData = Truestale = False active = True

Records in this state contain valid data. Records in this state may transition to the Active_stale state or to the Inactive state.

Active_stale hasData = Truestale = True active = True

Records in this state contain data which is may be out-of-date, i.e. it is stale. Stale records are in a recover-able error condition and will take all necessary steps to return to an Active_valid state.

Inactive hasData = don’t care stale = don’t care active = False

Records transition to this state when the service which created the given record is unable or unwilling to con-tinue providing access to the underlying data item. Once in this state, a record will never transition to another state.

State RecordAttributes Description

Table 4.1: Record States (Continued)

SFC Developer’s Guide 20

Page 35: sfc

4.1 SFC MODELS

• Inactive - This event indicates a transition to the Inactive state. Record clients will receive a processRecordInactive() event.

Record will also generate informational events when appropriate. Clients will receive a processRecordInfo() event. These events never indicate a change in record state.

Records have a text() method which provides a textual explanation of the current record state. Record clients are kept informed of progress by means of events which indicate that there is new textual data available concerning the state of the record.

Figure 4.1 shows the various real-time record states and state transitions.

Figure 4.1: Real-time Record States and Variables

Active_noData Active_valid

Active_staleInactive

Sync

Inactive

Inactive

InactiveStale

NotStale

(hasData = False, stale = True, active = True)Active_noData(hasData = True, stale = False, active = True)Active_valid(hasData = True, stale = True, active = True)Active_stale(hasData = XX, stale = XX, active = False)Inactive

Sync

Resync

Resync

Resync

SFC Developer’s Guide 21

Page 36: sfc

4.1 SFC MODELS

4.1.2.2 Snapshot Record StateNote that a snapshot record only receives a Sync or Inactive event. Immediately after a snapshot record receives a sync, the stale/valid state of the record cannot be determined. Therefore, it is always considered stale.

Snapshot record state is defined by the values of two attributes: hasData and active. The three snapshot record states are defined as follows:

State transitions are propagated to clients as events. Snapshot can only receive two event:

• Sync - This event indicates the availability of an initial "image". This event will only occur once for a given record instance. The event triggers a transition to the Active_stale state. Record clients will receive a processRecordSync() event.

State RecordAttributes Description

Active_noData hasData = False stale = True active = True

Records in this state cannot provide any fields. The initial "image" of the record is not yet available. Records in this state may transition to any of the other three states. Once out of this state, a record instance will never return to it.

Active_stale hasData = Truestale = True active = True

Records in this state contain data which is may be out-of-date, i.e. it is stale. Snapshots are always consid-ered stale because the data may have been updated immediately after the snapshot was received.

Inactive hasData = don’t care stale = don’t care active = False

Records transition to this state when the service which created the given record is unable or unwilling to con-tinue providing access to the underlying data item. Once in this state, a record will never transition to another state.

Table 4.2: Snapshot Record States

SFC Developer’s Guide 22

Page 37: sfc

4.1 SFC MODELS

• Inactive - This event indicates a transition to the Inactive state. Record clients will receive a processRecordInactive() event. Snapshot clients receive this event if the record does not exist or if the record object is deleted.

Figure 4.2 shows the various snapshot record states and state transitions.

Figure 4.2: Snapshot Record States and Variables

Active_noData

Active_stale

Inactive

Inactive

(hasData = False, stale = True, active = True)Active_noData

(hasData = True, stale = True, active = True)Active_stale(hasData = XX, stale = XX, active = False)Inactive

Sync

Inactive

SFC Developer’s Guide 23

Page 38: sfc

4.1 SFC MODELS

4.1.2.3 Record Chain StateRecord chain state is defined by four attributes: isValid, complete, stale, and error. The five record chain states are defined as follows:

State RecordAttributes Description

notComplete isValid = don’t care complete = False stale = don’t careerror = False

The chain has been requested. Nothing else is know about its validity or state yet.

Complete_stale isValid = Truecomplete = True stale = Trueerror = False

The chain is valid and complete, but one of the chain headers is currently stale.

Complete_notStale isValid = Truecomplete = True stale = Falseerror = False

The chain is valid, complete, and ready to be used.

Error isValid = don’t care complete = don’t care stale = don’t careerror = True

Some error occurred when processing one of the chain headers. This state could occur before a chain is complete if the last valid chain header points to a record that does not exist (e.g. if the NEXT_LR field of 1#.AV.O were set to 2#.AV.O, a non-existent RIC, the chain would go into the error state). This state could also occur after the chain is complete if any of the records that constitute chain headers become inactive for any reason.

Invalid isValid = False complete = False stale = don’t careerror = False

The RIC used for the chain name is a valid RIC, but it is not a chain header. Maybe the application should re-request the RIC as a regular record.

Table 4.3: Record Chain States

SFC Developer’s Guide 24

Page 39: sfc

4.1 SFC MODELS

State transitions are propagated to clients as events. Events that trigger state transitions are described as follows:

• Complete - This event indicates that all of the values currently available for the chain have been completely received. This event will only occur once for a given chain instance. The event triggers a transition from the notComplete state to either the Complete_stale or Complete_notStale state. The chain client will receive a processChainComplete() event.

• Error - This event indicates that some error occurred while processing one of the chain headers (e.g. 1#.DJI). The chain client will receive a processChainError() event. This event will only occur once for a given chain instance. If the chain’s count() is greater than zero, the current contents of the chain can still be used. If the client continues to use the chain, it should check to see if the chain resized.

• Stale - This event indicates a transition from the Complete_notStale state to the Complete_stale state. The chain client will receive a processChainStale() event.

• NotStale - This event indicates a transition from the Complete_stale state to the Complete_notStale state. The chain client will receive a processChainNotStale() event.

• Invalid - This event indicates a transition to the Invalid state. This event will occur if the requested chain is a valid record, but it does not include all of the required fields. The chain client will receive a processRecordInactive() event. This event will only occur once for a given chain instance.

A record chain is complete when its elements can be completely constructed. A record chain is invalid when the provided name is an available record, but that record is not a chain (e.g. IBM.N is requested as a chain). A record chain is in the error state if it could not be completely constructed or if one of its internal records (records that define the chain, not the chain elements’ records) becomes inactive. For example, if 1#.DJI were to become inactive, the chain client would receive a processChainError() event.

Chain client can receive additional events to indicate that the contents of the chain have changed.

• Partial - This event indicates that some elements have been added to the chain, but the chain is not yet complete. The chain client will receive a processChainPartial() event..This event is only received when the chain is in the notComplete state. It can be used by applications to proactively request records listed in a chain before the chain is complete.

• Resize - This event indicates that elements have been added to or removed from the chain. The chain client will receive a processChainResize() event. This event is only received when the chain is in the Complete_stale or Complete_notStale state. When this event is received, the chain

SFC Developer’s Guide 25

Page 40: sfc

4.1 SFC MODELS

client should also check to see if the chain moved between the Complete_stale and Complete_notStale states.

• UpdateComplete - This event indicates that a number of chain elements have changed but the change did not resize. The chain client will receive a processChainUpdateComplete() event. This event is only received when the chain is in the Complete_stale or Complete_notStale state. When this event is received, the chain client should also check to see if the chain moved between the Complete_stale and Complete_notStale states.

Figure 4.3 shows record chain states and events causing state transitions.

NOTE: Record chain elements are always added to and removed from the end of the chain. For example, if a value Y’ is inserted before the last value ’Z’ in the chain, the last chain element’s client will receive a ChainElementUpdate event for a change from ’Z’ to ’Y’. Then the chain client will receive a Resize event for 1 additional element. This element will contain the value ’Z’.

SFC Developer’s Guide 26

Page 41: sfc

4.1 SFC MODELS

Figure 4.3: Record Chain States and Variables

notComplete

Complete_notStaleComplete_stale

Error

Complete

NotStale

Stale

(isValid = XX, complete = False, stale = XX, error = False)notComplete(isValid = True, complete = True, stale = True, error = False)Complete_stale(isValid = True, complete = True, stale = False, error = False)Compete_notStale(isValid = XX, complete = XX, stale = XX, error = True)Error

Complete

InvalidInvalid

Error

ErrorError

(isValid = False, complete = False, stale = XX, error = False)Invalid

SFC Developer’s Guide 27

Page 42: sfc

4.1 SFC MODELS

4.1.2.4 Service StateThe state of services is determined by the value of two attributes: stale and active. The three services states are defined as follows:

State transitions are propagated to clients as events. The events triggered by state transitions are described as follows:

• Sync - This event indicates the service has been found and is ready to accept requests. Unlike the record sync event, this event can occur multiple times for a given service instance. However, it will never occur twice in a row. This event triggers a transition from the Stale state to the Ok state. Service clients will receive a processServiceSync() event.

State RecordAttributes Description

Stale stale = True active = True

The service is not available on the network. This state could be because the initial connection between the SFC application and the infrastructure has not been established, information from this service has not been retrieved from the infrastructure, or the service is sim-ply not available. Stale is a recoverable condition. Items may be requested from stale services, but they will remain stale until the service itself is no longer stale and can automatically request the items.

Ok stale = False active = True

The service has been found in the market data infra-structure and is ready to handle item requests.

Inactive stale = don’t care active = False

This state should never occur for services on a net-work because the application can never know if the service will recover sometime in the future. Services representing local publishers could go into this state because the application has control over the state of the local publisher. Services also go into this state right before their objects are destroyed.

Table 4.4: Service States

SFC Developer’s Guide 28

Page 43: sfc

4.1 SFC MODELS

• Stale - This event indicates a transition from the Ok state to the Stale state. Service clients will receive a processServiceStale() event.

• Inactive - This event indicates a transition to the Inactive state. Service clients will receive a processServiceInactive() event and should release all references to the service.

Services will also generate informational events when appropriate. Clients will receive a processServiceInfo() event. These events never indicate a change in the service’s state. Services have a text() method which provides a textual explanation of the current state of the service.

Figure 4.4 shows the various service states and state transitions.

Figure 4.4: Service States and Variables

4.1.2.5 Record Client ManagementRecords may have multiple clients, and those clients may be registered with multiple record items. In other words, there is n to n cardinality between record items and clients.

As an example, suppose an application needs the capability to display one or more individual records and also must provide limit minding capability. One possible solution entails designing two new client

Stale

Ok

Inactive

Inactive

(stale = True, active = True)Stale

(stale = False, active = True)Ok(stale = XX, active = False)Inactive

Sync

Inactive

Stale

SFC Developer’s Guide 29

Page 44: sfc

4.1 SFC MODELS

classes, i.e., specialized descendants of RTRRTRecordClient. The first, a "quote display" client is designed to display a single record. The second, a "limit minder" client, is designed to display the trade prices of one or more records. At run-time the application will consist of one or more quote display clients and a limit minding client. Figure 4.5 illustrates the run-time relationships which result when the application is displaying two records ("IBM.N" and "DEM=") and also performing limit minding on the same records. In this case, there are two record instances and three client instances, two of type "Quote Display" and one of type "Limit Minder". Each record has two clients, one each of type Quote Display and type Limit Minder. The single instance of Limit Minder is a client of two records; the instances of Quote Display are each clients of a single record.

Figure 4.5: Record and Client Run-time Relationships Example

In a typical application, these relationships are defined dynamically, i.e., on the basis of user input or other events, meaning that clients may be dynamically added (allocated) or removed (deleted) at any time.

The RTRRTRecord class defines three methods for "client management". They are:

void addClient(RTRRTRecordClient&) This method registers a client with an individual record so that the given client will receive all events subsequently generated by that record.

RTRRTRecord

RTRRTRecord

Quote Display Client

Record Client

InstancesInstances

"IBM.N"

"DEM="

viewing "IBM.N"

Quote Display Clientviewing "DEM="

Limit Minder Clientminding "IBM.N" & "DEM="

SFC Developer’s Guide 30

Page 45: sfc

4.1 SFC MODELS

void dropClient(RTRRTRecordClient&) This method un-registers a client with a particular record so that the given client will no longer receive events from that record.

RTRBOOL hasClient(RTRRTRecordClient&) This method is used to determine whether a given client is currently registered to receive events from a particular record.

4.1.2.6 Record ClientsRecord clients are descendants of (inherit from) RTRRTRecordClient. As such, they can register to receive events from one or more instances of RTRRTRecord. Once registered with a record they will receive all events generated by that record instance. Events are propagated by means of class member functions; i.e., when a record needs to "generate an event", it will invoke the appropriate member function of each client currently registered.

The "sync" event is one example of an event which can be generated by a record. The corresponding member function of RTRRTRecordClient is processRecordSync(RTRRTRecord&). Thus, when a record transitions from the Active_noData state to, say, the Active_valid state, it will invoke the processRecordSync() member function of each registered client.

Referring to the example illustrated in Figure 4.5, if the IBM.N record instance generates a sync event, it must invoke the appropriate method for each of it clients, of which there are two—one each of type QuoteDisplay and type LimitMinder. In this case, each method does something different; one draws a display, the other initializes limit minding.

All events which can be generated by instances of RTRRTRecord have a corresponding processing method in RTRRTRecordClient. In some cases, a default implementation (behavior) has been defined. In C++ terms, those event processing methods with default behavior are declared as virtual functions. Those for which there is no default behavior are declared as pure virtual. The event processing methods of RTRRTRecordClient for which there is no default (declared pure virtual) are as follows:

virtual void processRecordInfo(RTRRTRecord&) = 0 This event indicates that new informational text concerning the given record is available via the records text() method.

virtual void processRecordSync(RTRRTRecord&) = 0 The given record has made the transition out of the Active_noData state. The client can process field data as appropriate according to the condition of the data (stale vs. not stale).

SFC Developer’s Guide 31

Page 46: sfc

4.1 SFC MODELS

virtual void processRecordStale(RTRRTRecord&) = 0 The data for the given record is now in a stale condition.

virtual void processRecordNotStale(RTRRTRecord&) = 0 The data for given record is no longer in a stale condition.

virtual void processRecordInactive(RTRRTRecord&) = 0 The given record is no longer active. This represents an unrecoverable error condition. The client should un-register from the record (using dropClient()) and ensure that no further references are made to that record or to any of that records fields. The text() method provides informational text indicating the reason for this event.

The event processing methods of RTRRTRecordClient for which there is a default implementation (declared virtual) are as follows:

virtual void processCloseTick(RTRRTRecord&) This update event indicates that the fields modified by this update are not changing as a result of market activity but rather as a reflection of changes in certain historical fields. For example, a field which reflects the closing price for the previous day’s trading will be updated by a close tick prior to a new day of trading. This event is generated by a record instance prior to updating individual fields which are affected by this tick. The default implementation invokes the processUpdate() method of this client.

virtual void processCorrectionTick(RTRRTRecord&) This update reflects corrections to previously delivered data which is in error. Updates of this type do not indicate market activity. This event is generated by a record instance prior to updating individual fields which are affected by this tick. The default implementation invokes the processUpdate() method of this client.

virtual void processRecordResync(RTRRTRecord&) This update reflects the recovery from a recoverable error condition. It does not reflect market activity. This event is generated by a record instance prior to updating individual fields which are affected by the recovery. The default implementation invokes the processUpdate() method of this client.

virtual void processUpdate(RTRRTRecord&) This is the generic update event which is invoked as the default processing by the above event processing methods. Clients who wish to pre-process update events but who do not need to differentiate among updates by their semantics can redefine just this event processing method.

SFC Developer’s Guide 32

Page 47: sfc

4.1 SFC MODELS

Again, this "event" occurs prior to the individual field update events. The default implementation does nothing, i.e., pre-update events are ignored.

virtual void processUpdateComplete(RTRRTRecord&) This event is generated by a record after all fields affected by a tick have been modified. Clients who wish to post-process an update event can redefine this method. The default implementation does nothing, i.e., post-update events are ignored.

virtual void processResyncComplete(RTRRTRecord&) This event is generated by a record after all fields affected by a tick have been modified. Clients who wish to post-process a re-sync event can redefine this method. The default implementation invokes processUpdateComplete().

4.1.2.7 Access to FieldsRecords must provide both random and sequential access to their constituent fields. Sequential access is provided by means of an "iterator" class, an instance of which is associated with a particular record instance and provides access to each field of the record in turn. The basic record iterator is defined by the class RTRRTRecordIterator.

A record iterator instance is obtained using the iterator() method of class RTRRTRecord. Figure 4.6 shows how a record iterator is used to traverse all the fields of a record. The start() method is invoked to initiate a new traversal. This method makes the first field of the record available for inspection via the field() method of the iterator. The returned reference is of type RTRRTField, which, in this case, is the "display name". Invoking the forth() function makes available the next field, in this case "trade price 1", and so-on. After the call to start() and after each call to forth(), the off() condition should be tested. When off() returns RTRTRUE, the iteration has been completed.

SFC Developer’s Guide 33

Page 48: sfc

4.1 SFC MODELS

Figure 4.6: Accessing All Fields Using a Record Iterator

4.1.2.8 Field UpdatesThe SFC provides two techniques for obtaining updated field values. Sequential access to updated fields can be achieved by use of a class which is a variant on the iterator class described in the previous section. An instance of RTRRTRecordUpdateIterator is only valid during the processUpdateComplete() event and provides access to only those fields which have updated as a result of the current event. This is illustrated in Figure 4.7.

Figure 4.7: Accessing Updated Fields Using a Record Update Iterator

start()

forth()

DisplayName

TradePrice 1

TradePrice 2

High 1 Low 1 Bid

off()

forth() forth() forth()forth() forth()

off()

start()

DisplayName

TradePrice 1

TradePrice 2

High 1 Low 1 Bid

off()

forth() forth() forth()

off()

SFC Developer’s Guide 34

Page 49: sfc

4.1 SFC MODELS

An alternative technique is to define a class which is a descendant of RTRRTFieldClient and which can then be registered with one or more fields of interest. Field update events are generated by fields between the pre and post update events generated by the record which contains those fields.

Figure 4.8 illustrates the event sequence which will occur (assuming that the default processing for processTick() is retained) when a record called "DEM=" updates the "BID" and "ASK" fields.

Figure 4.8: Record and Field Update Event Sequence

4.1.3 ImplementationCurrently, the SFC provides two implementations of the real-time and snapshot record models. While most application components should refer only to the base classes mentioned in the preceding section, the "main" routine or initialization section of an application must instantiate one or more implementation specific classes.

SFC includes implementation classes for use by both single (simple) and multiple service (more complex) applications. These classes encapsulate the procedures for creating an SSL connection and the record services which use that connection. They are:

processTick()

processUpdate()

processUpdateComplete()

processFieldUpdate()

processFieldUpdate()

RTRRecord (DEM=)

RTRRTField ("BID")

RTRRTFieldClientRTRRTRecordClientRTRRTField ("ASK")

SFC Developer’s Guide 35

Page 50: sfc

4.1 SFC MODELS

• RTRSSLRTRecordService - This class is a descendant of RTRRTRecordService that creates its own SSL session. It is typically used by simple applications which require access to only a single service. Readers familiar with SSL functionality will realize that SSL record data is delivered in the Marketfeed format. All decoding and interpretation of SSL messages is handled by the implementation classes, a complete description of which is beyond the scope of this manual.

• RTRTIBRTRecordService - This class is a descendant of RTRRTRecordService that creates its own TIB session. It is typically used by simple applications which require access to only a single service. It can be used to consume data from an RTIC.

A typical application will instantiate one of the implementation service classes in main() (or its equivalent).

4.1.3.1 Multiple ServicesSome applications use more than one service. The connection and service pool factory classes make it easy to incorporate multiple services in a single application.

RTRSSLConnection and RTRTIBConnection can be used to fine tune the connection parameters for the implementation record services. They are described in detail in section 4.8.1.

RTRSSLServicePoolFactory and RTRTIBServicePoolFactory can be used to manage the life-cycle of and share a single connection among several market data services. They are described in detail in section 4.8.2.

4.1.4 Class SummariesThis section provides a summary of the classes which comprise the models for record data. The table matches snapshot record classes with their real-time record counterparts. For more details please refer to the appropriate sections of the alphabetical class reference.

Real-time Snapshot

RTRRTRecord RTRSnapshotRecord

RTRRTRecordClient RTRSnapshotRecordClient

RTRRTRecordIterator RTRSnapshotRecordIterator

Table 4.5: Real-time Record Classes vs. Snapshot Record Classes

SFC Developer’s Guide 36

Page 51: sfc

4.1 SFC MODELS

4.1.4.1 Real-time Record Class Summary• RTRRTRecord - This class defines an item of real-time record data. Records provide both linear

and sequential access to their constituent fields. Records have state which may change over time. Data and state change events are propagated to other application components which have registered with a record for the purpose of receiving record events. Records support multiple clients.

• RTRRTRecordClient - This is the abstract base class for application components which wish to register with one or more real-time records in order to receive data and state events from those records.

• RTRRTRecordIterator - Instances of this class provide sequential access to all the constituent fields within a given record.

• RTRRTRecordUpdateIterator - Instances of this class are used during update events to provide sequential access to those fields within a real-time record which where modified by the current update.

• RTRRTField - This class defines the base type for the constituent parts of a record. Fields are identified by name or FID, have a specific type, and provide various forms of access to the underlying data which they represent.

RTRRTRecordUpdateIterator not applicable

RTRRTField RTRSnapshotField

RTRRTAlphanumericField, etc. RTRSnapshotAlphanumericField, etc.

RTRRTFieldClient not applicable

RTRRTRecordService RTRSnapshotRecordService, or just useRTRRTRecordService

RTRRTRecordServicePool use RTRRTRecordServicePool

RTRRTRecordServicePoolClient use RTRRTRecordServicePoolClient

Real-time Snapshot

Table 4.5: Real-time Record Classes vs. Snapshot Record Classes (Continued)

SFC Developer’s Guide 37

Page 52: sfc

4.1 SFC MODELS

• RTRRTAlphanumericField, RTRRTDateField, RTRRTEnumeratedField, RTRRTIntegerField, RTRRTPriceField - These descendants of RTRRTField provide type-specific interpretation of the underlying data.

• RTRRTFieldClient - This is the abstract base class for application components which wish to register with one or more individual fields in order to receive data and state events from those fields.

• RTRRTRecordService - This class provides access to real-time record data and manages the aggregate state of those records. Service state change events are propagated to those application components which register to receive those events.

• RTRRTRecordServicePool - Instances of this class serve as a repository for all available real-time record services. Typically there is only one instance of this type within an application. A pool provides random and sequential access to the services it contains. A pool provides the means to insert and remove services and allows clients to register for the change events which are generated when the contents are modified.

• RTRRTRecordServicePoolClient - This is the abstract base class for components which wish to register with one or more real-time record service pools in order to receive data and state events from those pools.

4.1.4.2 Snapshot Record Class Summary• RTRSnapshotRecord - This class defines an item of snapshot record data. Records provide

both linear and sequential access to their constituent fields. Snapshot records do not change state or update data. Snapshot records support multiple clients.

• RTRSnapshotRecordClient - This is the abstract base class for application components which wish to register with one or more snapshot records in order to receive data for those records.

• RTRSnapshotRecordIterator - Instances of this class provide sequential access to all the constituent fields within a given snapshot record.

• RTRSnapshotField - This class defines the base type for the constituent parts of a record. Fields are identified by name or FID, have a specific type, and provide various forms of access to the underlying data which they represent. Snapshot fields do not update, so they do not have clients.

• RTRSnapshotAlphanumericField, RTRSnapshotDateTimeField, RTRSnapshotEnumeratedField, RTRSnapshotIntegerField, RTRSnapshotPriceField -

SFC Developer’s Guide 38

Page 53: sfc

4.1 SFC MODELS

These descendants of RTRSnapshotField provide type-specific interpretation of the underlying data.

• RTRSnapshotRecordService - This class provides access to snapshot record data.

4.1.4.3 Record Chain Class Summary• RTRRecordChain - This class defines a chain of real-time records. Status, error, and state

change events are propagated to the client of the chain. Record chains support only one client.

• RTRRecordChainClient - This is the abstract base class for application components which wish to register with one or more record chains to receive events from those chains.

• RTRRecordChainIteratorPtr - Instances of this class provide sequential access to all the constituent elements in a given record chain. This iterator is reference counted, meaning clients should always request an iterator from the chain. The iterator will be deleted automatically when it is no longer referenced by any variables.

• RTRRecordChainElement - This class encapsulates the name of a record in a record chain. If it updates, it propagates the event to its client. Record chain elements support only one client.

• RTRRecordChainElementClient - This is the abstract base class for application components which wish to register with one or more record chain elements to receive update events from those elements.

4.1.4.4 Summary of Other Classes in the Record Cluster• RTRMDServiceClient - This is the abstract base class for components which wish to register

with one or more instances of record or page services in order to receive data and state events from those services.

• RTRFidDb - This class represents the database of field definitions used by a particular service.

• RTRFidDefinition - This class represents the definition for an individual field. A definition comprises the identification (name and FID) of a field and the type. The type determines the way in which the raw data should be interpreted; the identity defines the meaning of the field.

SFC Developer’s Guide 39

Page 54: sfc

4.1 SFC MODELS

4.1.5 ExamplesSFC includes several examples which highlight different parts of the record model. All of these examples can be found the sfc/examples/realtime/ directory, with the exception of Quote, which is only available for Windows. The rest of the examples are very similar. They typically have two parts:

1. main() function that:

• parses command line arguments• creates a service pool factory or record service• requests a record, field or chain• creates the appropriate SFC client and registers it with the market data item• creates the event control loop

2. SFC client implementation that is responsible for

• processing data and status events• printing output to standard out

The following table summarized the record examples and details where more information about them can be found.

Example Description Refer to...

RecSnap Snapshot client• creates a RTRSnapshotRecordClient• outputs the record image received

recsnapclient.* recsnap.Csection 4.1.6

RecUpd Record client• creates a RTRRTRecordClient• outputs the record image and updates received

recupdclient.*recupd.Csection 4.1.7

RecFld Field client• creates a RTRRTRecordClient and RTRRTFieldClient• outputs the record’s BID, ASK, and TRDPRC_1 on

image• uses field client to determine if TRDPRC_1 has changed

on update

tickclient.*recfld.Csection 4.1.8

Table 4.6: Record Examples

SFC Developer’s Guide 40

Page 55: sfc

4.1 SFC MODELS

4.1.6 Record Snapshot ClientThe RecSnap example defines a simple record client component, RecordSnapshotClient. The purpose of this class is to print a snapshot of a record image on the standard output device. This record client is not concerned with updates or any other events once the initial image has been extracted.

In order to receive data in a record event, RecordSnapshotClient must be a descendant of RTRSnapshotRecordClient and therefore must provide implementations of all pure virtual methods inherited from its ancestor. These methods correspond to the events which can be received from RTRSnapshotRecord, and their implementation defines the behavior of this class. If the client were not interested in some of the events, the event processing methods would be implemented to do nothing.

RecTick Multiple record clients• creates one or more RTRRTRecordClients

tickclient.*rectick.C

Ticker Configured record and pool client• uses a config file• creates a service pool factory• access a service from the factory• creates one or more RTRRTRecordClients

tickclient.*tickmon.*ticker.Cticker.configsection 4.1.9

ChainUpd Chain Client• creates a RTRRecordChainClient• creates RTRRecordChainElementClients for the chain• adds, removes and changes chain element clients as

needed

Chain*Client.*chainupd.Csection 4.1.10

Quote(win32 only)

• provides simultaneous access to RMDS and Triarch through multiple service pool factories

• provides a unified service list through pool clients• creates record, chain, and field clients• displays chains and records in a window using display

templates.

mfcquote.pdf(win32 only)

Example Description Refer to...

Table 4.6: Record Examples (Continued)

SFC Developer’s Guide 41

Page 56: sfc

4.1 SFC MODELS

This class processes the following events:

• SnapshotInfo

• SnapshotSync

• SnapshotInactive

4.1.6.1 Declaration of RecordSnapshotClientThe following code is taken from recsnapclient.h and shows the declaration for RecordSnapshotClient:

#ifndef _recsnapclient_h#define _recsnapclient_h

#include "rtr/snaprec.h" // Defines RTRSnapshotRecordClientclass RTRSnapshotRecordService; // Forward declaration

class RecordSnapshotClient :public RTRSnapshotRecordClient

{public:// Constructor

RecordSnapshotClient(RTRSnapshotRecordService& service, const char *symbol);

// Destructor~RecordSnapshotClient();

// Event processing - from RTRSnapshotRecordClientvoid processSnapshotInfo(RTRSnpahotRecord&);

// This method invoked when there is new text associated with the// record. No state change is implied.

void processSnapshotSync(RTRSnapshotRecord&);// This method invoked when there is an initial image for the// record. (It can only happen once.)

void processSnapshotInactive(RTRSnapshotRecord&);// This method invoked when the record has made the transition to// the inactive state.

SFC Developer’s Guide 42

Page 57: sfc

4.1 SFC MODELS

protected:// Implementation attributes

RTRSnapshotRecord *_record;

};#endif

4.1.6.2 Definition of RecordSnapshotClientThe constructor of this class illustrates the correct procedure for accessing records from a service. In pseudo-code the procedure is as follows:

Get record referenceAdd client to recordIf record active then

If record has data thenprocess data and data condition

elseclean up

Notice that the processSnapshotSync() method uses an iterator to access all the fields in the record. The proper cleanup technique is illustrated in several places:

• in the destructor, in case the client is deleted while still a client of the record;

• in processSnapshotSync(), after the client is finished with the record; and

• in processSnapshotInactive(), after the client is informed of an unrecoverable error.

The following code contains the implementation of RecordSnapshotClient. Comments which are numbers (e.g., // 1) refer to more extensive comments at the end of the source file.

#include "rtr/rtrnotif.h"// Access to event loop#include "rtr/snaprecsrv.h"// RTRSnapshotRecordService

#include "recsnapclient.h"

// ConstructorRecordSnapshotClient::RecordSnapshotClient(

RTRSnapshotRecordService& service, const char *symbol): _record(0)

{

SFC Developer’s Guide 43

Page 58: sfc

4.1 SFC MODELS

// 1_record = &(service.snapshotRecord(symbol));_record->addClient(*this);if ( _record->active() ){

if ( _record->hasData() )processSnapshotSync(*_record);

elseprocessSnapshotInfo(*_record);

}else{

// 2cout << symbol << " - Inactive: " << _record->text() << endl;_record->dropClient(*this);_record = 0;

}}

// DestructorRecordSnapshotClient::~RecordSnapshotClient(){// 3

if ( _record )_record->dropClient(*this);

}

// Event processing methods

void RecordSnapshotClient::processSnapshotInfo(RTRSnapshotRecord& record){// 4

cout << record.symbol() << " - Info : " << record.text() << endl;}

void RecordSnapshotClient::processSnapshotSync(RTRSnapshotRecord& record){// 5

// Access each field from the record using an iterator

SFC Developer’s Guide 44

Page 59: sfc

4.1 SFC MODELS

// 6RTRSnapshotRecordIterator iterator = record.iterator();for (iterator.start(); !iterator.off(); iterator.forth()){

// Print the name and value of each fieldRTRSnapshotField& field = iterator.field();cout << field.name() << " " << field.string() << endl;

}// Clean up and terminate the application

// 7record.dropClient(*this);_record = 0;RTREventNotifierInit::notifier->disable();

}

void RecordSnapshotClient::processSnapshotInactive(RTRSnapshotRecord& record){

cout << record.symbol() << " - Inactive : " << record.text() << endl;record.dropClient(*this);_record = 0;RTREventNotifierInit::notifier->disable();

}

// 1 Records should always be accessed in this manner// * Obtain a reference to the desired record// * Register a client with the record// * Test the state of the record// Services return references to records, meaning that they are never// null. However, because clients should not retain references to inactive // records, this class stores a pointer to the record. This so that the // pointer can be set to null in the event of the record being inactive.//// 2 Clients should never remain registered with records in the inactive state//// 3 Be sure to un-register clients when clients are destructed//// 4 Records provide informational text about their state.//// 5 The record "sync" event occurs when a record transitions to the// "hasData" state. This transition/event only occurs once for a given

SFC Developer’s Guide 45

Page 60: sfc

4.1 SFC MODELS

// record.//// 6 Records provide both sequential and "random" access to their constituent// fields.//// 7 This client terminates the application once the record sync event// is received. This is not typical behaviour for record clients.

4.1.6.3 RecSnap ApplicationThis class by itself does not comprise an application. A complete application must provide access to an implementation of RTRRTRecordService and must instantiate one (or more) instance of RecordSnapshotClient. The next section illustrates such an application.

This application (recsnap.C) uses the RTRSelectNotifier for the control loop and combines an SSL or TIB implementation of RTRRTRecordService with an instance of RecordSnapshotClient. The control loop is defined by the SFC application framework introduced in Chapter 3 and presented in more detail in section 4.8.3 and in the SFC Reference Manual.

// Some of the code has been omitted for brevity.// See sfc/examples/realtime/recsnap.C for all of the code

#include "recsnapclient.h"#include "rtr/selectni.h"// RTRSelectNotifier#include "rtr/tibrtsvc.h"#include "rtr/sslrtrs.h"

RTRCmdLine RTRCmdLine::cmdLine;

int main(int argc, char* argv[]){

RTRString serviceName, infra, symbol;RTRString servicePort, network, daemon;

// Read command line parameters, set serviceName, infra, and symbol.// For TIB, also set servicePort, network, and daemon.// ...

RTRRTRecordService *service = 0;

SFC Developer’s Guide 46

Page 61: sfc

4.1 SFC MODELS

// Select which architecture to consume from if (infra == "tib"){

service = new RTRTIBRTRecordServiceService(appId, serviceName, servicePort, network, daemon);

}else if (infra == "ssl"){

service = new RTRSSLRTRecordService(appId, serviceName);}else{

cout << "invalid infrastructure: " << infra << endl;return -1;

}

if ( !service->active() ){

cerr << "Service error: " << service->text() << endl;delete (service);return -1;

}

RecordSnaphotClient client(*service, symbol);RTRSelectNotifier::run();

delete service;return 0;

}

4.1.7 Real-time Record ClientThe RecUpd example is similar to RecSnap, but it adds functionality to monitor updates from the record of interest. To receive update and state change events this class uses the real-time record classes. It uses a RTRRTRecordService to get a RTRRTRecord. RecordUpdateClient is a subclass of RTRRTRecordClient, so it will receive RecordSync, RecordInfo, and RecordInactive events instead of SnapshotSync, SnapshotInfo, and SnapshotInactive events. Since the record will be monitored continuously, this class also provides processing for stale events and recovery.

RecordUpdateClient processes these events by overriding virtual methods from RTRRTRecordClient::

SFC Developer’s Guide 47

Page 62: sfc

4.1 SFC MODELS

• RecordSync

• RecordInfo

• RecordInactive

• RecordStale

• RecordNotStale

RecordUpdateClient also processes this event by overriding the default behavior (which does nothing):

• UpdateComplete

4.1.7.1 Declaration of RecordUpdateClientThe declaration of RecordUpdateClient illustrates the basic techniques for processing record update events. This class is designed to print the image of the requested record and then monitor that record for updates. The values of updated fields are printed.

This class is similar to RecordSnapshotClient but provides processing for the RecordStale/RecordNotStale events and overrides the default event processing for UpdateComplete events.

#ifndef _recupdclient_h#define _recupdclient_h#include "rtr/rtrec.h"// Defines RTRRTRecordClient

class RecordUpdateClient : public RTRRTRecordClient

{public:// Constructor

RecordUpdateClient(RTRRTRecordService& srvc, const char *symbol);

// Destructor~RecordUpdateClient();

// Event processing - from RTRRTRecordClientvoid processRecordInfo(RTRRTRecord&);

// This method invoked when there is new text associated with the// record. No state change is implied.

SFC Developer’s Guide 48

Page 63: sfc

4.1 SFC MODELS

void processRecordSync(RTRRTRecord&);// This method invoked when there is an initial image for the// record. (It can only happen once.)

void processRecordStale(RTRRTRecord&);// This method invoked when the record has made the transition to// the stale state.

void processRecordNotStale(RTRRTRecord&);// This method invoked when the record has made the transition out// of the stale state.

void processRecordInactive(RTRRTRecord&);// This method invoked when the record has made the transition to// the inactive state.

void processUpdateComplete(RTRRTRecord&);// This method invoked when the record has completed a update.

protected:// Implementation attributes

RTRRTRecord *_record;

};#endif

4.1.7.2 Definition of RecordUpdateClientThe definition of RecordUpdateClient does most of the event processing work. The procedure used in the constructor follows the pattern:

Add a new client to the recordIf the record is active then

If the record has an initial image thenprocess that image and the current condition of the data

elseprocess the informational text and wait for record events

elseprocess the inactive record state

SFC Developer’s Guide 49

Page 64: sfc

4.1 SFC MODELS

This procedure should be used in all record client classes. It is especially important that clients do not assume that they are the "first" or only client to access a given record. This is because the record may, for example, already be in the "hasData" state, in which case it will never again generate the Sync event. In general it should be assumed that a record instance may already be in use by some other client within the application.

Note that while the processRecordSync() and processRecordNotStale() methods use an instance of RTRRTRecordIterator to access all fields in the record, the processUpdateComplete() method uses an instance of RTRRTRecordUpdateIterator which provides access to only those fields which have been updated by the most recent update event.

//// This file contains the implementation of RecordUpdateClient//

#include "rtr/rtrnotif.h"// Access to event loop#include "rtr/rtrecsrv.h"// RTRRTRecordService

#include "recupdclient.h"

// 1RecordUpdateClient::RecordUpdateClient(

RTRRTRecordService& service, const char *symbol): _record(0)

{// Obtain a record reference, register with the record and check// its state.

_record = &(service.rtRecord(symbol));_record->addClient(*this);if ( _record->active() ){

if ( _record->hasData() )processRecordSync(*_record);

elseprocessRecordInfo(*_record);

}else{

cout << symbol << " - Inactive: " << _record->text() << endl;_record->dropClient(*this);

SFC Developer’s Guide 50

Page 65: sfc

4.1 SFC MODELS

_record = 0;}

}

RecordUpdateClient::~RecordUpdateClient(){

if ( _record )_record->dropClient(*this);

}

void RecordUpdateClient::processRecordInfo(RTRRTRecord& record){

cout << record.symbol() << " - Info : " << record.text() << endl;}

void RecordUpdateClient::processRecordSync(RTRRTRecord& record){

// Display the record image.RTRRTRecordIterator iterator = record.iterator();for (iterator.start(); !iterator.off(); iterator.forth()){

RTRRTField& field = iterator.field();cout << field.name() << " " << field.string() << endl;

}}

void RecordUpdateClient::processRecordStale(RTRRTRecord& record){

// Print the textual information regarding the records stale statecout << record.symbol() << " - Stale : " << record.text() << endl;

}

void RecordUpdateClient::processRecordNotStale(RTRRTRecord& record){

// Redisplay the updated image.RTRRTRecordIterator iterator = record.iterator();for (iterator.start(); !iterator.off(); iterator.forth()){

RTRRTField& field = iterator.field();cout << field.name() << " " << field.string() << endl;

SFC Developer’s Guide 51

Page 66: sfc

4.1 SFC MODELS

}}

void RecordUpdateClient::processRecordInactive(RTRRTRecord& record){

cerr << record.symbol() << " - Inactive : " << record.text() << endl;record.dropClient(*this);_record = 0;RTREventNotifierInit::notifier->disable();

}

void RecordUpdateClient::processUpdateComplete(RTRRTRecord& record){

// Display the updated fields from the current record update// 2

RTRRTRecordUpdateIterator iterator = record.updateIterator();cout << endl;for (iterator.start(); !iterator.off(); iterator.forth()){

RTRRTField& field = iterator.field();cout << field.name() << " " << field.string() << endl;

}}

// 1 It is assumed that the reader is familiar with the implementation// of RecordSnapshotClient//// 2 The update iterator is similar to the "image" iterator, however it// only traverses fields which were updated during the current tick.// It is only valid to use the update iterator during the tick event.

4.1.7.3 RecUpd ApplicationAn application using this RecordUpdateClient looks almost identical to the application in section 4.1.6. The allocation of RecordSnapshotClient is simply replaced with an allocation of RecordUpdateClient as follows:

RecordUpdateClient example(*service, symbol);

This application can be found in the file recupd.C.

SFC Developer’s Guide 52

Page 67: sfc

4.1 SFC MODELS

4.1.8 Field ClientIn some programs it is easier to have application components receive events about individual fields rather than full records. The RecFld example program shoes how to register interest in a single field.

The TickerClient class is similar to the RecordUpdateClient but is more particular about which field data is displayed. The purpose of the class is to display the value of four fields from the record: the name of the underlying instrument, the bid price, the ask price, and, when it changes, the trade price.

In addition to being a RTRRTRecordClient, TickerClient is a descendant of RTRRTFieldClient. This allows an instance of TickerClient to register with the price field of the record being monitored. When a field level update is received, a flag is set in order to modify the output of the processUpdateComplete() method (a record generates events before and after the individual field updates).

Snapshot fields do not receive events, so there is no corresponding example for a snapshot record and fields.

Also, SFC always requests full records from the market data infrastructure. So, SFC uses record clients to determine which market data items are actively being watched. Field clients will only receive updates as long as a least one record client exists for the same item from the same service.

See the RecFld example program for more details.

4.1.9 Pool ClientPrevious examples have relied on a single service instance, created by the application. This section illustrates the use of a pool of services. This example makes use of record clients of type TickerClient which, as described previously, take at construction a record service instance. The main difference is in the way the service instances provided to the TickerClient are obtained. In addition, this application makes use of the configuration capabilities of the SFC. These capabilities are fully explained in section 4.8.5.

4.1.9.1 Declaration for TickerMonitor (tickmon.h)The purpose of the TickerMonitor class is to monitor a pool for a particular service and, when that service is available, to create a number of TickerClient instances. The records monitored are determined by the contents of a configuration variable which is interpreted as a list of symbols. In the Ticker example, the pool used by TickerMonitor is created by a service pool factory.

SFC Developer’s Guide 53

Page 68: sfc

4.1 SFC MODELS

TickerMonitor is a descendant of RTRRTRecordServicePoolClient. This allows TickerMonitor to register with a pool and receive relevant events. In this case, TickerMonitor monitors "ServiceAdd" events by providing an implementation of processRTRecordServiceAdd().

//// This file contains the declaration of TickerMonitor which// illustrates the basic techniques for processing service pool events. In// addition, the use of the RTRConfig and RTRConfigDb are illustrated.//// This class is designed to monitor a given pool for a particular service.// Once that service is available, an instance of TickerClient is created// for each symbol in a list.//// The name of the service and the contents of the symbol list are // configurable.//#ifndef _tickmon_h#define _tickmon_h

#include "rtr/rtrecspl.h"// Defines RTRRTRecordServicePoolClientclass RTRObjectId; // Forward declarationclass TickerClient; // Forward declaration

typedef TickerClient *TickerClientPtr;

class TickerMonitor : public RTRRTRecordServicePoolClient

{public:// Constructor

TickerMonitor(const RTRObjectId& context, const char *name, RTRRTRecordServicePool& pool);

// Destructor~TickerMonitor();

// Event processing - from RTRRTRecordServicePoolClientvoid processRTRecordServiceAdd(

SFC Developer’s Guide 54

Page 69: sfc

4.1 SFC MODELS

RTRRTRecordServicePool&, RTRRTRecordService&);

protected:// Implementation attributes

const RTRObjectId _instanceId;RTRString _serviceName;RTRRTRecordServicePool& _pool;int _tickCount;TickerClientPtr *_tickStore;

// Static data membersstatic RTRObjectId _classId;

};#endif

4.1.9.2 Definition of TickerMonitor (tickmon.C)The constructor of TickerMonitor extracts from the configuration database the name of the service to be used and checks to see if that service is already in the pool. If not, there is nothing to do but wait for the service to appear. The event processing method obtains the list of symbols from the configuration database and allocates a TickerClient for each symbol. Once the service has been obtained, pool events are no longer of interest to TIckerMonitor. Note that the destructor of TickerMonitor illustrates the proper cleanup procedure.

#include "rtr/config.h"// Defines RTRConfig

#include "tickmon.h"#include "tickclient.h"

// ConstructorTickerMonitor::TickerMonitor(

const RTRObjectId& context,const char *name,RTRRTRecordServicePool& pool)

: _instanceId(context, name), _pool(pool), _tickCount(0), _tickStore(0)

{

SFC Developer’s Guide 55

Page 70: sfc

4.1 SFC MODELS

// Get the name of the service to use// 1

_serviceName = RTRConfig::configDb().variable(_classId,_instanceId,"service_name","IDN_SELECTFEED");

// Register with the pool and see if the desired service is in the pool// 2

_pool.addClient(*this);RTRRTRecordService *service = _pool.service(_serviceName);if (service)

processRTRecordServiceAdd(pool, *service);}

// DestructorTickerMonitor::~TickerMonitor(){

// Be sure to de-register this client from the poolif ( _pool.hasClient(*this) )

_pool.dropClient(*this);for ( ; _tickCount; )

delete _tickStore[--_tickCount];delete [] _tickStore;

}

// Event processing

// 3void TickerMonitor::processRTRecordServiceAdd(

RTRRTRecordServicePool&, RTRRTRecordService& service)

{if (_serviceName == service.name()){

// 4// Get a list of symbols to retrieve

RTRListOfExternalValue ricList = RTRConfig::configDb().variable(_classId,_instanceId,"symbol_list",

SFC Developer’s Guide 56

Page 71: sfc

4.1 SFC MODELS

"RTRSY.O").list(‘,’);

_tickStore = new TickerClientPtr [ricList.count()];// Iterator over the items in the list

for (ricList.start(); !ricList.off(); ricList.forth()){

_tickStore[_tickCount++] = new TickerClient(service, ricList.item());

}

// 5_pool.dropClient(*this);

}}

// 6RTRObjectId TickerMonitor::_classId("TickerMonitor");

// 1 TickerMonitor uses the configuration database to determine the name // of the service from which to access data. The first argument is// the class identifier of this component (roughly the equivalent to the// C++ class name), a value which is the same for all instances of this// class (supposing there were more than one in the application). The// second argument is the instance identifier of this instance. It should// be unique to this particular instance of TickerMonitor. The third// argument is the name of the variable and the fourth argument is the// default value (as a string) of that variable.//// 2 Descendants of RTRRTRecordServicePoolClient may register with a pool to // receive events from that pool.//// 3 This method will be called everytime a new service is added to the pool//// 4 The list of symbols is retrieved from the configuration database using// the same class and instance identifiers but with a different variable// name and a default value of "RTRSY.O". In addition, the return value// is further interpreted as a list, delimited by the ‘,’ character.//// 5 In this case, addition pool events are of no further interest so// this client un-registers from the pool.

SFC Developer’s Guide 57

Page 72: sfc

4.1 SFC MODELS

//// 6 One way to define a class identifier common to all instances of a// class is to use the static data member construct.

4.1.10 Chain ClientApplications that use the chain model may be interested in all of the data for all of the records in a chain. However, this is not always feasible, especially for large chains. So some applications initially take interest in only the list of records in a chain and will request data for just those records that are currently being displayed.

Chain client components can normally be broken into two parts:

1. the component interested in the chain’s list.

2. the component interested in the record data referred to by elements in the chain.

The ChainUpd example is split in just such as manner. The ChainUpdChainClient class is interested in the list. Based on events that it receives, it creates and destroys ChainUpdRecordClients, which each monitor a single field in a single record. Figure 4.9 shows how the classes in the ChainUpd example are related to SFC client classes.

SFC Developer’s Guide 58

Page 73: sfc

4.1 SFC MODELS

Figure 4.9: Classes in ChainUpd

4.1.10.1 ChainElementRecordClientFigure 4.9 includes one class that has not been mentioned yet, ChainElementRecordClient. ChainElementRecordClient merges implementations of a RTRRecordChainElementClient and a RTRRTRecordClient.

The elements in statistical chains, like .AV.O and .NG.L, often change. Remember that chain elements are fixed to a position, not a record symbol. So when statistical chains re-sort or resize, the RTRRecordChainElementClients have to react. Actions are require when:

• the chain shrinks, causing some elements to be removed

• chain elements update, causing some elements to point to new records

In ChainElementRecordClient, these events result in:

• dropping all references so the client’s element and record can safely be deleted

RTRRecordChainElementClient RTRRTRecordClient

ChainElementRecordClient

RTRRTFieldClientRTRRecordChainClient

ChainUpdChainClient ChainUpdRecordClient*

SFC Developer’s Guide 59

Page 74: sfc

4.1 SFC MODELS

• dropping interest in one record and adding interest in another

These actions are reasonably generic, so they have been abstracted into ChainElementRecordClient, thus keeping the market data logic separate from the display code of ChainUpdateRecordClient (albeit simple cout <<’s). It should also be noted that ChainElementRecordClient is generic enough that it is also used by the GUI quote display example for Windows.

SFC Developer’s Guide 60

Page 75: sfc

4.2 SFC MODELS

4.2 Record Publication

4.2.1 OverviewSection 4.1, Record Subscription, described the basic characteristics of real-time record data and how application components subscribe to that data. These real-time record characteristics remain the same for publishing and this section assumes that the Record Subscription section has already been read.

The main difference between the models for record publication and subscription is that the publication model adds new methods to allow application components to "write” to the record. Specifically, the publication model allows applications to:

• control the contents of a record service

• determine the contents of a service’s constituent real-time records

• update the data of real-time records

• change the state of the service and records

• propagate data and state change events to other interested application components at the record, field and service level

• provide entitlement data and associated events to other interested application components for each record

The data provider is the application component that interacts with the record publication model. The application developer creates the data provider component.

4.2.1.1 Published RecordsA published real-time record publishes real-time "logical” or record-oriented data (i.e. the data item is composed of logical fields) representing a market data instrument.

A published record is comprised of 1 to N fields that are created by the data provider and put into the published record. There are several different type-specific fields available in the SFC for alphanumeric, date-time, enumerated, integer, numeric, and price values. These type-specific fields provide the

NOTE: This model is used to publish records which represent market data instruments.

SFC Developer’s Guide 61

Page 76: sfc

4.2 SFC MODELS

capability to interpret the stored field string value according to the rules associated with its particular type.

A field definition database (fidDb) defines the set of all possible fields that may be added to a published record. A field definition defines the semantic meaning of a record field, including the name, numeric identifier (FID), type and maximum data length of a field. Every field in a record is provided a field definition when the field is created.

A published record may change state depending on the ability of the data provider to supply up-to-date record data.The published record data may also change as updates are made to the data. Each of these types of state changes result in events being propagated to downstream client components.

In the SFC model, a RTRRTRecordImpl class represents a published real-time record. This class provides public methods that are used by application components to populate a real-time record with data, to update the record’s data and to propagate the state and data change events to other interested application components. Instances of RTRRTRecordImpl are obtained from a service of type RTRRTRecordServiceImpl.

The main benefits of the RTRRTRecordImpl class are:

• it implements the basic data caching and event propagation code for a real-time record (thus the name RTRRTRecordImpl)

• it makes it easy to control how the record functions

• it provides a standardized interface for publishing record data to different downstream components and architectures (e.g. Triarch and RMDS networks)

• it allows application components to stay focused on the task of determining how the record data is obtained and updated

4.2.1.2 Publishing ServiceA publishing service is used to publish record oriented market data to one or more downstream client components. A publishing service:

• manages requests for new records from downstream clients,

NOTE: A record propagates both state change events and data change events. State changes reflect the overall state of the record and all constituent fields. Data change events reflect updates to some or all constituent fields in a record.

SFC Developer’s Guide 62

Page 77: sfc

4.2 SFC MODELS

• creates new records in response to requests from downstream clients,

• creates new records as directed by the data provider for this service,

• accepts changes to the state of the service and

• propagates service state change events to downstream clients.

Developers create application components that interact with a publishing service and determine how the service will handle record requests, when the service will transition states, and how published records will be managed. The application components act as the data provider for the service.

In the SFC model, the RTRRTRecordServiceImpl class represents a publishing service. There are several different implementations of this service type that publish record data to the Triarch and RMDS infrastructures and to components within the application. However, application code is written to the generic RTRRTRecordImpl and RTRRTRecordServiceImpl interfaces.

4.2.2 Design

4.2.2.1 Record CreationPublished records of type RTRRTRecordImpl are created by the data provider for this service and, if the publishing service implementation permits, by the publishing service (RTRRTRecordServiceImpl) in response to requests from downstream components.

Records can be added to the service at any time. However, if the publishing service only supports a source-driven cache (like the TIB implementation), then it is best to load all the records into the publishing service at application start-up to ensure that these records will be there when the service becomes available to downstream client components and end-users.

Source-driven modeA source-driven, or non-interactive, publisher determines the entire contents of the publishing service cache on its own. Input is not accepted from downstream components.

NOTE: The SFC record publication service implementations always cache the item data that is being published. Requests from downstream clients for items already cached in the record publica-tion service will be satisfied from that service without notifying the data provider code.

SFC Developer’s Guide 63

Page 78: sfc

4.2 SFC MODELS

A data provider can use the RTRRTRecordServiceImpl::newRTRecordImpl() method to create a new RTRRTRecordImpl instance in the service for a specific instrument name (also known as a symbol). Note that the record must not exist in the service prior to making a newRTRecordImpl() method call. A reference to the newly published record is returned and the data provider initializes the state and data for the record (see the RTRRTRecordImpl section of the SFC Reference Manual).

A source-driven publisher has the ability to populate the cache of a 4.2 Source Distributor or later (Market Data Hub component). From the perspective of the SFC Developer this action is virtually transparent, but there are some configuration issues that may arise (see section 5.4.5.2 for details).

The *criteriaName configuration parameter is provided to set the criteria request name that is allowed to request data from a source application. This parameter must match the criteria request name configuration of the Source Distributor to allow the Source Distributor to request data. The default value is "triarch".

Sink-driven modeA sink-driven, or interactive, publisher determines the entire contents of the publishing service cache based on requests from downstream components.

The publishing service can also create new published records itself based on demand from downstream components. Note that not all publishing service implementations necessarily support this capability. The data provider component must register with the publishing service to receive an event whenever a record not currently cached in the publishing service is requested by a downstream component. Only a descendant of RTRRTRecordServiceImplClient can register with the service via the RTRRTRecordServiceImpl::setClient() method. Note that there is one and only one event client for a RTRRTRecordServiceImpl instance.

When a new RTRRTRecordImpl instance is created due to user demand, the RTRRTRecordServiceImplClient::processNewRecord() method is invoked by the service. This method is implemented in the data provider code. The data provider may choose to allow or disallow the record in the service’s cache. This decision may be made during the event call-back or at a later time if the data provider needs to query an upstream component before deciding.

NOTE: After the publisher indicates the service as sync, if client requests a record that has not been sent out to the Source Distributor by the publisher, this client will get the record status as inactive. As a result, this client has to re-request this record.

SFC Developer’s Guide 64

Page 79: sfc

4.2 SFC MODELS

Initially, a new published record is in the Active_stale state. If the data provider determines the record is valid, it will populate the record with fields and update the record’s state and data as needed (see section 4.2.2.5).

If the data provider determines that the record is not valid for some reason (e.g. not a valid instrument or instrument is no longer supported), the data provider sets the record state to Inactive, using the RTRRTRecordImpl::setInactive() and notifies downstream components of the record state change using RTRRTRecordImpl::indicateInactive(). If the data provider wishes to provide the record for that symbol later on, it must first remove the record from the publishing service via the RTRRTRecordServiceImpl::removeRTRecordImpl() method. Then it can create a new record and add it to the service.

Mixed modeAn application can also be designed to load items into the publishing service cache and accept requests from downstream components for new records as well. To do this, the application simply uses both of the methods described above.

Note that certain implementations do not support for the sink-driven mode. In particular, the TIB implementation will only allow the source-driven mode to be utilized. This means that the typical application using TIB will need to publish all of its records during initialization so they will be available when the application goes live on the RMDS network on a TIBCO Rendezvous Distribution Layer. Note that your application can still be designed to use the sink-driven mode, but when used with the TIB implementation, it will never receive requests from downstream components.

4.2.2.2 Record State DiagramThe state of a real-time record is defined by the values of three record attributes:

• active

• hasData

• stale

These state variables allow downstream users to determine whether the record is valid, whether the record has been populated with its set of fields, and whether the data is currently up-to-date.

Figure 4.10 shows record states and the events that indicate transitions between states:

SFC Developer’s Guide 65

Page 80: sfc

4.2 SFC MODELS

Figure 4.10: Real-time Published Record - States, Transitions and Variables

4.2.2.3 Record State Change EventsRecord state may change as the record transitions through initialization, data provider data-loss and recovery conditions, and end-of-life for the record. As transitions occur in the state of the record, the data provider will change the record’s state variables and then propagate state change events to downstream client components. Following are descriptions of the state transition events:

• Sync - This event indicates the availability of an initial "image”. This event is propagated after the data provider has added all fields to a record and provided the initial data for each field. The RTRRTRecordImpl::indicateSync() method is called to send this event.

• Resync - This event indicates the record data is about to be refreshed. This event can indicate a change in state from Active_stale to Active_valid, but it is the responsibility of the downstream client component to check whether the record state has changed. This event can be used to

Active_noData Active_valid

Active_staleInactive

Sync

Inactive

Inactive

Inactive

StaleNotStale

(hasData = False, stale = True, active = True)Active_noData(hasData = True, stale = False, active = True)Active_valid(hasData = True, stale = True, active = True)Active_stale(hasData = XX, stale = XX, active = False)Inactive

Sync

Resync

Resync

SFC Developer’s Guide 66

Page 81: sfc

4.2 SFC MODELS

indicate an update to fields due to recovery from a data-loss condition. The RTRRTRecordImpl::indicateResync() method is called to send this event.

• ResyncComplete - This event indicates that the record data has been refreshed. Downstream client components will access the fields that have changed during this call. The RTRRTRecordImpl::indicateResyncComplete() method is called to send this event.

• Stale - This event indicates a transition from the Active_valid state to the Active_stale state. All field data is considered out-of-date when the record makes this transition. It is the responsibility of the data provider to recover the data in a timely fashion. This event can be used when the record data is no longer up-to-date. The RTRRTRecordImpl::indicateStale() method is called to send this event.

• NotStale - This event indicates a transition from the Active_stale state to the Active_valid state. All field data is considered up-to-date when the record makes this transition. This event can be sent after the record data has been brought back up-to-date. The RTRRTRecordImpl::indicateNotStale() method is called to send this event.

• Inactive - This event indicates a transition to the Inactive state. This event can be sent when the record is no longer valid, such as when requests are made for non-existent items or when a request cannot be satisfied due to entitlements restrictions. This is a permanent condition; the record cannot be transitioned out of this state. The RTRRTRecordImpl::indicateInactive() method is called to send this event.

Records have a text() method which provides a textual explanation of the current record state. Record clients are kept informed of progress by means of events which indicate that there is new textual data available concerning the state of the record.

A record will also generate informational events when appropriate. The record’s text() should be changed to describe the informational event. This event is used to pass on information that may be of interest to downstream client components. This might include information regarding progress ininitializing the record data or in recovering record data. These events never indicate a change in record state. The RTRRTRecordImpl::indicateInfo() method is called to send this event.

NOTE: A transition to the Inactive state is a permanent condition. It is meant to indicate that this record will not be available anymore. If a record is temporarily unavailable, it should be put into the Stale state, not the Inactive state.

SFC Developer’s Guide 67

Page 82: sfc

4.2 SFC MODELS

4.2.2.4 Record Data Change EventsThe constituent fields of a record may change over time at the discretion of the data provider component. These field-level data changes manifest themselves at the record level as updates or "ticks”. These ticks are manifested by events which are initiated by the data provider and are propagated from the RTRRTRecordImpl instance to all interested downstream clients of the record.

Each tick indicates a change to one or more fields of a record. There are pre-tick and post-tick events generated with each tick. The pre-tick events (CloseTick, CorrectionTick, Tick) indicate that the some fields are about to be updated and indicate the type of update that will occur. The post-tick event (UpdateComplete) indicates that the fields have been updated and that a list of the updated fields is now available to downstream client components.

Following are descriptions of the data change events:

• CloseTick - This update event indicates that the fields modified by this update are not changing as a result of market activity, but rather as a reflection of changes in certain historical fields. For example, a field which reflects the closing price for the previous day’s trading will be updated by a close tick prior to a new day of trading. This event is initiated by the data provider prior to updating individual fields which are affected by this tick. The RTRRTRecordImpl::indicateCloseTick() method is called to send this event.

• CorrectionTick - This update reflects corrections to previously delivered data which is in error. Updates of this type do not indicate market activity. This event is initiated by a data provider prior to updating individual fields which are affected by this tick. The RTRRTRecordImpl::indicateCorrectionTick() method is called to send this event

• Tick -This update reflects an update to record data due to market activity. This event is initiated by a data provider prior to updating individual fields which are affected by this tick. The RTRRTRecordImpl::indicateTick() method is called to send this event.

• UpdateComplete -This event is initiated by the data provider after all fields affected by a tick have been modified. This event must be sent after field data has been updated. The RTRRTRecordImpl::indicateUpdateComplete() method is called to send this event.

Field-level events are generated by the data provider immediately after field data is updated. The FieldUpdate event is propagated through individual RTRRTField instances to downstream components that have registered interest with the field. Field events may only occur between a pre-tick and post-tick event for the associated record.

SFC Developer’s Guide 68

Page 83: sfc

4.2 SFC MODELS

See section 4.1.1.7 on Record Clients for information on how events are typically handled in downstream client components.

4.2.2.5 Record InitializationAfter the data provider component initially obtains a RTRRTRecordImpl instance, it must initialize the record. The basic algorithm for initializing a record is:

Create new fields and put them into the published recordSet the descriptive text of the published recordSend a Sync event for the record

Initially, the RTRRTRecordImpl instance (published record) obtained from a publishing service is in the Active_noData state (hasData=False and stale=True). Refer to the state diagram in Figure 4.10. This initial state indicates that the record has not yet been populated with fields. It is the responsibility of the data provider to populate all the fields associated with the record. This is done by creating instances of the defined field types and adding them to the record with the RTRRTRecordImpl::putField() method.

The defined field types are: RTRRTPriceField, RTRRTEnumeratedField, RTRRTIntegerField, RTRRTNumericField, RTRRTAlphanumericField, and RTRRTDateTimeField, RTRRTField.

When creating one of the defined field types, the data provider must supply several parameters to the field constructor:

NOTE: Fields can be added to records at any time. Down stream clients will only receive these new fields if the publisher calls either RTRRTRecordImpl.indicateSync() or RTRRTRecordImpl.indi-cateResyncComplete(RTRRTFieldUpdateList & fldList). On the client side this added field will not be contained in the RTRRTRecordUpdateIterator and will only show up in the RTRRTRecordIt-erator during the clients RTRRTRecordClient::processResyncComplete() callback.

Adding fields after a record transitions out of the Active_noData state is not supported when record templates are used. Adding fields may work if the added field is in the template, however if the field is not in the template the RTIC will not cache the field.

SFC Developer’s Guide 69

Page 84: sfc

4.2 SFC MODELS

• A RTRFidDefinition instance that properly represents that field. This means that the RTRFidDefinition::type() must match the type of field being created as indicated in the following table:

The FID definition is obtained from the service that created the published record (RTRRTRecordServiceImpl::fidDb()).

• A character array that will be used by the field to store data. Both the character array and the length of the array are passed.

• The length of the allocated memory. This should be the maximum length defined by the FID definition (i.e. RTRFidDefinition::length()) plus 1 byte to accommodate an end-of-delimiter character in the field data. Note that this is not the size of data currently found in the buffer, but the maximum size of the buffer.

After allocating the field, the initial data value is set using the RTRRTField::set() method.

RTRFidDefinition::type() Field type to use

TimeSecs,Time,DateTime RTRRTDateTimeField

Integer RTRRTIntegerField

Numeric RTRRTNumericField

Price RTRRTPriceField

Enumerated RTRRTEnumeratedField

Alphanumeric, LongAlphanumeric RTRRTAlphanumericField

Binary RTRRTField

Table 4.7: Mapping of RTRFidDefinition::type() and Field Types

NOTE: When allocating memory for the field, you must allocate 1 extra byte to accommodate an end-of-field delimiter; e.g. "char* buf = new char[ fidDef->length() + 1]”. If the correct length is not supplied, the field may not include all of the data.

SFC Developer’s Guide 70

Page 85: sfc

4.2 SFC MODELS

After the record is fully populated with fields, the state of the record should be changed to either Active_stale or Active_valid. The record data can be either stale or up-to-date when a Sync event is propagated. The RTRRTRecordImpl::setNotStale() method is used to change the record data state from stale to notStale. This must be done prior to sending the Sync event. Also, the RTRRTRecordImpl::setText() method may be used to reset the descriptive text associated with the record.

The RTRRTRecordImpl::indicateSync() method is called to propagate the Sync event to downstream client components. The RTRRTRecordImpl::hasData() record state variable will automatically be transitioned to True on this call.

4.2.2.6 Updating Fields in a Published RecordAt some point after the record is initialized, one or more fields may need to be updated as market movement occurs. The general algorithm for updating record fields is:

Notify downstream clients that fields are about to be updated Create/re-initialize a field update list of type RTRRTFieldUpdateListFor each field to be updated

Update the field data as required (using the RTRRTField.set() method)Notify field clients that the field data has changedAdd the updated field to a field update list

End for each fieldNotify downstream record clients that fields have been updated

There are two discrete events associated with updates to record fields. The first event indicates that a particular type of update is about to occur to some fields in the record. The RTRRTRecordImpl:: methods indicateUpdateTick(), indicateCorrectionTick() or indicateCloseTick() are used to indicate a particular type of update event.

NOTE: A transition from the Active_noData state occurs only once during the lifetime of the record. Future re-synchronization of the record is indicated by sending Resync and ResyncComplete events (see section 4.2.2.8).

SFC Developer’s Guide 71

Page 86: sfc

4.2 SFC MODELS

The data provider then updates the fields that have changed. Each field that is to be updated is obtained from the record using one of the record’s field accessor methods. Fields are then updated by calling the RTRRTField::set() method and providing the new data for the field.

After the appropriate fields have been updated, the indicateUpdateComplete() method is called. This method takes a RTRRTFieldUpdateList reference which is used as a container for the fields from this record that have been updated. The RTRRTFieldUpdateList class provides methods to insert fields by name, by FID or by reference. Upon completion of the indicateUpdateComplete() method, all of the record’s registered event clients have been notified of the updates to the fields passed in the field update list.

4.2.2.7 Changing Record StateAfter a Sync event occurs, the only valid state changes for a real-time record are:

• Active_stale to Active_valid

• Active_valid to Active_stale

• Active to Inactive

The general algorithm for changing the state of a record is:

Reset the state of the recordSet new informational text for the recordNotify downstream client components of the specific state change

To change a record’s state, the record is first set to its new state using one of the setStale(), setNotStale or setInactive() methods. Next, typically, the setText() method is used to provide a reason for the state change. Then the state transition is propagated to downstream client components using the indicateStale(), indicateNotStale() or indicateInactive() methods.

NOTE: If a length value of 0 is given to the RTRRTField::set() method, the field data will be cleared.

If the length value given to the RTRRTField::set() method is greater than the maximum length pro-vided to the field at construction, the provided data will be truncated at the maximum length of the field.

HINT: It is a good idea to keep a RTRRTFieldUpdateList in memory and re-initialize it as needed rather than creating a new one for each update loop.

SFC Developer’s Guide 72

Page 87: sfc

4.2 SFC MODELS

Note that the transition from Active to Inactive represents a permanent state change and that the record is no longer valid. No more data or state changes may occur to the record once it has transitioned to the Inactive state. Typically, the record is removed from the service (using the service’s removeRTRecordImpl() method) after the Inactive event is propagated to downstream client components.

4.2.2.8 Resynchronizing Record DataData may need to be resynchronized if the data becomes out-of-date for some reason, like failure of an upstream data source feed. A record is resynchronized using the same procedure as an update, except that the Resync and ResyncComplete events are sent and the state of the record may be changed in conjunction with the events.

The general algorithm for resynchronizing a record is:

Notify downstream clients that fields are about to be updatedCreate/re-initialize a field update list of type RTRRTFieldUpdateListFor each field to be updated

Update the field data as requiredNotify field clients that the field data has changedAdd the updated field to a field update list

End for each fieldNotify downstream record clients that fields have been refreshed

There are two discrete events associated with refreshing record fields. The first event indicates that a resync is about to occur and zero or more fields will be updated in the record. The method RTRRTRecordImpl::indicateResync() is called to send a Resync event. The second event indicates that the fields associated with the refresh have been updated and a list of the changed fields is available. The RTRRTRecordImpl::indicateResyncComplete() is called to send a ResyncComplete event.

4.2.2.9 Access to Published RecordsA RTRRTRecordServiceImpl provides the publisher both "random” and sequential access to its cache of records. Random access is achieved by calling the RTRRTRecordServiceImpl::rtRecordImpl() method and providing the symbol name of the instrument.

SFC Developer’s Guide 73

Page 88: sfc

4.2 SFC MODELS

Sequential access is achieved by obtaining an iterator from the record with the RTRRTRecordServiceImpl::iterator() method. An instance of RTRRTRecordServiceImplIterator provides access to all the published records within a record.

4.2.2.10 Publishing Service State ChangesThe state of a publishing service is determined by the value of two attributes: stale and active. The three valid service states are defined as follows:

State RecordAttributes Description

Stale stale = True active = True

The service is not capable of providing up-to-date data. This can occur if the data provider’s data source becomes unreliable (lost connection, slow data flow, innacturate data, etc.). All of the constituent records must be changed to the Stale state also. Stale is a recoverable condition and it is the responsibility of the data provider to recover all constituent records. Items may be requested from stale services, but the items will remain stale until the service itself is no longer stale and can automatically recover the items.

A GroupStale is a side effect of service stale. When a service transitions to stale, SFC will automatically trig-ger a GroupStale. (There is only one group in SFC, so all items in that service are stale.) Publishing to the network is disabled. Items can only be published to publisher’s cache while the service is stale. Also, any insert objects in the service that have not been acknowledged will be N-ACKed and deleted.

Table 4.8: Publishing Service States

SFC Developer’s Guide 74

Page 89: sfc

4.2 SFC MODELS

The data provider component is responsible for determining the current state of the publishing service. State transitions are propagated to clients as events generated by the data provider. The events triggered by state transitions are described as follows:

• Sync - This event indicates that the service is ready to accept requests and will recover data for any items currently cached in the service. Unlike the record sync event, this event can occur multiple times for a given service instance. However, it will never occur twice in a row. This event triggers a transition from the Stale state to the Ok state. Triarch and in-process service clients will receive a processServiceSync() event. This will also allow publisher to publish to the network.

• Stale - This event indicates a transition from the Ok state to the Stale state. Triarch and in-process service clients will receive a processServiceStale() event. Publishing to the network is disabled. (Network connection is still up). The publisher can still publish data; however, the data will only go to the publisher’s cache. Also, any inserts in the cache are N-ACKed and deleted.

Ok stale = False active = True

The service is now capable of providing up-to-date data and will recover any cached items.

A GroupNotStale will be sent when the service transi-tions from Stale to Ok. Any items in the cache will be marked Ok as well. Publisher is allowed to publish to the network.

Inactive stale = don’t care active = False

The service is being deactivated. All constituent items in this service must also be changed to the Inactive state. Users across a Triarch network will be notified that the service is Stale (not Inactive, since other ser-vices on the network with the same name may be available to handle user requests). Users on an RMDS network on a TIBCO Rendezvous Distribution Layer will receive individual inactives. Users within the same process must drop all references to this service as this is a non-recoverable condition.

State RecordAttributes Description

Table 4.8: Publishing Service States (Continued)

SFC Developer’s Guide 75

Page 90: sfc

4.2 SFC MODELS

• Inactive - This event indicates a transition to the Inactive state. In-process service clients will receive a processServiceInactive() event and should release all references to the service but this inactive event will not be propogated across the network. Consumers will recieve stale events.

Two methods are available for sending group messages efficiently to downstream clients.

• GroupStale - This event indicates Stale for all records in a particular group. This event can be used to efficiently send stale notifications to all records of a group. The indicateGroupStale() method is called to send this event. Unlike a service stale, a GroupStale still allows the publisher to publish to the network. However, all the items published to the network are stale.

• GroupNotStale - This event indicates NotStale for all records in a particular group. This event can be used to efficiently send NotStale notifications to all records of a group. The indicateGroupNotStale() method is called to send this event.

Services will also generate informational events when appropriate. Triarch and in-process service clients will receive a processServiceInfo() event. These events never indicate a change in the service’s state. Services have a text() method which provides a textual explanation of the current state of the service.

SFC Developer’s Guide 76

Page 91: sfc

4.2 SFC MODELS

Figure 4.11 shows the various service states and state transitions.

Figure 4.11: Publishing Service - States and Variables

4.2.2.11 Publishing Entitlement DataSome publishing applications are required to provide entitlement data for each item that is published. The entitlement data can be used by downstream components to determine whether a given user is allowed to access the data for a particular item from that service.

OverviewThe RTRRTRecordImpl class provides methods to set entitlement data for each record and to propagate an event indicating the existence of the entitlement data. The RTRRTRecordImpl::setEntitlementData() method is used to set new entitlement data. The entitlement data is passed in the form of an RTREntitlementData object. After setting the entitlement data, the RTRRTRecordImpl::indicateEntitlementData() is used to propagate an EntitlementData

NOTE: Some DACS specific configuration must occur in order for respective entitlement data to be published properly. See section 5.3 Entitlements for implementation specific details.

Stale

Ok

Inactive

Inactive

(stale = True, active = True)Stale

(stale = False, active = True)Ok(stale = XX, active = False)Inactive

Sync

Inactive

Stale

SFC Developer’s Guide 77

Page 92: sfc

4.2 SFC MODELS

event to downstream components. This event indicates that entitlement data or updated entitlement data is available for the record.

The RTREntitlementData class encapsulates a buffer containing the entitlement data and a format attribute which identifies the format in which the entitlement data is encoded. A pre-defined format (RTREntitlementData::DacsAccessLockFormat) is provided for using the DACS entitlement system, the standard entitlement system for RMDS. The purpose of the format attribute is to allow different entitlement data formats to be provided in the future.

The following code segment shows how entitlement data is created with a DACS access lock, then published to a record. This code segment assumes that a DACS access lock has already been created and that the appropriate RTRRTRecordImpl instance has been obtained:

SFC Developer’s Guide 78

Page 93: sfc

4.2 SFC MODELS

#include "rtr/rtrecimp.h"

// int lockLength;// unsigned char* lockPtr;// RTRRTRecordImpl& publishedRec;

RTREntitlementData *edata = 0;

edata = new RTREntitlementData( RTREntitlementData::DacsAccessLockFormat, lockPtr, lockLength);

publishedRec.setEntitlementData( edata );publishedRec.indicateEntitlementData();delete edata;

Entitlement data can be set on a record at any time during the life of the record. However, in order to ensure that downstream users are only allowed access to data for which they are entitled, entitlement data must be provided before the initial image is published for the record. After the record and entitlement data are cached, the SFC record publishing implementation will respond to further requests for that record by first sending any entitlement data associated with the record and then sending the image.

Entitlement data can also be updated later at the discretion of the data provider. The new entitlement data must be set in the record and another RTRRTRecordImpl::indicateEntitlementData() call must be made to propagate an EntitlementData event to downstream components.

For more details on how to set up your system to publish entitlement data and more implementation details, see section 5.3.

4.2.2.12 Managing Record Resources

OverviewData provider components that are interactive typically find it useful to know when interest in a given record has been added or dropped. One possible use for these events would be to remove records that have not been actively monitored for some period of time.

SFC Developer’s Guide 79

Page 94: sfc

4.2 SFC MODELS

To receive interest add and drop events from RTRRTRecordImpl, the data provider component registers with the published record. The registered published record client will then receive events whenever the first client adds interest in the record and when the last client drops interest in the record.

The typical use of this capability is to better manage memory and CPU resources by removing records that are not being used by downstream clients. Note that the actual number of downstream clients using the item is not available to the data provider component; this information may not be available to the published record as it may be publishing to a distributed network.

Registering and receiving client interest eventsA data provider component may receive events from an instance of RTRRTRecordImpl by inheriting from RTRRTRecordImplClient and registering with the record using the RTRRTRecordImpl::addClient() method. Once registered, the data provider component will receive events indicating either the presence or absence of interested downstream client components for the published record.

The processHasEventClient() method is invoked by the published record when a transition from no interested clients to one or more interested clients has occurred. The processNotHasEventClient() method is invoked by the published record when a transition from one or more interested clients to no interested clients has occurred.

The data provider component can also use the RTRRTRecordImpl::dropClient() method to deregister for the client interest events.

4.2.3 Class SummaryThis section provides a summary of the classes which comprise the model for publishing real-time record data. For more details please refer to the appropriate sections of the alphabetical class reference.

• RTRRTRecordImpl - This class defines an item of real-time record data. Record implementations provide methods used both to populate fields in a record and to access the fields either sequentially or in random fashion. Record implementations have state which may change over time. Data and state change events are propagated to other application components which

NOTE: Not all implementations of RTRRTRecordImpl support interactive, sink-driven requests for items. Therefore, registered data provider components may or may not receive these notifications depending on the particular implementation of RTRRTRecordImpl being used. See

SFC Developer’s Guide 80

Page 95: sfc

4.2 SFC MODELS

have registered with a record for the purpose of receiving record data and state change events. Record implementations have their own event clients that are notified whenever the number of consumers monitoring the record transitions from zero to one or from one to zero. There may be multiple clients of a record implementation.

• RTRRTRecordImplClient - This is the abstract base class for application components which wish to register with one or more real-time record implementations in order to receive data and state change events from those records.

• RTRRTRecordImplIterator - Instances of this class provide sequential access to all the constituent fields within a given record implementation.

• RTRRTFieldUpdateList- Instances of this class are used during update events to provide sequential access to those fields within a real-time record implementation that have been modified.

• RTRRTField - This class defines the base type for the constituent parts of a record. Fields are identified by name or FID, have a specific type, and provide various forms of access to the underlying data which they represent.

• RTRRTAlphanumericField, RTRRTDateField, RTRRTEnumeratedField, RTRRTIntegerField, RTRRTPriceField - These descendants of RTRRTField provide type-specific interpretation of the underlying data. These instances are created by the data provider and added into a record implementation instance.

• RTRRTRecordServiceImpl - This class provides methods used by application components to control the creation/deletion of record implementations, to manipulate the state of the service, and to propagate state change events to interested service consumers. A RTRRTRecordServiceImpl implements all the caching and memory management of record implementations.

• RTRRTRecordServiceImplClient - This is the abstract base class for components that need to register with one or more instances of record service implementation in order to receive state change events whenever a new record is added to the service due to service consumer demand.

• RTRRTRecordServiceImplIterator - Instances of this class provide sequential access to all the constituent published records within a given publishing service implementation

• RTRFidDb - This class represents the database of field definitions used by a particular service.

• RTRFidDbClient - This is the abstract base class for components that need to register with a RTRFidDb to receive events when the database has completed initialization or when an error has occurred while initializing the database.

SFC Developer’s Guide 81

Page 96: sfc

4.2 SFC MODELS

• RTRFidDefinition - This class represents the definition for an individual field. A definition comprises the identification (name and FID) of a field and the type. The type determines the way in which the raw data should be interpreted; the identity defines the meaning of the field.

• RTREntitlementData - This class represents entitlement data which is used to entitle users in downstream components. The class encapsulates a buffer of entitlement data and a format attribute identifying the encoding format for the data.

4.2.4 ImplementationCurrently, the SFC provides three implementations of the record publication classes—an SSL publisher, a TIB publisher, and an in-process publisher. The names of these publishing service implementations are based on the relationship of how the data is published into the service and how the data is published out to downstream client components. Specifically,

• RTRRTFieldToSSLRecordService - publishes records to the SSL infrastructure, to the RMDS on the Market Data Hub, or to a directly connecting SSL-based application.

• RTRRTFieldToTIBRecordService - publishes records to the TIB infrastructure or to the RMDS on the Rendezvous Distribution Layer.

• RTRRTFieldToFieldRecordService - publishes records to other in-process components as a RTRRTRecordService service type.

The following table provides a comparison of the main features of the different publishing service implementations

Feature SSL Publisher

TIB Publisher

In-process Publisher

Supports source-driven, non-interactive mode X X X

Supports sink-driven, interactive mode X X

Client applications can connect directly to publisher X

Publishing service can be used within the application process as a RTRRTRecordService object. (E.g. can be added to a service pool)

X X X

Table 4.9: Publishing Service Implementations - Feature Comparison

SFC Developer’s Guide 82

Page 97: sfc

4.2 SFC MODELS

4.2.4.1 SSL Publishing ServiceThe RTRRTFieldToSSLRecordService class provides users with the ability to publish real-time record data for a single service name to multiple SSL client applications, SSL infrastructure components, and RMDS Market Data Hub components.

User application code determines exactly which record symbols will be published, where the record data comes from, and how the data updates and changes state. As a descendant of the RTRRTRecordServiceImpl, this service inherits methods that let publishing components register for notifications when users request new records, manipulate the contents of the service record cache and modify the state of the service.

Client connectivityClient applications that can connect to this service include any user application using SSL 4.X or higher libraries and infrastructure components that support connecting into a source application, like the 4.1.X and higher version of Source Distributor.

In contrast to earlier versions, this publishing service implementation allows client applications to connect directly to the publishing application. The RTRSSLConnectionServer opens a well-known port

Can publish to 4.2 Source Distributor or later X

Can publish to RTIC in SASS2 mode X

Can publish to RTIC in SASS3 mode X

Can publish in Marketfeed format X

Can publish in TIBMsg self-describing format X

Can publish DACS entitlement data X

Caches items locally X X X

Feature SSL Publisher

TIB Publisher

In-process Publisher

Table 4.9: Publishing Service Implementations - Feature Comparison

SFC Developer’s Guide 83

Page 98: sfc

4.2 SFC MODELS

("triarch_sink” by default) that client applications connect to using SSL 4.X or higher protocol. From the perspective of the client application, the SSL publishing service looks like a Sink Distributor.

Multiple instances of publishing services may use the same connection server to allow client applications to access all services over the same connection. Several different constructors are available to provide programmers flexibility in choosing which services publish to which port.

The RTRSSLConnectionServer class manages the well-known port that downstream applications use to establish communications with SSL publishing services. This class is used by SSL publishing services to find out when new downstream connections have been established so that the publishing services can be made available on the channel.

For applications publishing a single service, an instance of RTRSSLConnectionServer is typically created automatically by the publishing service (based on which service constructor is used).

Alternatively, application components can create an instance of this class and pass it to one or more publishing services. This is typically done when the application is publishing multiple services and each service needs to share the same downstream connection.

Another reason to create and pass an instance of RTRSSLConnectionServer to publishing services is if multiple well-known ports will be used on a given machine to publish services. In this case a different instance of RTRSSLConnectionServer would be created for each publishing service and given different well-known ports.

By default, RTRSSLConnectionServer uses port service "triarch_sink." This is the default port used by the Source Distributor (version 4.1 and later) and by SSL and SFC-based end user applications to access market data.

If the connection server is unable to open the well-known port, it will continue retrying the port at 5-second intervals and will log a message. This condition would typically occur if another application already has the port open.

Application structureTypically, an application is structured so that an instance of RTRRTFieldToSSLRecordService is created during initialization (the program’s "main” for instance) and then passed to application components as a RTRRTRecordServiceImpl. This allows the data provider code to focus only on its

NOTE: SFC-based client applications can connect directly to an SFC publishing application. This is new in the 4.1 release.

SFC Developer’s Guide 84

Page 99: sfc

4.2 SFC MODELS

given task, publishing data via the RTRRTRecordServiceImpl instance. This also hides the implementation type from the vast majority of your application code, allowing your application to easily switch between publisher implementations.

After construction, this service will be in the Active/Stale state. It is the responsibility of the programmer’s application code to determine when the service should transition to Active/NotStale. As client applications connect to the service, an indication of the state of the service will be sent to the client application.

4.2.4.2 TIB Publishing ServiceThe RTRRTFieldToTIBRecordService class provides users with the ability to publish real-time record data for a single service name to the RMDS network on a TIBCO Rendezvous Distribution Layer.

User application code determines exactly which record symbols will be published, where the record data comes from, and how the data updates and changes state. As a descendant of the RTRRTRecordServiceImpl, this service inherits methods that manipulate the contents of the service record cache and modify the state of the service.

Note that a TIB publishing service is always non-interactive in nature and must publish to an RTIC process on the RMDS network. This means that the publishing application will not receive notifications from RMDS when users request items not already cached in an RTIC. The RTIC is not capable of forwarding item requests to publishing applications. So publishing applications must publish all items that might be requested by subscriber applications to the RMDS network on a TIBCO Rendezvous Distribution Layer. Typically this would occur when the application is initialized, before the application connects to the RMDS network on a TIBCO Rendezvous Distribution Layer. Once the connection to RMDS is established, the publishing service will send initial images for all cached items to the RMDS.

Mapping SFC symbol names to TIB subject namesWhen publishing records to an RMDS network on a TIBCO Rendezvous Distribution Layer, SFC tries to infer the suitable 4-part subject name using the SFC service name and the item name. In cases where the mapping algorithm does not produce the appropriate 4-part subject name, the application programmer may override methods in the RTRTIBCustomizer class to provide the name mapping required by the publishing application. See section 5.5.7 and see RTRTIBCustomizer in the SFC Reference Manual for more information.

Moreover, while working with RTIC (SASS2), SFC normally prefixes "_TIC." to the subject when publishing to RTIC(SASS2) (unmanaged publication). The *pubSubjectPrefix configuration allows control of the character string required to be prefixed to all subjects published to the RTIC(SASS2).

SFC Developer’s Guide 85

Page 100: sfc

4.2 SFC MODELS

The default is "_TIC."; therefore, the SFC publisher would send the subject "_TIC.A.B.C.D" for publishing of the subject "A.B.C.D" to RTIC.

TIB connectivityThe TIB publishing service will communicate with the RMDS network via the Rendezvous Daemon (RVD). The connection to the rvd is created and handled by the RTRTIBConnection class. The TIB connection can be shared with multiple TIB publishing and subscription services.

By default, the TIB publishing service will create a TIB connection using default parameters. The data provider application may override the default values for these parameters or may create a RTRTIBConnection and pass it into the service at construction.

An application may have multiple instances of publishing services use the same rvd connection by creating a single RTRTIBConnection and passing it into each RTRRTFieldToTIBRecordService instance at construction. Several different constructors are available to provide programmers flexibility in choosing which services publish through which RVD.

See section 4.8.1 and see the SFC Reference Manual for more information on RTRTIBConnection.

Application structureTypically, an application is structured so that an instance of RTRRTFieldToTIBRecordService is created during initialization (the program’s "main” for instance) and then passed to application components as a RTRRTRecordServiceImpl. This allows the data provider code to focus only on its given task, publishing data via the RTRRTRecordServiceImpl instance.

After construction, this service will be in the Active_stale state. It is the responsibility of the programmer’s application code to determine when the service should transition to Active_valid and when it will start publishing records.

4.2.4.3 In-Process RTRRTRecordService PublisherThe RTRRTFieldToFieldRecordService allows developers to create their own implementation of RTRRTRecordService for use within an application. As a descendant of the RTRRTRecordService class, this class provides the standard service interface to consumers of SFC-based real-time record data. As a descendant of RTRRTRecordServiceImpl, this class provides the standard service provider interface for populating the service with records.

SFC Developer’s Guide 86

Page 101: sfc

4.2 SFC MODELS

Typically, an application is structured so that an instance of RTRRTFieldToFieldRecordService is created during initialization (the "main” of the program, for instance) and then passed to application components as an ancestral type. For instance, the data provider component might take a RTRRTRecordServiceImpl whereas the data consumer component would take a RTRRTRecordService. This allows for greater flexibility in changing the implementation type of the publishing service.

At construction, the state of this service set to Active and Stale. It is the responsibility of a data provider component to set the service to the NotStale state when it deems appropriate and to handle all events associated with a publishing service (see RTRRTRecordServiceImpl).

The Field-to-Field implementation allows in-process SFC consumer application components to access the record and service implementations as RTRRTRecord and RTRRTRecordService instances. The Field-to-Field implementation effectively "glues” the provider and consumer SFC interfaces together. The Field-to-SSL implementation publishes record data as an SSL source service, handling all issues regarding publication via the SSL (like creation of SSL and Marketfeed messages).

4.2.5 ExamplesSeveral sample programs have been provided to show different ways in which a record publisher application can be constructed.

Figure 4.12 provides a component version of the various interfaces and implementations. Note that the Data Provider and Data Consumer components are written to the abstract interfaces, then are "plugged in” with a specific implementation of the abstract interface.

While most application components should refer only to the base classes mentioned in the preceding section, the "main” routine or initialization section of an application must instantiate one or more implementation specific classes. Please refer to the alphabetical reference section and the relevant example programs for more details concerning these classes.

Table 4.10 provides a brief overview of the example applications provided with the software distribution. A few representative samples of these programs are detailed in the sections following this table.

You are encouraged to study the examples as a guide to using the SFC record publication classes.

SFC Developer’s Guide 87

Page 102: sfc

4.2 SFC MODELS

Figure 4.12: Component View of the Record Publication Implementations

SFCRealTime

"Consumer”

Interface

SFCRealTime

"Provider”

Interface

Implementation

Fieldto

Field

Implementation

DataProvider

Component

Real-time

Data Flow

Real-timeData

ConsumerComponent

SSLNETWORK

SSL

Implementation

The Components

In-Process Solution

Networked Solutions

Real-timeData

ConsumerComponent

DataProvider

Component

Real-time

DataProvider

Component

Real-time Real-timeData

ConsumerComponent

SSL Publishing Service Record Service

ImplementationTIBNETWORK

TIB

ImplementationData

ProviderComponent

Real-time Real-timeData

ConsumerComponent

TIB Publishing Service Record Service

SFC Developer’s Guide 88

Page 103: sfc

4.2 SFC MODELS

Example Program Description Refers To

Simulator Simple application that publishes canned record data based on user requests. This example shows how to:

• create specific field types • properly initialize publishing services and

records• optionally setting template numbers• change state and propagate state change

events• update record data and propagate data

change events• publish as a sink-driven (interactive) or

source-driven (non-interactive) service.• create necessary components to publish to

TIB, to SSL, or within an application process

simulator.C (main)simrec.Csimsrvc.Cfcsimsrvc.C

(section 4.2.6)

Gateway An application that obtains record data via the sub-scription SFC interfaces and re-publishes the data using the publisher SFC interfaces. This example shows the same capabilities as the Simulator exam-ple, plus how to:

• publish data from an asynchronous data source (an SFC RTRecordService in this case)

• handle differences in field definitions between subscription and publication services

• design a bridging or value-added gateway application using SFC

gateway.C (main)gatesvc.Csinkgates.Csrcgates.Cgaterec.C

(section 4.2.7)

Table 4.10: Record Publication Example Applications

SFC Developer’s Guide 89

Page 104: sfc

4.2 SFC MODELS

This section describes the design and implementation of a new class or "component” and shows how to use that class in an application.

4.2.6 Simulator ProgramAll the code and makefiles for this example are available in the product distribution.

4.2.6.1 RequirementsThe application must respond to requests from downstream clients for canned record data and subsequent update and state change notifications. The main purpose of the program is to show the basics of how to set up a publishing service and use the various methods from the publishing classes. This application also serves to provide all the different types of events associated with a real-time record publisher.

This application can be used as a starting point for most user applications.

Injector An application that extends the gateway application by injecting an extra field into each record that is republished using the provider SFC. This example shows the same capabilities as the Gateway exam-ple, plus how to:

• publish value-added data in a gateway application

injector.C (main)gatesvc.Cgaterec.Cinjectsvc.Csrcinjectsvc.Cinjectrec.C

Aggregator An application that extends the gateway application by publishing record updates at specific time inter-vals. This example shows the same capabilities as the Gateway example, plus how to:

• write a gateway application that supplies data updates at regular intervals rather than as the updates occur in the market.

aggregator.C (main)gatesvc.Cgaterec.Caggsvc.Csrcaggsvc.Caggrec.C

Example Program Description Refers To

Table 4.10: Record Publication Example Applications (Continued)

SFC Developer’s Guide 90

Page 105: sfc

4.2 SFC MODELS

4.2.6.2 Design and ImplementationThe application consists of three components: SimulatedService publisher, SimulatedRecord publisher and a program main. The SimulatedService publisher may be replaced by the FullCacheSimulatedService publisher for cases where records need to be pre-loaded onto the system.

The SimulatedService component will register with a publishing service (of type RTRRTRecordServiceImpl) and create simulated records whenever a new published record is added into the publishing service due to a request from a downstream client components. Note that this class will only work if the publishing service implementation has the ability to forward requests from downstream components.

Before handling new records, the simulated service makes sure that the FID database is completely populated because the FID database’s definitions are needed for creating new record fields. To do this, the service checks the state of the FID database. If the FID database is not in the Complete state, then the simulated service registers with the FID database to be notified when it is complete or when an error occurs. Once the FID database is complete, the simulated service may handle requests and populate records with fields.

The SimulatedRecord provides an initial set of fields to the given published record (RTRRTRecordImpl) and subsequent state and data changes and events. The state and data changes occur automatically in each SimulatedRecord based on random time intervals. The data provided to the published record is hard-coded into the SimulatedRecord, so the record can be populated as soon as the request for the new symbol is received.

The simulated record will produce many of the possible state and data change events that a record can transition through as well as a variety of event combinations. In this respect, the SimulatedRecord represents an interesting test of the ability of the downstream components to handle various events that may rarely occur on live systems.

NOTE: This type of sink-driven, or interactive, service model will not work with the TIB implementa-tion because new requests will not be forwarded to the publisher on an RMDS (RTIC) system. Rather, requests are always made to an RTIC process on the RMDS network. To work on RTIC, the simulated service must pre-load records into the publishing service. See the FullCacheSimulated-Service class in section 4.2.6.5 for details.

SFC Developer’s Guide 91

Page 106: sfc

4.2 SFC MODELS

4.2.6.3 SimulatedService Class DeclarationThis section contains the contents of a header file (simsrvc.h) which declares the class SimulatedService as designed in section 4.2.6.2. Note that the class inherits from RTRRTRecordServiceImplClient so the processNewRecord() method can be called whenever a new record is requested by a downstream client component.

#ifndef _simsrvc_h#define _simsrvc_h

#include "rtr/rtrsvimp.h"#include "rtr/logevnt.h"#include "rtr/objid.h"

class SimulatedService: public virtual RTRRTRecordServiceImplClient

public RTRFidDbClient{public:

SimulatedService(RTRObjectId& context, RTRRTRecordServiceImpl& s, int lowRangeUpdateRate = 3, int highRangeUpdateRate = 60);

virtual ~SimulatedService();

void processNewRecord(RTRRTRecordServiceImpl&, RTRRTRecordImpl&);

void processFidDbComplete(RTRFidDb&);void processFidDbError(RTRFidDb&);

protected:RTRRTRecordServiceImpl& _implService; RTRObjectId _instanceId;RTRLogEvent _logEvent;int _lowRangeUpdateRate;int _highRangeUpdateRate;

};

#endif

SFC Developer’s Guide 92

Page 107: sfc

4.2 SFC MODELS

4.2.6.4 SimulatedService Class DefinitionThis section contains the source file which implements the class SimulatedService as declared in the previous section (in simsrvc.h).

At construction, the simulated service checks to see if the fidDb of the publishing service is complete. If not, the service registers (as a descendant of RTRFidDbClient) with the FID database so it can be called back when the FID database becomes complete.

When the FID database is complete, the simulated service initializes the publishing service by updating its text, setting its state to NotStale and sending a Sync event to downstream components. The simulated service also registers to receive events from the publishing service.

As a descendant of RTRRTRecordServiceImplClient, the simulated service inherits the processNewRecord() method. This method will be called by the publishing service whenever a new record is being requested by a downstream client (like an SSL or TIB consumer application).

When the processNewRecord() method is called, the simulator service simply creates a new instance of SimulatedRecord, providing it with the published record, FID database and high and low intervals for sending new events to the record (remember, the simulated record sends canned data and events, so it must determine when to send the events). The simulated record will then handle all data and state changes associated with that published record.

#include "simsrvc.h"#include "simrec.h"

SimulatedService::SimulatedService(RTRObjectId& context,RTRRTRecordServiceImpl& s,int lr,int hr)

: _implService(s), _instanceId(context, s.name()), _lowRangeUpdateRate(lr), _highRangeUpdateRate(hr)

{_logEvent.setComponent(_instanceId);

NOTE: The processNewRecord() method will only be called if a new record is added to the publish-ing service due to demand from downstream client components. Any future requests for a record that is already populated in the publishing service will be handled by the publishing service; the sim-ulated service will not be notified.

SFC Developer’s Guide 93

Page 108: sfc

4.2 SFC MODELS

if (implService.fidDb().complete()){

initPubService();}else{

_implService.setText("Waiting for fid db to initialize...");_implService.indicateInfo();

RTRFidDb*fidDb = (RTRFidDb*)&_implService.fidDb();fidDb->addClient(*this);

}

void SimulatedService::initPubService(){

_implService.setText("Ready!");_implService.setNotStale();_implService.indicateSync();_implService.setClient(*this);

}

SimulatedService::~SimulatedService(){

_implService.unsetClient();}

void SimulatedService::processNewRecord(RTRRTRecordServiceImpl&, RTRRTRecordImpl& newRecord)

{RTRString tmp("Got NewRecord event for record ");tmp.append(newRecord.symbol());_logEvent.setText(tmp);_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

// Create a new SimulatedRecord, passing the new RTRRTRecordImpl// instance that was added to the impl service.//

SimulatedRecord *simRec = new SimulatedRecord(_instanceId,

SFC Developer’s Guide 94

Page 109: sfc

4.2 SFC MODELS

newRecord, _implService.fidDb(),_lowRangeUpdateRate, _highRangeUpdateRate);

};

void SimulatedService::processFidDbComplete( RTRFidDb& fidDb){

// Now that the fid db is complete, activate the service.initPubService();

}

void SimulatedService::processFidDbError( RTRFidDb& fidDb){

_implService.setText(fidDb.errorText());_implService.indicateInfo();

}

4.2.6.5 FullCacheSimulatedService ClassIn cases where the application must run in a source-driven mode, the FullCacheSimulatedService will be used in place of the SimulatedService class. The only difference between the two classes is that the FullCacheSimulatedService pre-loads records into the SFC service publisher and disallows requests from records that are not already cached. Note that the name "FullCache" is another term for source-driven or non-interactive.

A single extra method load() is called when the service is initialized. This method creates new records from a list of symbols read in from a configuration parameter. After the records are loaded in, the service will not accept any requests for different records. The processNewRecord() method shows how to decline any new records and how to remove those records from the SFC service publisher cache.

void FullCacheSimulatedService::load(){

// Get a list of symbols to retrieve. If no configuration// variable is present, use the default RTRSY.O//

RTRListOfExternalValue ricList = RTRConfig::configDb().variable(_classId,

SFC Developer’s Guide 95

Page 110: sfc

4.2 SFC MODELS

_instanceId,"symbolList","RTRSY.O").list(’,’);

RTRRTRecordImpl *_implRecord = 0;for (ricList.start(); !ricList.off(); ricList.forth()){

// Check for duplicate symbols. if (!_implService.hasRTRecordImpl(ricList.item())){

// Create a new record in the _implService.//

_implRecord = &(_implService.newRTRecordImpl( ricList.item() ));

// Create new SimulatedRecord, passing new RTRRTRecordImpl// instance that was added to the impl service.//

SimulatedRecord *simRec = new SimulatedRecord(_instanceId,*_implRecord, _implService.fidDb(),_lowRangeUpdateRate, _highRangeUpdateRate);

if (!simRec->active())delete simRec;

}}

}

void FullCacheSimulatedService::processNewRecord(RTRRTRecordServiceImpl& service, RTRRTRecordImpl& newRecord)

{// As a Full Cache service, only the records that were pre-loaded// into the cache will be made available. By setting the text on // the newRecord and calling indicateInactive(), we are able to provide// some reason why the request will not be accepted. //// As an alternative, this application component could have not// become a client of the RTRRTRecordServiceImpl, in which case// the implService would handle requests for un-cached items. In // particular, a canned text string ("Item Not Available") would

SFC Developer’s Guide 96

Page 111: sfc

4.2 SFC MODELS

// be returned to the user requesting this item.

// Set the record’s text to something appropriate.//

newRecord.setText("Cannot satisfy request. Not configured to cache this record");

// Change the record’s state to Inactive.//

newRecord.setInactive();newRecord.indicateInactive();

// Remove this new record from the service’s cache._implService.removeRTRecordImpl(newRecord.symbol());

// Log a message via the event logger.RTRString tmp("Rejecting user request for record ");tmp.append(newRecord.symbol());_logEvent.setText(tmp);_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

};

4.2.6.6 SimulatedRecord Publisher Class DeclarationThis section contains the contents of a header file (simrec.h) which declares the class SimulatedService as designed in section 4.2.6.2. The class declares several methods that are used to take the different actions available through the RTRRTRecordImpl interface. This class inherits the RTRRTRecordImplClient class so it can register with its RTRRTRecordImpl to receive notifications whenever the record transitions between watched and unwatched.

Note that a static template number variable is declared. This may be used to set up a template number to be published to all records. This may be required by some downstream client applications.

#ifndef _simrec_h#define _simrec_h

#include "rtr/rtrecimp.h" // RTRRTRecordImpl#include "rtr/random.h" // Random number generator#include "rtr/vardatti.h" // Date/Time class#include "rtr/timercmd.h" // RTRTimerCmd class#include "rtr/logevnt.h" // RTRLogEvent

SFC Developer’s Guide 97

Page 112: sfc

4.2 SFC MODELS

#include "rtr/objid.h" // RTRObjectId#include "rtr/fid_db.h" // RTRFidDb

class SimulatedRecord : public RTRRTRecordImplClient, public RTRTimerCmd

{public:

SimulatedRecord(RTRObjectId& context,RTRRTRecordImpl& record, const RTRFidDb& fidDb,long lowRange, long highRange);

virtual ~SimulatedRecord();

// Inherited From RTRTimerCmdvoid processTimerEvent();

void setTimer();

// Inherited From RTRRTRecordImplClientvoid processHasEventClient(RTRRTRecordImpl&);

void processNotHasEventClient(RTRRTRecordImpl&);

// Update event propagationvoid sendUpdate();

void sendCorrection();

void sendClosingRun();

// State change event propagationvoid sendInfo();

void sendStale();

void sendNotStale();

SFC Developer’s Guide 98

Page 113: sfc

4.2 SFC MODELS

void sendResync();

// Utilityvoid updateFields();

void initializeFields(const RTRFidDb&);

protected:RTRRandomNumberGenerator _randomValue;RTRRTFieldUpdateList _updList;RTRRTRecordImpl& _record;RTRObjectId _instanceId;RTRLogEvent _logEvent;RTRVariableDateTime _dateTime;int _counter;int _bidVal;int _tradeVal;int _askVal;int _acvolVal;

};

#endif

4.2.6.7 SimulatedRecord Class DefinitionThis section contains the source file which implements the class SimulatedRecord as declared in the previous section (in simrec.h).

At construction, the simulated record initializes the given published record by adding fields to the published record, setting the descriptive text of the published record, changing the state to NotStale and then sending a RecordSync event to downstream components. The simulated record also registers with the published record to receive watched/not-watched events.

The initializeFields() method shows how to create each of the defined field types, initialize the data for the field and add the field to the published record. The updateFields() method shows how to update fields in the published record.

A timer is set in the constructor to determine when to send different events. The processTimerEvent() method is called when the timer expires. The various helper methods are then used to update the data

SFC Developer’s Guide 99

Page 114: sfc

4.2 SFC MODELS

fields and to modify the state of the record. Associated events are sent to downstream client components through the RTRRTRecordImpl interface methods. After taking the appropriate action, the simulated record gets the next random time interval (between the high and low ranges) and activates the timer again. This continues for the life of the simulated record.

As a registered RTRRTRecordImplClient, the simulated record prints out a message whenever a transition occurs between having and not having downstream event clients.

The simulated record will continue running indefinitely.

#include "simrec.h"#include "rtr/rtstrhsh.h"

SimulatedRecord::SimulatedRecord(RTRObjectId& context,RTRRTRecordImpl& record, const RTRFidDb& fidDb,long lowRange, long highRange)

: _record(record), _updList(record), _bidVal(1), _askVal(3), _tradeVal(2), _counter(1), _instanceId(context,record.symbol()), _randomValue((int)strHashFunction(

record.symbol()),highRange, lowRange)

{_logEvent.setComponent(_instanceId);

_record.addClient(*this);

// Create and add fields to the record impl.initializeFields(fidDb);

_record.setText("Ready.");_record.setNotStale();_record.indicateSync();

setTimer();activate();

}

SimulatedRecord::~SimulatedRecord()

SFC Developer’s Guide 100

Page 115: sfc

4.2 SFC MODELS

{_record.dropClient(*this);

// Clean up memory allocated by this record._record.deleteAllFields();

}

// From RTRTimerCmdvoid SimulatedRecord::processTimerEvent(){

// Do different kinds of data and state// events periodically.

_counter++;if (!(_counter % 4)){

if (_record.stale())sendInfo();

elsesendStale();

}else if (!(_counter % 5)){

sendResync();}else if (!(_counter % 3)){

sendCorrection();}else if (!(_counter % 120)){

sendClosingRun();}else

sendUpdate();

// Wait some random amount of time before executing// the next event. The time interval is between the// lowRange and highRange values provided at// construction.

SFC Developer’s Guide 101

Page 116: sfc

4.2 SFC MODELS

setTimer();activate();

}

void SimulatedRecord::setTimer(){

_randomValue.getNext();setTimerOffset(_randomValue, 0);

}

// From RTRRTRecordImplClientvoid SimulatedRecord::processHasEventClient(RTRRTRecordImpl&){

_logEvent.setText("Users are now monitoring this record.");_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

}

void SimulatedRecord::processNotHasEventClient(RTRRTRecordImpl&){

_logEvent.setText("Users are no longer monitoring this record.");_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

}

void SimulatedRecord::updateFields(){

static RTRString val;RTRRTField *fld = 0;_tradeVal++;_bidVal++;_askVal++;_acvolVal += 100;

_updList.reinitialize(_record);

// Update the TRDPRC_1 (fid 6) field. Note the// use of the RTRRTRecordImpl and RTRRTFieldUpdateList// methods that take fid numbers for parameters.

val.clear();

SFC Developer’s Guide 102

Page 117: sfc

4.2 SFC MODELS

fld = _record.field(6);if (fld){

val.append(_tradeVal);fld->set(val,val.count());fld->indicateFieldUpdated();_updList.putFieldByFid(6);

}

// Update the BID (fid 22) field. Note the// use of the RTRRTRecordImpl and RTRRTFieldUpdateList// methods that take the fid names for parameters.

val.clear();fld = _record.fieldByName("BID");if (fld){

val.append(_bidVal);fld->set(val,val.count());fld->indicateFieldUpdated();_updList.putFieldByName("BID");

}

val.clear();fld = _record.fieldByName("ASK");if (fld){

val.append(_askVal);fld->set(val,val.count());fld->indicateFieldUpdated();_updList.putField(*fld);

}

val.clear();fld = _record.fieldByName("ACVOL_1");if (fld){

val.append(_acvolVal);fld->set(val,val.count());fld->indicateFieldUpdated();_updList.putField(*fld);

SFC Developer’s Guide 103

Page 118: sfc

4.2 SFC MODELS

}

val.clear();fld = _record.fieldByName("TRDTIM_1");if (fld){

_dateTime.setToSystemTime();val.append(_dateTime.hours());val.append(":");val.append(_dateTime.minutes());val.append(":");val.append(_dateTime.seconds());fld->set(val,val.count());fld->indicateFieldUpdated();_updList.putField(*fld);

}}

void SimulatedRecord::sendUpdate(){

_record.indicateUpdateTick();updateFields();_record.indicateUpdateComplete(_updList);

}

void SimulatedRecord::sendCorrection(){

_record.indicateCorrectionTick();updateFields();_record.indicateUpdateComplete(_updList);

}

void SimulatedRecord::sendClosingRun(){

// Update the record and indicate.//

_record.indicateCloseTick();updateFields();_record.indicateUpdateComplete(_updList);

}

SFC Developer’s Guide 104

Page 119: sfc

4.2 SFC MODELS

void SimulatedRecord::sendInfo(){

// Notify info_record.setText("Informational message...");_record.indicateInfo();

}

void SimulatedRecord::sendStale(){

// Notify info_record.setText("GOING STALE NOW");_record.setStale();_record.indicateStale();

}

void SimulatedRecord::sendNotStale(){

_record.setText("OK NOW");_record.setNotStale();_record.indicateNotStale();

}

void SimulatedRecord::sendResync(){

_record.setText("Resyncronized");if (_record.stale())

_record.setNotStale();else

_record.setStale();_record.indicateResync();updateFields();_record.indicateResyncComplete(_updList);

}

void SimulatedRecord::initializeFields(const RTRFidDb& fidDb){

const RTRFidDefinition *fidDef = 0;RTRRTField *fld = 0;char *farea = 0;

SFC Developer’s Guide 105

Page 120: sfc

4.2 SFC MODELS

// Add DSPLY_NAME field using this record’s symbol as// the field’s value. This is an example of creating// an Alphanumeric field.//// NOTE: Could also use fidDb.defByFid(3) here.//

fidDef = fidDb.defByName("DSPLY_NAME");if (fidDef){

// NOTE: Always add 1 character for end-of-field delimiter.//

farea = new char[fidDef->length() + 1];fld = new RTRRTAlphanumericField(*fidDef, farea, 0);fld->set(_record.symbol(), _record.symbol().count());_record.putField(*fld);

}

// Add TRDPRC_1 field - a Price field//// NOTE: Could also use fidDb.defByName("TRDPRC_1") here.//

fidDef = fidDb.defByFid(6);if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("2", 1);_record.putField(*fld);

}

// Add ACVOL_1 field - an Integer field//

fidDef = fidDb.defByName("ACVOL_1");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTIntegerField(*fidDef, farea, 0);fld->set("200", 1);_record.putField(*fld);

SFC Developer’s Guide 106

Page 121: sfc

4.2 SFC MODELS

}

// Add TRADE_DATE field - a Date field//

fidDef = fidDb.defByName("TRADE_DATE");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTDateTimeField(*fidDef, farea, 0);

// NOTE: Date format is "MM/DD/YY" //

_dateTime.setToSystemTime();RTRString tmp;tmp.append(_dateTime.monthNumber());tmp.append("/");tmp.append(_dateTime.dayOfMonth());tmp.append("/");tmp.append(_dateTime.year());

fld->set(tmp, tmp.count());_record.putField(*fld);

}

// Add TRDTIM_1 field - a Time field//

fidDef = fidDb.defByName("TRDTIM_1");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTDateTimeField(*fidDef, farea, 0);

// NOTE: Time format is "HH:MM:SS" or "HH:MM"//

_dateTime.setToSystemTime();RTRString tmp;tmp.append(_dateTime.hours());tmp.append(":");tmp.append(_dateTime.minutes());

SFC Developer’s Guide 107

Page 122: sfc

4.2 SFC MODELS

fld->set(tmp, tmp.count());_record.putField(*fld);

}

// Add RDN_EXCHID field - an Enumerated field//

fidDef = fidDb.defByName("RDN_EXCHID");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTEnumeratedField(*fidDef, farea, 0,

*fidDb.enumTableByName("RDN_EXCHID")); fld->set("NYS", 3);_record.putField(*fld);

}

// Add TRDPRC_2 field//

fidDef = fidDb.defByName("TRDPRC_2");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0); fld->set("0", 1);_record.putField(*fld);

}

// Add TRDPRC_3 field//

fidDef = fidDb.defByName("TRDPRC_3");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}

// Add TRDPRC_4 field//

SFC Developer’s Guide 108

Page 123: sfc

4.2 SFC MODELS

fidDef = fidDb.defByName("TRDPRC_4");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}

// Add TRDPRC_5 field//

fidDef = fidDb.defByName("TRDPRC_5");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}

// Add BID field//

fidDef = fidDb.defByName("BID");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("1", 1);_record.putField(*fld);

}

// Add BID_1 field//

fidDef = fidDb.defByName("BID_1");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

SFC Developer’s Guide 109

Page 124: sfc

4.2 SFC MODELS

}

// Add BID_2 field//

fidDef = fidDb.defByName("BID_2");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}

// Add ASK field//

fidDef = fidDb.defByName("ASK");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("3", 1);_record.putField(*fld);

}

// Add ASK_1 field//

fidDef = fidDb.defByName("ASK_1");if (fidDef){

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}

// Add ASK_2 field//

fidDef = fidDb.defByName("ASK_2");if (fidDef){

SFC Developer’s Guide 110

Page 125: sfc

4.2 SFC MODELS

farea = new char[fidDef->length() + 1];fld = new RTRRTPriceField(*fidDef, farea, 0);fld->set("0", 1);_record.putField(*fld);

}}

4.2.6.8 Creating an ApplicationThe preceding sections showed how to design, declare and implement simulator publishing components that can publish to any system. This section shows how to include the new classes in an application. The Simulator program that is provided in the product distribution has the ability to run on either RMDS or Triarch systems or strictly in-process. It also can run in sink-driven (interactive) or source-driven (non-interactive) modes.

This section will show how to create and combine the right components to accomplish each of these configurations. The code snippets shown in this section have been taken from the simulator.C source file and reorganized based on the implementation that is being used - SSL, TIB or in-process.

There actually are not many differences required in the code to run with the different service implementations. The basic sequence of events used to create an application is:

1. Include required header files.

2. Create any required utility objects, like the application identifier, configuration database and event logger. These need to be created first because other components will use them.

3. Create the specific type of SFC publishing service that is required. This could be one of the following publishing service types: RTRRTFieldToSSLRecordService, RTRRTFieldToTIBRecordService or RTRRTFieldToFieldRecordService.

4. Create the specific type of simulated service that is required. This could be either the SimulatorService for sink-driven, interactive mode or the FullCacheSimulatedService for source-driven, non-interactive mode. The simulated service will be given the SFC publishing service created in step 2.

5. Create record display components, if necessary. In this application, this is only necessary for displaying data from a RTRRTFieldToFieldRecordService. In that case, the dat aif printed to stdout.

6. Initialize the main-loop notifier to start handling I/O and timer events.

SFC Developer’s Guide 111

Page 126: sfc

4.2 SFC MODELS

7. Clean-up when the program is exiting.

Application code for running SimulatedService on SSLThe following code includes the header files needed by most SFC application, independent of any downstream infrastructure that is being used:

#include <iostream.h>#include "rtr/selectni.h"// RTRSelectNotifier#include "rtr/rtxfdb.h"// RTRXFileDb, RTRConfig#include "rtr/dfltlog.h"// RTRDefaultLogger#include "rtr/cmdline.h"// RTRCmdLine

These headers are needed to publish to a Triarch system:

#include "rtr/fldtossl.h"// RTRRTFieldToSSLRecordService#include "rtr/ufdb.h" // RTRFileFidDb

This header is needed to publish simulated data in a sink-driven mode.

#include "simsrvc.h" // SimulatedService

This code creates utility objects that allow SFC components to read configuration information and log events to log files and stderr. The logger makes use of the configDb, so the configDb is instantiated first:

RTRObjectId appId("Simulator");// Initialize the configuration database

configDb = new RTRXFileDb(clConfigPath.stringValue());if (configDb->error()){

cerr << "Config error: " << configDb->errorText() << endl;cleanup(-2, argv[0]);

}RTRConfig::setConfigDb(*configDb);

RTRDefaultLogger logger(appId, "logger");

This code creates the publishing service and the simulated service that will provide data to the publishing service. Note that the RTRRTFieldToSSLRecordService has several different constructors that may be used. This particular one takes a FID database at construction, but uses default values to create the well-known port that downstream Triarch components and user applications will connect to:

SFC Developer’s Guide 112

Page 127: sfc

4.2 SFC MODELS

initSSLFidDb();pubService = new RTRRTFieldToSSLRecordService(appId,

pubServiceName, *sslfdb);

simService = new SimulatedService(appId, *pubService);

This code creates a Triarch FID database which is loaded from a disk file:

void initSSLFidDb(){

if (!sslfdb){

sslfdb = new RTRFileFidDb (appId, "fidDb");((RTRFileFidDb *) sslfdb)->load();if (sslfdb->error()){

cout<< "FidDb error: " << sslfdb->errorText() <<endl;cleanup(-2);

}}

}

This code initializes the notifier to run and cleans up resources after the notification loop exits. Note that in this example, the system select() version of the notifier is being used. Each implementation of notifier will have a different way to start the main loop. See section 4.8.3 for details.

Note that all cleanup must be done in the opposite order of creation to ensure that resources are properly freed and objects do not reference components that have already been deleted:

RTRSelectNotifier::run();

delete simServicedelete pubService;delete sslfdb;delete logger;delete configDb;return 0;

SFC Developer’s Guide 113

Page 128: sfc

4.2 SFC MODELS

Application code for running FullCacheSimulatedService on RMDS with a TIBCO Rendezvous Distribution LayerThe following code includes the header files needed by most SFC application, independent of any downstream infrastructure that is being used:

#include <iostream.h>#include "rtr/selectni.h"// RTRSelectNotifier#include "rtr/rtxfdb.h"// RTRXFileDb, RTRConfig#include "rtr/dfltlog.h"// RTRDefaultLogger#include "rtr/cmdline.h"// RTRCmdLine

These headers are needed to publish to a TIB system:

#include "rtr/tconnect.h"// RTRTIBConnection#include "rtr/fldtotib.h"// RTRRTFieldToTIBRecordService#include "rtr/tfdb.h" // RTRTIBFidDb

This header is needed to publish simulated data in a source-driven mode. Note that the FullCacheSimulatedService is being used on the RMDS network with a TIBCO Rendezvous Distribution Layer because this simulated service pre-loads the cache with records. This is required as the TIB publishing service implementation will not provide notifications when users on the RMDS network with a TIBCO Rendezvous Distribution Layer access a new record, so the records need to be pre-loaded.

#include "fcsimsrvc.h" // FullCacheSimulatedService

This code creates utility objects that allow SFC components to read configuration information and log events to log files and stderr. The logger makes use of the configDb, so the configDb is instantiated first:

RTRObjectId appId("Simulator");// Initialize the configuration database

configDb = new RTRXFileDb(clConfigPath.stringValue());if (configDb->error()){

cerr << "Config error: " << configDb->errorText() << endl;cleanup(-2, argv[0]);

}RTRConfig::setConfigDb(*configDb);

RTRDefaultLogger *logger = new RTRDefaultLogger(appId, "logger");

SFC Developer’s Guide 114

Page 129: sfc

4.2 SFC MODELS

This code creates the TIB publishing service and the simulated service that will provide data to the publishing service. Note that the RTRRTFieldToTIBRecordService has several different constructors that may be used. This particular constructor takes a context ID, name of the service and a connection at construction. The connection handles connectivity to RTIC via the RVD. The publishing service will automatically download the data dictionary (FID database).

connection = new RTRTIBConnection(appId, "tibconnection", servicePort,network, daemon);

connection->connect();

RTRRTFieldToTIBRecordService *pubService =new RTRRTFieldToTIBRecordService(appId,

pubServiceName, *connection);

simService = new FullCacheSimulatedService(appId, *pubService);

This code initializes the notifier to run and cleans up resources after the notification loop exits. Note that in this example, the system select() version of the notifier is being used. Each implementation of notifier will have a different way to start the main loop. See section 4.8.3 for details.

Note that all cleanup must be done in the opposite order of creation to ensure that resources are properly freed and objects do not reference components that have already been deleted:

RTRSelectNotifier::run();

delete simServicedelete pubService;delete connection;delete logger;delete configDb;return 0;

Application code for running SimulatedService in-processThe following code includes the header files needed by most SFC applications, independent of any downstream infrastructure that is being used:

#include <iostream.h>#include "rtr/selectni.h"// RTRSelectNotifier

SFC Developer’s Guide 115

Page 130: sfc

4.2 SFC MODELS

#include "rtr/rtxfdb.h"// RTRXFileDb, RTRConfig#include "rtr/dfltlog.h"// RTRDefaultLogger#include "rtr/cmdline.h"// RTRCmdLine

This header is needed to publish simulated data in a sink-driven mode

#include "simsrvc.h" // SimulatedService

This header are needed to publish in-process to other SFC consumer components:

#include "rtr/fldtofld.h"// RTRRTFieldToFieldRecordService

This header is needed to display SFC data published within the process:

#include "tickclient.h" // TickerClienttypedef TickerClient *TickerClientPtr;

This header is needed to publish simulated data in a source-driven mode. Note that the FullCacheSimulatedService is being used on the RMDS network with a TIBCO Rendezvous Distribution Layer because this simulated service pre-loads the cache with records. This is required as the TIB publishing service implementation will not provide notifications when users on the RMDS network with a TIBCO Rendezvous Distribution Layer access a new record, so the records need to be pre-loaded.

#include "fcsimsrvc.h" // FullCacheSimulatedService

This code creates utility objects that allow SFC components to read configuration information and log events to log files and stderr. The logger makes use of the configDb, so the configDb is instantiated first:

RTRObjectId appId("Simulator");// Initialize the configuration database

configDb = new RTRXFileDb(clConfigPath.stringValue());if (configDb->error()){

cerr << "Config error: " << configDb->errorText() << endl;cleanup(-2, argv[0]);

}RTRConfig::setConfigDb(*configDb);

RTRDefaultLogger logger(appId, "logger");

This code creates an in-process publishing service and the simulated service that will provide data to the publishing service. The field-to-field publishing service constructor takes a context ID, the name of

SFC Developer’s Guide 116

Page 131: sfc

4.2 SFC MODELS

the service and a FID database at construction. The publishing service is then given to a number of SFC consumer clients that display record data to stdout.

// RTFieldToFieldService is a RTRecordServiceImpl// and a RTRecordService.

initSSLFidDb();RTRRTFieldToFieldRecordService *pubService =

new RTRRTFieldToFieldRecordService(pubServiceName, *sslfdb);

simService = new SimulatedService(appId, *pubService);

createFieldClients(*pubService);

This code initializes several display components that obtain data from an RTRRTRecordService and display it to stdout. Each TickerClient component watches a single record and displays various fields from the record to stdout. Note that the service passed into the createFieldClients() method takes a type of RTRRTRecordService. Since the RTRRTFieldToFieldRecordService implements the RTRRTRecordService (consumer) interface in addition to the RTRRTRecordServiceImpl (publishing) interface, the publishing service is passed directly to the createFieldClients() method.

void createFieldClients(RTRRTRecordService &service){

RTRListOfExternalValue ricList = RTRConfig::configDb().variable(appId, "Simulator", "symbolList", "RTRSY.O").list(’,’);

clients = new TickerClientPtr [ricList.count()];int i = 0;for (ricList.start(); !ricList.off(); ricList.forth(), i++)

clients[i] = new TickerClient(service, ricList.item());}

This code initializes the notifier to run and cleans up resources after the notification loop exits. Note that in this example, the system select() version of the notifier is being used. Each implementation of notifier will have a different way to start the main loop. See section 4.8.3 for details.

Note that all cleanup must be done in the opposite order of creation to ensure that resources are properly freed and objects do not reference components that have already been deleted:

RTRSelectNotifier::run();

delete clients[];delete simServicedelete pubService;

SFC Developer’s Guide 117

Page 132: sfc

4.2 SFC MODELS

delete logger;delete configDb;return 0;

4.2.7 Gateway ExampleAnother example program available in the product distribution is the Gateway program. This section will provide some helpful hints for writing gateway applications that source data from one market-data system via SFC and publish into another market-data system. Many of the basic algorithms used to create records, handle SFC publishing service events, publish record data and events remain the same in this program (and in all programs). The main difference from the Simulator program is that the data and events are obtained from a subscription service or record which works asynchronously.

This sort of application can be used to bridge two different market data systems or to create a new service that implements value-added processing to existing SFC record data. This program acts as a bridge, but can easily be modified to do value-added processing. This is how some of the other example programs provided in the product distribution have been built. Namely, the Injector program adds a calculated mid-price to each record and the Aggregator provides record updates at a specified rate. Each of these programs uses the basic structure of this program.

Note that the application main() has been omitted. See the source file for the Gateway program for details.

4.2.7.1 RequirementsThe application must respond to requests from downstream clients for live record data and subsequent update and state change notifications that are obtained from a different upstream market data system. No translation of the data is made; it is simply published straight to the SFC publishing service.

The main purpose of the program is to show how to set up a gateway publishing service and how to ensure that your application can be made portable across multiple market data systems. This application also shows how an application can respond to new record requests in an asynchronous fashion and apply data updates and state changes in an asynchronous fashion.

This application can be used as a starting point for gateway style applications.

SFC Developer’s Guide 118

Page 133: sfc

4.2 SFC MODELS

4.2.7.2 Design and ImplementationThe application consists of five components: GatewayService publisher, SinkGatewayService, SourceGatewayService, GatewayRecord publisher and a program main. The GatewayService is the base class for the SinkDrivenGatewayService and SourceDrivenGatewayService.

The GatewayService acts as a proxy for an upstream SFC-based service and provides a GatewayRecord cache. All state change events that occur in an upstream SFC service will be immediately reflected in the downstream SFC publishing service. See section 4.2.7.3 and 4.2.7.4 for details.

The SinkDrivenGatewayService is a gateway service implementation that accepts requests for new published records from downstream client components (e.g. Triarch Source Distributor or user applications) and creates new GatewayRecords to supply data and events to the new published records. It also inherits all the functionality of the GatewayService. See section 4.2.7.5 and 4.2.7.6 for details.

The SourceDrivenGatewayService is a gateway service implementation that determines the contents of its cache via a configured list of symbols. This service will not accept requests for new published records; it will only publish the records found in the configured list. This service also inherits all the functionality of the GatewayService. See section 4.2.7.7 and 4.2.7.8 for details.

GatewayRecord is in charge of handling all data and state change events from an upstream SFC-based record and publishing those changes back out to downstream client components through an SFC published record. The GatewayRecord acts as a proxy for the upstream SFC-based record. See section 4.2.7.9 and 4.2.7.10 for details.

4.2.7.3 GatewayService Class DeclarationThis section contains the contents of a header file (gatesvc.h) which declares the class GatewayService as designed in section 4.2.7.2. Note that the class inherits from RTRMDServiceClient so it can receive events from an upstream SFC service of type RTRRTRecordService.

#ifndef _gatesvc_h #define _gatesvc_h

#include "rtr/rtrecsrv.h" // RTRMDService#include "rtr/rtrsvimp.h" // RTRRTRecordServiceImpl#include "rtr/objid.h"// RTRObjectId#include "rtr/logevnt.h" // RTRLogEvent

SFC Developer’s Guide 119

Page 134: sfc

4.2 SFC MODELS

#include "rtr/rtllist.h"// RTRLinkedList#include "gaterec.h"

class GatewayService: public RTRMDServiceClient

{public:// Constructor

GatewayService(RTRObjectId& context, RTRRTRecordServiceImpl& implService, RTRRTRecordService& gateService);

// Destructorvirtual ~GatewayService();

// Identificationconst char *name();

// Service event propogation (From RTRMDServiceClient) virtual void processServiceAlert(RTRMDService&) {};

// A new alert is available from service s // (via method lastAlert()).

virtual void processServiceTimestamp(RTRMDService&) {};// A new timestamp is available from service s // (via method lastTimestamp()).

virtual void processServiceInfo(RTRMDService& gateService);// A new explanatory message is available from service s // (via method text()).

virtual void processServiceHeadline(RTRMDService& ) {};// A new headline is available from service s // (via method lastHeadline()).

// Service "state" event propogation (From RTRMDServiceClient)virtual void processServiceSync(RTRMDService& gateService);

virtual void processServiceStale(RTRMDService& gateService);

SFC Developer’s Guide 120

Page 135: sfc

4.2 SFC MODELS

virtual void processServiceInactive(RTRMDService& gateService);

// AccessRTRBOOL hasRecord(const RTRString& symbol);

// Is the gateway record associated with symbol currently// cached?

void addRecord(GatewayRecord *gateRec);// Add the given record to the gateway service’s cache.// REQUIRE: !hasRecord(symbol)

void removeRecord(const RTRString& symbol);// Remove the gateway record associated with symbol from// the gateway service’s cache.

protected:RTRRTRecordService& _gateService;RTRRTRecordServiceImpl& _implService;RTRLinkedList<GatewayRecord> _cache;RTRObjectId _instanceId;RTRObjectId _classId;RTRLogEvent _logEvent;

};

#endif

4.2.7.4 GatewayService Class DefinitionThis section contains the source file which implements the class GatewayService as declared in the previous section (in gatesvc.h).

At construction, the gateway service is given two other services: an RTRRTRecordService (subscription service) from which to access data and state and a RTRRTRecordServiceImpl (publishing service) that is used to publish the same data and state information. The publishing service is initialized to the text() of the subscription service and a state of Stale. Further initialization activities will be implemented by descendants of this class.

As a descendant of RTRMDServiceClient, the gateway service inherits methods that will be called whenever the state of the subscription service has changed. In the constructor, the gateway service

SFC Developer’s Guide 121

Page 136: sfc

4.2 SFC MODELS

registers with the subscription service to receive these events. Each of the methods inherited from RTRMDServiceClient are implemented to on-pass the event and gateway service text to the publishing service.

There are several methods that are used to create, store and destroy all GatewayRecord instances created in this service. This cache of gateway records is needed to allow for proper clean-up when the gateway service is destructed.

The destructor for this class will basically undo all the previous actions. Specifically, the publishing service is sent an Inactive event, all the gateway records are destroyed and the gateway service deregisters from the subscription service.

#include "gatesvc.h" // GatewayService#include "gaterec.h" // GatewayRecord

GatewayService::GatewayService(RTRObjectId& context,RTRRTRecordServiceImpl& implService, RTRRTRecordService& gateService)

: _implService(implService), _gateService(gateService), _instanceId(context, gateService.name()), _classId("GatewayService")

{_logEvent.setComponent(_instanceId);

_gateService.addClient(*this);_implService.setText(gateService.text());_implService.setStale();

};

GatewayService::~GatewayService(){

if (_gateService.hasClient(*this))_gateService.dropClient(*this);

_implService.setText("Service unavailable.");_implService.setInactive();_implService.indicateInactive();

for (_cache.start(); !_cache.off(); _cache.start())

SFC Developer’s Guide 122

Page 137: sfc

4.2 SFC MODELS

{GatewayRecord *gateRec = _cache.item();delete gateRec;

}};

const char *GatewayService::name(){

return _implService.name();}

RTRBOOL GatewayService::hasRecord(const RTRString& symbol) {

RTRLinkedList<GatewayRecord>& list = _cache;for (list.start(); !list.off(); list.forth()){

if (list.item()->symbol() == symbol)break;

}if (list.off())

return RTRFALSE;else

return RTRTRUE;}

void GatewayService::removeRecord(const RTRString& symbol){

for (_cache.start(); !_cache.off(); _cache.forth()){

if (_cache.item()->symbol() == symbol){

_cache.remove();break;

}}

}

void GatewayService::addRecord(GatewayRecord *gateRec){

RTPRECONDITION( !hasRecord(gateRec->symbol()) );

SFC Developer’s Guide 123

Page 138: sfc

4.2 SFC MODELS

_cache.extend(gateRec);}

void GatewayService::processServiceInfo(RTRMDService& gateService)// A new explanatory message is available from service s // (via method text()).

{_implService.setText(gateService.text());_implService.indicateInfo();

};

void GatewayService::processServiceSync(RTRMDService& gateService){

_implService.setNotStale();_implService.setText(gateService.text());_implService.indicateSync();

};

void GatewayService::processServiceStale(RTRMDService& gateService){

_implService.setStale();_implService.setText(gateService.text());_implService.indicateStale();

};

void GatewayService::processServiceInactive(RTRMDService& gateService){

_implService.setInactive();_implService.setText(gateService.text());_implService.indicateInactive();_implService.unsetClient();_gateService.dropClient(*this);delete this;

};

SFC Developer’s Guide 124

Page 139: sfc

4.2 SFC MODELS

4.2.7.5 SinkDrivenGatewayService Class DeclarationThis section contains the contents of a header file (sinkgates.h) which declares the class SinkDrivenGatewayService as designed in section 4.2.7.2. Note that the class inherits from RTRRTRecordServiceImplClient so it can receive events from the publishing service. It also inherits all the capabilities of the GatewayService.

#ifndef _sinkgates_h #define _sinkgates_h

#include "gatesvc.h"

class SinkDrivenGatewayService: public GatewayService, public virtual RTRRTRecordServiceImplClient

{public:// Constructor

SinkDrivenGatewayService(RTRObjectId& context, RTRRTRecordServiceImpl& implService, RTRRTRecordService& gateService);

// Destructorvirtual ~SinkDrivenGatewayService();

// Service impl notifications (From RTRRTRecordServiceImplClient)void processNewRecord(RTRRTRecordServiceImpl&,

RTRRTRecordImpl&);

};

#endif

4.2.7.6 SinkDrivenGatewayService Class DefinitionThis section contains the source file which implements the class SinkDrivenGatewayService as declared in the previous section (in sinkgates.h).

As a descendant of RTRRTRecordServiceImplClient, the SinkDrivenGatewayService (gateway service) adds the ability to receive notifications from a RTRTRecordServiceImpl (publishing service) whenever a new record has been added to the service’s cache. These notifications are generated by

SFC Developer’s Guide 125

Page 140: sfc

4.2 SFC MODELS

the publishing service whenever a user of that service requests data for a record that is not currently in the service’s cache. The term "sink driven" is used to describe a service that has the ability to receive record requests interactively from the publishing service.

It is the responsibility of this component to take action whenever a processNewRecord() event occurs. In this implementation, a new GatewayRecord instance is created to supply data and state information to the given published record. The data and state information is obtained from a different record service, the subscription service which is given to the new GatewayRecord instance at construction.

As a descendant of GatewayService, this class inherits the ability to handle service level events from the subscription service and to cache GatewayRecords.

At construction, the SinkDrivenGatewayService is given two other services: an RTRRTRecordService (subscription service) from which to access data and state and a RTRRTRecordServiceImpl (publishing service) that is used to publish the same data and state information. If the subscription service is in the NotStale state, then the publishing service is also initialized to the NotState state and a ServiceSync event is sent to all downstream client components. If the subscription service is Stale, then this class waits until the subscription service transitions to NotStale (as indicated when the GatewayService::processServiceSync() event is called by the subscription service).

The processNewRecord() method is implemented to create a new GatewayRecord instance for the given published record and to log the event through the SFC logger. The GatewayRecord constructor takes an instance of RTRRTRecord (subscription record) that is obtained from the subscription service. This is the record that the gateway record will be publishing information from. Note that the GatewayRecord will add itself to the cache of this gateway service.

#include "sinkgates.h" // SinkDrivenGatewayService

SinkDrivenGatewayService::SinkDrivenGatewayService(RTRObjectId& context,RTRRTRecordServiceImpl& implService, RTRRTRecordService& gateService)

: GatewayService(context, implService, gateService){

_implService.setClient(*this);if (!_gateService.stale()){

_implService.setText(_gateService.text());_implService.setNotStale();_implService.indicateSync();

SFC Developer’s Guide 126

Page 141: sfc

4.2 SFC MODELS

}};

SinkDrivenGatewayService::~SinkDrivenGatewayService(){

_implService.unsetClient();};

void SinkDrivenGatewayService::processNewRecord(RTRRTRecordServiceImpl&, RTRRTRecordImpl& newRecord)

{RTRString tmp("Got NewRecord event for new record ");tmp.append(newRecord.symbol());

_logEvent.setText(tmp);_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

RTRRTRecord& _sinkRecord = _gateService.rtRecord(newRecord.symbol());

GatewayRecord *gateRecord = new GatewayRecord(_instanceId, _sinkRecord, newRecord,*this);

if (!gateRecord->active())delete gateRecord;

};

4.2.7.7 SourceDrivenGatewayService Class DeclarationThis section contains the contents of a header file (srcgates.h) which declares the class SourceDrivenGatewayService as designed in section 4.2.7.2. Note that the class inherits all the capabilities of the GatewayService.

#ifndef _srcgates_h #define _srcgates_h

#include "gatesvc.h"

class SourceDrivenGatewayService

SFC Developer’s Guide 127

Page 142: sfc

4.2 SFC MODELS

: public GatewayService {public:// Constructor

SourceDrivenGatewayService(RTRObjectId& context, RTRRTRecordServiceImpl& implService, RTRRTRecordService& gateService);

// Destructorvirtual ~SourceDrivenGatewayService();

// Initializationvoid load();

// Initialize the cache.

friend class GatewayRecord;};

#endif

4.2.7.8 SourceDrivenGatewayService Class DefinitionThis section contains the source file which implements the class SourceDrivenGatewayService as declared in the previous section (in srcgates.h).

The SourceDrivenGatewayService illustrates the basic technique for publishing real-time records in a source-driven, or non-interactive, fashion. This service implements a load() method that will read a list of symbols from the configuration database and create instances of GatewayRecord for each symbol.

This application will only publish records that are loaded at construction. By not becoming an event client of the publishing service, this SourceDrivenGatewayService disables the ability for downstream client components to obtain data from records that do not already reside in the publishing service.

As a descendant of GatewayService, this class inherits the ability to handle service level events from the subscription service and to cache GatewayRecords.

At construction, the SourceDrivenGatewayService is given two other services: an RTRRTRecordService (subscription service) from which to access data and state and a RTRRTRecordServiceImpl (publishing service) that is used to publish the same data and state information. The load() method is called in the constructor and is implemented to create new GatewayRecord instances for each symbol found in a configuration value. No duplicate symbols will

SFC Developer’s Guide 128

Page 143: sfc

4.2 SFC MODELS

be added. The GatewayRecord constructor takes an instance of RTRRTRecord (subscription record) that is obtained from the subscription service. The gateway record will be publishing information from the subscription record. Note that the GatewayRecord will add itself to the cache of this gateway service.

After all the records have been loaded into the cache, the publishing service’s state may be initialized. If the subscription service is in the NotStale state, then the publishing service is also initialized to the NotState state and a ServiceSync event is sent to all downstream client components. If the subscription service is Stale, then this class waits until the subscription service transitions to NotStale (as indicated when the GatewayService::processServiceSync() event is called by the subscription service).

After construction of the SourceDrivenGatewayService, no new records will be added into the publishing service’s cache. Any requests for new records from downstream client components will be denied automatically by the publishing service.

#include "srcgates.h" // SourceDrivenGatewayService#include "rtr/config.h"

SourceDrivenGatewayService::SourceDrivenGatewayService(RTRObjectId& context,RTRRTRecordServiceImpl& implService,

RTRRTRecordService& gateService): GatewayService(context, implService, gateService)

{// Initialize the cache.

load();

if (!_gateService.stale()){

_implService.setNotStale();_implService.setText(_gateService.text());_implService.indicateSync();

}};

SourceDrivenGatewayService::~SourceDrivenGatewayService(){};

void SourceDrivenGatewayService::load(){

SFC Developer’s Guide 129

Page 144: sfc

4.2 SFC MODELS

// Get a list of symbols to retrieve. If no configuration// variable is present, use the default RTRSY.O//

RTRListOfExternalValue ricList = RTRConfig::configDb().variable(_classId,_instanceId,"symbolList","RTRSY.O").list(’,’);

RTRRTRecordImpl *_implRecord = 0;for (ricList.start(); !ricList.off(); ricList.forth()){

// Check for duplicate symbols. if (!_implService.hasRTRecordImpl(ricList.item())){

// Create a new record in the _implService.//

_implRecord = &(_implService.newRTRecordImpl( ricList.item() ));

// Get the sink record from which data will be sourced.//

RTRRTRecord& _sinkRecord = _gateService.rtRecord( ricList.item() );

// Create a gateway record to tie together the _implRecord and // _sinkRecord. Note that the gateway record adds and deletes// itself from this gateway service’s cache.//

GatewayRecord *gateRec = new GatewayRecord(_instanceId, _sinkRecord, *_implRecord, *this);

if (!gateRec->active())delete gateRec;

}}};

SFC Developer’s Guide 130

Page 145: sfc

4.2 SFC MODELS

4.2.7.9 GatewayRecord Class DeclarationThis section contains the contents of a header file (gaterec.h) which declares the class GatewayRecord as designed in section 4.2.7.2. Note that the class inherits from both RTRRTRecordClient (for subscription event) and RTRRTRecordImplClient (for publication events).

#ifndef _gaterec_h#define _gaterec_h

#include "rtr/rtrecimp.h" // RTRRTRecordImpl#include "rtr/rtrec.h" // RTRRTRecord#include "rtr/timercmd.h"// RTRTimerCmd#include "rtr/objid.h" // RTRObjectId#include "rtr/logevnt.h"// RTRLogEvent

class GatewayService;

class GatewayRecord : public RTRRTRecordImplClient, public RTRRTRecordClient

{public:// Constructor

GatewayRecord(RTRObjectId& context, RTRRTRecord& gateRec, RTRRTRecordImpl& srcRec, GatewayService& service);

// Destructorvirtual ~GatewayRecord();

// Identificationconst RTRString& symbol() const;

// StateRTRBOOL active();

// Event processing (Inherited from RTRRTRecordClientvoid processRecordInfo(RTRRTRecord& gateRec);void processRecordSync(RTRRTRecord& gateRec);void processRecordStale(RTRRTRecord& gateRec);void processRecordNotStale(RTRRTRecord& gateRec);

SFC Developer’s Guide 131

Page 146: sfc

4.2 SFC MODELS

void processRecordInactive(RTRRTRecord& gateRec);void processUpdate(RTRRTRecord&);void processTick(RTRRTRecord&);void processCloseTick(RTRRTRecord&);void processCorrectionTick(RTRRTRecord&);void processUpdateComplete(RTRRTRecord& gateRec);void processRecordResync(RTRRTRecord& gateRec);void processResyncComplete(RTRRTRecord& rec);

// From RTRRTRecordImplClientvoid processHasEventClient(RTRRTRecordImpl&);

// Handle the case where the first downstream client has // started watching the record

void processNotHasEventClient(RTRRTRecordImpl&);// Handle the case where the last downstream client has // stopped watching the record.

protected:RTRRTFieldUpdateList _updList;RTRRTRecordImpl& _implRecord;RTRRTRecord& _gateRecord;GatewayService& _service;static RTRLogEvent _logEvent;RTRObjectId _instanceId;

};

#endif

4.2.7.10 GatewayRecord Class DefinitionThis section contains the source file which implements the class GatewayRecord as declared in the previous section (in gaterec.h).

This class primarily acts as a "glue" layer between a RTRRTRecord instance (subscription record) and a RTRRTRecordImpl instance (published record).

At construction, the gateway record registers with both the subscription record and published record to receive events. Then the gateway record checks to make sure the subscription record is valid (_gateRecord.active()) and adds itself to the gateway service. If the subscription record is fully

SFC Developer’s Guide 132

Page 147: sfc

4.2 SFC MODELS

populated (_gateRecord.hasData()), then the published record is populated with fields and its state is initialized by calling the processRecordSync() method. If the subscription record is not populated yet, then the gateway record will wait until the subscription record sends a Sync event.

The processRecordSync() method is implemented to iterate through all the fields found in the subscription record and add a new field of the same type into the published record. To do this, an instance of RTRRTRecordIterator is obtained from the subscription record and, for each field in the iteration, a new field of the same type is created. It is possible that the publishing service’s FID database will not contain all the same fields as the subscription service. When this occurs, the gateway record will ignore the field.

Note that the RTRFidDefinitions passed to the constructor of each new field are obtained from the RTRFidDb of the publishing service. Since the subscription and publishing services can have different FID databases, the gateway application must get the FID definitions from the publishing service.

After the new fields are populated into the published record, the record’s state is changed to reflect that of the subscription record and a RecordSync event is propagated to all downstream client components.

As updates occur in the subscription record, the processUpdateComplete() method is called. This method is implemented to iterate through all the fields that have updated in the subscription record and reset the values of the corresponding published record. After all fields have been updated, the list of fields is passed to the published record and an UpdateComplete event is propagated to all downstream client components.

The same processing occurs when the subscription record is resynchronized, or refreshed, and the processResyncComplete() method is called.

As other events are received from the subscription record, the events are reflected in the published record. Whenever a subscription record state change event occurs, the published record’s state and descriptive text are changed and the same event is propagated to the published record.

If a RecordInactive event is received from the subscription record, the gateway record will propagate the event to the published record, remove the published record from the publishing service, remove

NOTE: Use the field name (RTRRTField.name()) when querying the FID database for a FID defini-tion. The field names are more likely to be consistent across different system’s FID databases. This is true of the RMDS and SSL systems, where the field ID values tend to be inconsistent, while the field names are consistent.

SFC Developer’s Guide 133

Page 148: sfc

4.2 SFC MODELS

itself from the gateway service, de-register from the subscription and published records and then destroy itself. An Inactive event is a permanent indication that the symbol is no longer valid.

Note that the processHasEventClient() and processNotHasEventClient() callbacks are not implementated to take any action. This is because, for the purposes of this example program, the record will remain cached for the life of the application once it is added

#include "gaterec.h"#include "gatesvc.h"

GatewayRecord::GatewayRecord(RTRObjectId& context, RTRRTRecord& gateRec, RTRRTRecordImpl& srcRec,GatewayService& service)

: _gateRecord(gateRec), _implRecord(srcRec), _instanceId(context, gateRec.symbol()), _service(service), _updList(srcRec)

{RTPRECONDITION( !service.hasRecord(gateRec.symbol()) );

_implRecord.setStale();_implRecord.addClient(*this);_gateRecord.addClient(*this);if ( _gateRecord.active() ){

_service.addRecord(this);if ( _gateRecord.hasData() ){

processRecordSync(_gateRecord);}else{

_implRecord.setText(_gateRecord.text());_implRecord.indicateInfo();

}}else{

_gateRecord.dropClient(*this);}

};

SFC Developer’s Guide 134

Page 149: sfc

4.2 SFC MODELS

GatewayRecord::~GatewayRecord(){

_implRecord.dropClient(*this);_implRecord.setText(_gateRecord.text());

if (_gateRecord.hasClient(*this))_gateRecord.dropClient(*this);

// Notify any clients of state change._implRecord.setInactive();_implRecord.indicateInactive();

// Delete all fields and allocated field memory._implRecord.deleteAllFields();

// Remove the impl record from it’s RTRRTRecordServiceImpl._implRecord.service().removeRTRecordImpl(_implRecord.symbol());

// Remove this gateway record from the GatewayService._service.removeRecord(symbol());

};

const RTRString& GatewayRecord::symbol() const{

return _gateRecord.symbol();}

RTRBOOL GatewayRecord::active(){

return _gateRecord.active();};

void GatewayRecord::processRecordInfo(RTRRTRecord& gateRec){

_implRecord.setText(gateRec.text());_implRecord.indicateInfo();

};

void GatewayRecord::processRecordSync(RTRRTRecord& gateRec)

SFC Developer’s Guide 135

Page 150: sfc

4.2 SFC MODELS

{RTRRTRecordIterator iter = gateRec.iterator();

char* farea;RTRRTField *fld = 0;

// If template number exists in upstream record,// on-pass it to published record.//

if (gateRec.recordTemplateNumber() != 0)_implRecord.setRecordTemplateNumber(gateRec.recordTemplateNumber());

// Create new fields for each of the fields found in// the gateRec.//

for (iter.start(); !iter.off(); iter.forth()){

RTRRTField& field = iter.field();const RTRFidDefinition *def = _implRecord.fidDb().defByName(field.name());

if (def){

// NOTE: Always allocate one extra byte for storing the// end-of-data delimiter.

int fLength = def->length() + 1;

if (field.type() == RTRFidDefinition::Price){

farea = new char [fLength];fld = new RTRRTPriceField(*def, farea, 0);

}else if (field.type() == RTRFidDefinition::Alphanumeric ||

field.type() == RTRFidDefinition::LongAlphanumeric ){

farea = new char [fLength];fld = new RTRRTAlphanumericField(*def, farea, 0);

}else if (field.type() == RTRFidDefinition::TimeSecs ||

field.type() == RTRFidDefinition::Date ||field.type() == RTRFidDefinition::Time )

SFC Developer’s Guide 136

Page 151: sfc

4.2 SFC MODELS

{farea = new char [fLength];fld = new RTRRTDateTimeField(*def, farea, 0);

}else if (field.type() == RTRFidDefinition::Integer){

farea = new char [fLength];fld = new RTRRTIntegerField(*def, farea, 0);

}else if (field.type() == RTRFidDefinition::Numeric){

farea = new char [fLength];fld = new RTRRTNumericField(*def, farea, 0);

}else if (field.type() == RTRFidDefinition::Enumerated){

int eLength = def->expandedLength() + 1;if(eLength > fLength)

farea = new char [eLength];else

farea = new char [fLength];const RTREnumTable *tbl =

_implRecord.fidDb().enumTableByName(field.name());fld = new RTRRTEnumeratedField(*def, farea, 0, *tbl);

}else {

farea = new char [fLength];fld = new RTRRTField(*def, farea, 0);

}// Set the field value.

fld->set(field.to_c(), field.count());

// Add the field to the publication record._implRecord.putField(*fld);

}}

if (!gateRec.stale())_implRecord.setNotStale();

SFC Developer’s Guide 137

Page 152: sfc

4.2 SFC MODELS

_implRecord.setText(gateRec.text());_implRecord.indicateSync();

};

void GatewayRecord::processRecordStale(RTRRTRecord& gateRec){

_implRecord.setStale();_implRecord.setText(gateRec.text());_implRecord.indicateStale();

};

void GatewayRecord::processRecordNotStale(RTRRTRecord& gateRec){

_implRecord.setText(gateRec.text());_implRecord.setNotStale();_implRecord.indicateNotStale();

};

void GatewayRecord::processRecordInactive(RTRRTRecord&){

// Note - clean up of gate and impl records is done in // the destructor.

delete this;};

void GatewayRecord::processUpdate(RTRRTRecord&){

_implRecord.indicateUpdateTick();};

void GatewayRecord::processTick(RTRRTRecord&){

_implRecord.indicateUpdateTick();};

void GatewayRecord::processCloseTick(RTRRTRecord&){

_implRecord.indicateCloseTick();};

SFC Developer’s Guide 138

Page 153: sfc

4.2 SFC MODELS

void GatewayRecord::processCorrectionTick(RTRRTRecord&){

_implRecord.indicateCorrectionTick();};

void GatewayRecord::processUpdateComplete(RTRRTRecord& gateRec){

RTRRTRecordUpdateIterator iter = gateRec.updateIterator();

_updList.reinitialize(_implRecord);for (iter.start(); !iter.off(); iter.forth()){

// Update the _implRecord’s field with the value// from the _gateRecord’s field.//

RTRRTField& gateFld = iter.field();RTRRTField& implFld = *_implRecord.fieldByName(gateFld.name());if (&implFld){

implFld.set(gateFld.to_c(), gateFld.count());_updList.putField(implFld);implFld.indicateFieldUpdated();

}}

_implRecord.indicateUpdateComplete(_updList);};

void GatewayRecord::processRecordResync(RTRRTRecord& gateRec){

_implRecord.setText(gateRec.text());if (gateRec.stale())

_implRecord.setStale();else

_implRecord.setNotStale();_implRecord.indicateResync();

};

void GatewayRecord::processResyncComplete(RTRRTRecord& gateRec){

SFC Developer’s Guide 139

Page 154: sfc

4.2 SFC MODELS

RTRRTRecordUpdateIterator iter = gateRec.updateIterator();

_updList.reinitialize(_implRecord);for (iter.start(); !iter.off(); iter.forth()){

// Update the _implRecord’s field with the value// from the _gateRecord’s field.//

RTRRTField& gateFld = iter.field();RTRRTField& implFld = *_implRecord.fieldByName(gateFld.name());if (&implFld){

implFld.set(gateFld.to_c(), gateFld.count());_updList.putField(implFld);implFld.indicateFieldUpdated();

}}

_implRecord.indicateResyncComplete(_updList);};

// From RTRRTRecordImplClientvoid GatewayRecord::processHasEventClient(RTRRTRecordImpl&){

_logEvent.setComponent(_instanceId);_logEvent.setText("Users are now monitoring this record.");_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

};

void GatewayRecord::processNotHasEventClient(RTRRTRecordImpl&){

_logEvent.setComponent(_instanceId);_logEvent.setText("Users are no longer monitoring this record.");_logEvent.setSeverity(RTRLogSeverity::debug);_logEvent.log();

};

RTRLogEvent GatewayRecord::_logEvent;

SFC Developer’s Guide 140

Page 155: sfc

4.3 SFC MODELS

4.3 Page Subscription

4.3.1 Overview

4.3.1.1 PagesA page represents an item of market data which is paginated, i.e., the data has embedded formatting and display information. This is done by encoding escape sequences in the data or by providing formatting data in a separate attribute field. It is this embedded display information that differentiates pages from records. In Triarch and RMDS, pages are sometimes called ANSI pages. In TIB, they are referred to as effects pages.

In all other ways, pages represent real-time market data, just like records. The content of a page may change over time. These changes are referred to as updates and constitute distinct events which must be conveyed to the clients of any given page. Page clients are application components which are interested in the events associated with a particular page. This interest is expressed by the act of registering a client with a page.

The data represented by a page can be characterized by its condition. The condition of the data may affect the way in which it is used by a client. For example, if data is suspect, or stale, a display application might indicate this by using a different color to display that data. Data condition is expressed in the model by state variables associated with a page. Changes in the condition of the data result in changes to page state. As with updates, page state changes are generally of interest to clients, requiring timely propagation of these events to individual clients of the page.

Some services support a "next" and "previous" page. The names of these adjacent pages are dependent on the service and the infrastructure. The infrastructure-specific names are available from the page.

4.3.1.2 Logical PagesSFC has two models for representing pages: logical pages and page streams. The second model, page "streams," is only available for the Triarch infrastructure and is discussed in section 4.4. While the RMDS infrastructure does provide page data in an ANSI format, the legacy page stream model is not supported for the RMDS infrastructure. The logical model is preferred.

Logical pages separate the data from the attributes and split the data into regions. A page region is a single row of cached data, with a starting and an ending column. Each column of a region is called a cell. The data and attributes of logical page are always cached.

SFC Developer’s Guide 141

Page 156: sfc

4.3 SFC MODELS

The logical page abstraction is represented in SFC by the class RTRPage. Page regions are represented by the class RTRPageRegion. Clients can register interest in a page’s state and data events with the interface RTRPageClient. They can register interest in an individual region using the interface RTRPageRegionClient.

4.3.1.3 AttributesLogical pages also include attributes that describe how the data should be displayed. They can describe properties such as highlighting, inverse printing, and colors. Attributes are stored with the page, so an individual cell’s attribute data can be accessed from the page. A page actually stores two sets of attributes, the normal attributes and the fade attributes. The fade attributes are used to temporarily highlight regions that have updated. Figure 4.13 shows the object structure of a RTRPage

.

Figure 4.13: Logical Page Class Model

RTRPageClient

+processSync()+processUpdate()+processRename()+processInactive()+processInfo()+processResync()+processStale()+processNotStale()

1..nRTRPageRegion

RTRPageRegionClient

+processUpdate()

1..n1..n

RTRPageAttributes2..1

RTRPage

SFC Developer’s Guide 142

Page 157: sfc

4.3 SFC MODELS

A page’s attributes describe how each cell within the page should be displayed. All of a page’s attributes are stored in a single object of type RTRPageAttributes. The page model supports the following attributes:

• background color - enumeration of type RTRPageAttributes::Color

• foreground color - enumeration of type RTRPageAttributes::Color

• character set - enumeration of type RTRPageAttributes::CharSet Character sets can be used to select a display character set that supports the necessary extended ASCII characters (character above127).

• blink - RTRBOOL

• bold (also called bright) - RTRBOOL

• dim - RTRBOOL

• overline - RTRBOOL

• reverse - RTRBOOL

• underline - RTRBOOL

4.3.1.4 Services and Service PoolsPage services and page service pools are analogous to real-time record services and record service pools. The only difference is that they provide access to pages instead of records. Please refer to section 4.1.1.5 and section 4.1.1.6 for a discussion of the roles of services and pools in an application. The relavent logical page classes are RTRPageService, RTRPageServicePool, and RTRPageServicePoolClient.

4.3.2 Design

4.3.2.1 Page StateLogical page state is defined by the values of three page attributes:

• stale

• active

• hasData

SFC Developer’s Guide 143

Page 158: sfc

4.3 SFC MODELS

State transitions are propagated to clients as events on the RTRPageClient interface. Figure 4.14 shows page states and events causing state transitions. The state transition diagram is the same as the one for records.

Figure 4.14: Logical Page States and Variables

4.3.2.2 Service StatePage service state is identical to record service state. It even uses the same RTRMDConnectionClient interface. For more details see section 4.1.2.4.

4.3.3 Class SummaryThis section provides a summary of the classes which comprise the model for real-time page data. For more details please refer to the appropriate sections of the alphabetical class reference.

Active_noData Active_validSync

Inactive

Inactive

InactiveStale

NotStale

(hasData = False, stale = True, active = True)Active_noData(hasData = True, stale = False, active = True)Active_valid(hasData = True, stale = True, active = True)Active_stale(hasData = XX, stale = XX, active = False)Inactive

Sync

Resync

Resync

Inactive Active_stale

SFC Developer’s Guide 144

Page 159: sfc

4.3 SFC MODELS

• RTRPage - This class defines an item of real-time page data that has been shredded into a logical format. A RTRPage maintains an ordered list of RTRPageRegions and the attribute information for the page. Also, it keeps track of the state of the market data item.

• RTRPageClient - This is the abstract base class for application components that wish to register with one or more real-time pages in order to receive data and state events from those pages.

• RTRPageRegion - This class stores the data for a single row of a page.

• RTRPageRegionClient - This is the abstract base class for application components which wish to register to receive data events for one or more page regions.

• RTRPageRegionIterator - This class provides sequential access to all regions in a page.

• RTRPageRegionUpdate - This class is used during page updates to keep track of the offsets in a page region that were updated. It is only valid during a RTRPageClient::processUpdate() or a RTRPageRegionClient::processUpdate() callback.

• RTRPageRegionUpdateIterator - During a RTRPageClient::processUpdate() callback, this class provides sequential access to the regions that were updated.

• RTRPageAttributes - This class stores all of the attributes of a page. Attributes for a single page cell can be accessed by specifying the row and column.

• RTRPageService - This class provides access to real-time page data and manages the aggregate state of those pages. Service state change events are propagated to those application components that register to receive those events.

• RTRMDServiceClient - This is the abstract base class for components that wish to register with one or more instances of page or record services in order to receive data and state events from those services.

• RTRPageServicePool - Instances of this class serve as a repository for all available real-time page services. Typically there is only one instance of this type within an application. A pool provides random and sequential access to the services it contains. A pool provides the means to insert and remove services and allows clients to register for the change events which are generated when the contents are modified.

• RTRPageServicePoolClient - This is the abstract base class for components that wish to register with one or more real-time page service pools in order to receive data and state events from those pools. This interface does not indicate when the state of a service changes. To monitor

SFC Developer’s Guide 145

Page 160: sfc

4.3 SFC MODELS

state changes in a service (e.g. when a service becomes stale), register directly with the service using RTRMDServiceClient.

4.3.4 ImplementationCurrently, the SFC provides two implementations of the real-time page model, although other implementations are possible. While most application components should refer only to the base classes mentioned in the preceding section, the "main" routine or initialization section of an application must instantiate one or more implementation specific classes. The implementation classes mentioned here are similar in functionality and implementation to those that provide access to real-time record data and which are presented in section 4.1.3. Please refer to that section for more details.

The SFC page model includes implementation classes for use by both single (simple) and multiple service (more complex) applications. These classes encapsulate the procedures for creating an SSL connection and the page services which use that connection. They are:

• RTRSSLPageService - This class is a descendant of RTRPageService and creates is own RTRRTPageService to retrieve data. It is typically used by simple applications which require access to only a single service.

• RTRTIBPageService - This class is a descendant of RTRPageService which creates its own TIB connection. It is typically used by simple applications which require access to only a single service.

4.3.4.1 Character SetsThe TIB infrastructure does not provide character set information with its data. So, when getting data from a TIB infrastructure, the TIB implementation is dependent on a character mapping file, charMapFile.cnf. By default, the TIB Implementation looks for this file in /var/triarch. See the comments in the file for information on the file format. Several services have already been configured in this file. This file’s format may change in the future. See section 5.5.8.2 for further information.

4.3.4.2 Attribute MappingMost attribute information is boolean, meaning the attribute is either on or off. For memory and bandwidth considerations, attribute data is encoded into one or two bytes. For example, the first bit may represent bold while the third bit represents underline. Each system that supports attributes does so in a different encoding format. TIB, Triarch, the curses display library, and the WinConsole API all encode this data differently. SFC decodes attribute information from TIB and Triarch page services so

SFC Developer’s Guide 146

Page 161: sfc

4.3 SFC MODELS

the Triarch and TIB formats do not have to be interpreted by the application. Typical applications will still need to map attributes from SFC boolean function values to the display API’s encoding format. The WinPage and CursesPage examples have functions that map SFC semantic attributes to display attributes.

TIB services do not deliver fade attributes, so SFC will return the same data for RTRPage::attributes() and RTRPage::fadeAttributes().

Some datafeeds for TIB page services do not use the TIB standard method for encoding attributes. Instead of sending color information, they encode the colors in the attribute fields. SFC provides a mechanism for mapping these attributes to the correct TIB-semantic attributes. For more information on configuring a TIB page service, see section 5.5.8.2.

4.3.4.3 ConfigurationBoth implementations provide the following configuration variables for setting up a page service:

• enableColors - should colors be enabled (default is true)

• defaultFgColor - set the default foreground color (7 for white)

• defaultBgColor - set the default background color (0 for black)

4.3.4.4 Multiple ServicesSome applications use more than one service. The connection and service pool factory classes make it easy to incorporate multiple services in a single application.

RTRSSLConnection and RTRTIBConnection can be used to fine tune the connection parameters for the implementation page services. They are described in detail in section 4.8.1.

RTRSSLServicePoolFactory and RTRTIBServicePoolFactory can be used to manage the life-cycle of and share a single connection among several market data services. They are described in detail in section 4.8.2.

4.3.5 ExamplesSFC includes a few examples that highlight different parts of the page model. These examples can be found the sfc/examples/pages/ directory. They typically have two parts:

1. main() function that:

SFC Developer’s Guide 147

Page 162: sfc

4.3 SFC MODELS

• parses command line arguments• creates a service pool factory or page service• requests a page• creates the appropriate SFC client and registers it with the page• creates the event control loop

2. SFC client implementation that is responsible for:

• processing data and status events• printing output to standard out

The following table summarizes the record examples and details where more information about them can be found.

4.3.6 Page ClientThe PageUpd example prints a page’s status and data events on the standard output device. Attributes are ignored. The entire page is printed when a Sync, Resync or Update event is received.

Example Program Description Refer to...

PageUpd Displays a page’s image, updates and events to stan-dard out.

pageupdclient.*pageupd.Csection 4.3.6

RegionUpd Displays updates from a single region from a page. regionupdclient.*regionupdsection 4.3.7

WinPage(win32 only)

Displays a page’s data and applies its attributes to a Windows console using Win32 platform SDK functions.

section 4.3.8winpage.Cconsolepageclient.*(win32 only)

CursesPage(Unix only)

Displays a page’s data and applies its attributes to an xterm using the X-Open curses library.

section 4.3.8cursespage*.*(Unix only)

Table 4.11: Page Examples

SFC Developer’s Guide 148

Page 163: sfc

4.3 SFC MODELS

The name of this class is PageUpdClient. In order to receive page events, this class is a descendant of RTRPageClient. This class must provide implementations of all pure virtual methods inherited from its ancestor. These methods correspond to the events that can be received from RTRPage.

This class processes these events:

• Sync

• Resync

• Stale

• NotStale

• Info

• Inactive

• Rename

• Update

4.3.6.1 Declaration of PageUpdClient (pageupdclient.h)

// PageUpdClient is a concrete implementation of RTRPageClient.// It prints the entire page when an image is initially received// and when any part of the page updates.

#ifndef _pageupdclient_h_#define _pageupdclient_h_

#include "rtr/page.h"#include "rtr/pgreg.h"

class RTRPageService;

class PageUpdClient :public RTRPageClient

{public:

PageUpdClient(RTRPageService &service, RTRString &ric);virtual ~PageUpdClient();

SFC Developer’s Guide 149

Page 164: sfc

4.3 SFC MODELS

// RTRPageClientvirtual void processSync(RTRPage&);virtual void processResync(RTRPage&);virtual void processStale(RTRPage&);virtual void processNotStale(RTRPage&);virtual void processInfo(RTRPage&);virtual void processInactive(RTRPage&);virtual void processUpdate(RTRPage&);virtual void processRename(RTRPage&);

protected:RTRPage *_page;

};

#endif

4.3.6.2 Definition of PageUpdClient (pageupdclient.C)

#include "pageupdclient.h"#include "rtr/pgsrvc.h"

PageUpdClient::PageUpdClient(RTRPageService &service, RTRString &ric){

_page = &(service.page(ric));_page->addClient(*this);

}

PageUpdClient::~PageUpdClient(){

if (_page && _page->hasClient(*this))_page->dropClient(*this);

}

void PageUpdClient::processSync(RTRPage &page){

cout << page.symbol() << ": page sync" << endl;

// print the entire pagecout << *_page;

}

SFC Developer’s Guide 150

Page 165: sfc

4.3 SFC MODELS

void PageUpdClient::processResync(RTRPage &page){

cout << page.symbol() << ": page resync" << endl;cout << *_page;

}

void PageUpdClient::processStale(RTRPage &page){

cout << page.symbol() << ": page stale: " << page.text() << endl;}

void PageUpdClient::processNotStale(RTRPage &page){

cout << page.symbol() << ": page not stale" << endl;}

void PageUpdClient::processInfo(RTRPage &page){

cout << page.symbol() << ": page info: " << page.text() << endl;}

void PageUpdClient::processInactive(RTRPage &page){

cout << page.symbol() << ": page inactive" << endl;_page->dropClient(*this);_page = 0;

}

void PageUpdClient::processRename(RTRPage &page){

// This event occurs when a next or previous page is requested. The new// page name is automatically requested by SFC unless page.dropClient()// is called here.

cout << page.symbol() << ": page renamed" << endl;}

void PageUpdClient::processUpdate(RTRPage &page){

SFC Developer’s Guide 151

Page 166: sfc

4.3 SFC MODELS

cout << page.symbol() << ": page sync" << endl;cout << *_page;

}

4.3.6.3 Creating Page Service and PageUpdClientThe following code shows how to create an SSL or TIB page service. It is similar in structure to the RecSnap example in section 4.1.6.3.

// Some of the code has been omitted for brevity.// See sfc/examples/realtime/recsnap.C for all of the code

#include "pageupdclient.h"#include "rtr/selectni.h"// RTRSelectNotifier#include "rtr/tibpgsrvc.h"#include "rtr/sslpgsrvc.h"

RTRCmdLine RTRCmdLine::cmdLine;

int main(int argc, char* argv[]){

RTRString serviceName, infra, symbol;RTRString servicePort, network, daemon;

// Read command line parameters, set serviceName, infra, and symbol.// For TIB, also set servicePort, network, and daemon.// ...

RTRPageService *service = 0;

// Select which architecture to consume from if (infra == "tib"){

service = new RTRTIBPageService(appId, serviceName, servicePort, network, daemon);

}else if (infra == "ssl"){

SFC Developer’s Guide 152

Page 167: sfc

4.3 SFC MODELS

service = new RTRSSLPageService(appId, serviceName);}else{

cout << "invalid infrastructure: " << infra << endl;return -1;

}

if ( !service->active() ){

cerr << "Service error: " << service->text() << endl;delete (service);return -1;

}

PageUpdClient client(*service, symbol);RTRSelectNotifier::run();delete service;return 0;

}

4.3.7 Region ClientRegionUpdClient is similar to PageUpdClient, except it ignores page updates and focuses on updates for a single region. The specific differences in the declaration include:

• includes "rtr/pgreg.h"

• inherits from RTRPageRegionClient

• declares void processUpdate(RTRPageRegionUpdate&);

• constructor accesses a short, which is the row number (1-based) of the region to monitor

• stores the row number and region pointer in variables

4.3.7.1 Definition of RegionUpdClient (regionupdclient.C)The definition is also very similar to pageupdclient.C. Some the file’s code has been omitted for brevity. The key differences are shown below in processSync(RTRPage &), processUpdate(RTRPageRegion&), and the destructor.

SFC Developer’s Guide 153

Page 168: sfc

4.3 SFC MODELS

#include "regionupdclient.h"

// ...

RegionUpdClient::~RegionUpdClient(){

if (_region && _region->hasClient(*this))_region->dropClient(*this);

if (_page && _page->hasClient(*this))_page->dropClient(*this);

}

void RegionUpdClient::processSync(RTRPage &page){

cout << page.symbol() << ": page sync" << endl;_region = page.getRegion(_row);if (_region)

_region->addClient(*this);cout << _page->symbol() << " - " << _row << endl;cout << _region->value() << endl;

}

// ...

void RegionUpdClient::processUpdate(RTRPageRegionUpdate &update){

cout << "Page: " << _page->symbol() << " - row: " << _row << ": (" << update.start() << "," << update.stop() << ")" << endl;

cout << update.region().value() << endl;}

4.3.8 Attribute ExamplesSFC includes two examples that take attribute data from logical pages and apply it to a display environment. The winpages example for Win32 platforms uses the Windows console system functions. The cursespage example for Unix platforms uses the X-Open curses library for xterms. Both applications follow a similar process:

SFC Developer’s Guide 154

Page 169: sfc

4.3 SFC MODELS

1. Request the page supplied at the command line.

2. Whenever a data event is received, extract the RTRPageAttributes from the page.

3. For each row and column changed in the update, check each of the attributes that are supported by the display environment (for example, colors are supported by a Windows console, but not by all xterms). If the attribute is true, enable that attribute for the target attribute encoding. This process maps the SFC encoding of attributes to the display environments encoding of attributes.

4. When attribute mapping has been completed, display the data and mapped attribute information using the appropriate system library calls.

Each example may also go through some display environment-specific process which is independent of SFC.

SFC Developer’s Guide 155

Page 170: sfc

4.4 SFC MODELS

4.4 Page Stream Subscription

NOTE: The Page Stream model is a legacy model, only available for Triarch. It is included with SFC for backwards compatibility. All new development should use the logical page model.

4.4.1 Overview

4.4.1.1 Page StreamsThe second model for page data is stream-based. A page stream makes no attempt to decode the data. It just delivers it to its clients. The page stream abstraction is represented in SFC by the class RTRRTPage. Note that the class names for page streams include the RT prefix between the RTR- prefix and the base class name. The new logical page classes dropped the extra RT. This does not imply one model is more "real-time" than the other. The naming distinction simply maintains backwards compatibility for the legacy stream classes while avoiding name conflicts with the logical page model.

Stream pages are a particular type of real-time data stream. Streams provide encoded data representing images and updates. What makes a page a page is the type of encoding used. A stream (page) is not required to cache the most recent image, although it may choose to do so. Clients of a stream may request an image for that stream and will then receive an image and subsequent updates to that image. Because stream clients have state with respect to a particular stream (some clients may have received an image and consider the stream "not current" or stale, while others may not have received an image and hence consider the stream stale), clients may only register with one stream at a time, although a given stream can support multiple clients. The page client abstraction is represented in the SFC by the class RTRRTPageClient.

4.4.1.2 ServicesReal-time page services are very similar to real-time record services, except that they provide pages instead of records. As with record services, if a page service is unable (or unwilling) to provide data for a requested page, the page will be in an inactive state. The text of an inactive page explains the reason that data will not be provided. Once in an inactive state, a page will never transition to the active state. Applications should not maintain references (pointers) to inactive items. This rule is based on practical considerations, e.g. memory management. Resources used by inactive items are eligible to be reclaimed. In the SFC, logical page services are represented by the class RTRPageService, and page stream services are represented by the class RTRRTPageService.

SFC Developer’s Guide 156

Page 171: sfc

4.4 SFC MODELS

4.4.1.3 Service PoolsReal-time page services and page service pools are similar to real-time record services and record service pools. Please refer to sections 4.1.1.5 and 4.1.1.6 for a discussion of the role of services and pools in an application. The relevant logical page classes are RTRPageService, RTRPageServicePool, and RTRPageServicePoolClient. The equivalent stream page classes are RTRRTPageService, RTRRTPageServicePool, and RTRRTPageServicePoolClient.

4.4.2 Design

4.4.2.1 Page StateSince page stream data is not cached, hasData for a stream page is never true. Page stream state is defined by the values of only two page attributes:

• stale

• active.

State transitions are propagated to clients as events on the RTRRTPageClient interface. Figure 4.15 shows page states and events causing state transitions.

Figure 4.15: Real-time Page Stream States and Variables

Active_valid Active_stale

Inactive

InactiveInactive

Stale

NotStale

(stale = False, active = True)Active_valid(stale = True, active = True)Active_stale(stale = XX, active = False)Inactive

SFC Developer’s Guide 157

Page 172: sfc

4.4 SFC MODELS

4.4.2.2 Service StatePage service state is identical to record service state. It even uses the same RTRMDConnectionClient interface. For more details see section 4.1.2.4.

4.4.3 Class SummaryThis section provides a summary of the classes which comprise the model for real-time page data. For more details please refer to the appropriate sections of the alphabetical class reference.

• RTRRTPage - This class defines an item of real-time page data. Pages represent a stream which provides an image/update model of access to encoded data. Pages support multiple clients which are application components that register with an individual page for data and state events from that page. Because pages are not required to cache an image of the current data, the state of a stream depends in part on the state of the client "viewing" the stream. A page provides the means for clients to request a refresh of the current image, which is presented as an encoded sequence including both character data and presentation attributes encoded for display on character terminals.

• RTRRTPageClient - This is the abstract base class for application components which wish to register with one or more real-time pages in order to receive data and state events from those pages.

• RTRRTPageService - This class provides access to real-time page data and manages the aggregate state of those pages. Service state change events are propagated to those application components which register to receive those events.

• RTRMDServiceClient - This is the abstract base class for components which wish to register with one or more instances of page or record services in order to receive data and state events from those services.

• RTRRTPageServicePool - Instances of this class serve as a repository for all available real-time page services. Typically there is only one instance of this type within an application. A pool provides random and sequential access to the services it contains. A pool provides the means to insert and remove services and allows clients to register for the change events which are generated when the contents are modified.

• RTRRTPageServicePoolClient - This is the abstract base class for components which wish to register with one or more real-time page service pools in order to receive data and state events from those pools. This interfaces does not indicate when the state of a service changes. To

SFC Developer’s Guide 158

Page 173: sfc

4.4 SFC MODELS

monitor state changes in a service (e.g. when a service becomes stale), register directly with the service using RTRMDServiceClient.

• RTRBufferReadIterator - This class provides access to the encoded page images and updates.

4.4.4 ImplementationCurrently, the SFC provides an SSL based implementation of the real-time page model, although other implementations are possible. While most application components should refer only to the base classes mentioned in the preceding section, the "main" routine or initialization section of an application must instantiate one or more implementation specific classes. The implementation classes mentioned here are similar in functionality and implementation to those which provide access to real-time record data and which are presented in section 4.1.3. Please refer to that section for more details.

The SFC page model includes implementation classes for use by both single (simple) and multiple service (more complex) applications. These classes encapsulate the procedures for creating an SSL connection and the page services which use that connection. They are:

• RTRDefaultRTPageService - This class is a descendant of RTRRTPageService (via RTRSSLRTPageService) which creates its own SSL session. It is typically used by simple applications which require access to only a single service.

• RTRDefaultRTPageServicePool - This class is a descendant of RTRRTPageServicePool which creates its own SSL session and monitors that session for page based services. For each observed service, the pool adds to itself an instance of RTRSSLRTPageService. Other application components can, as usual, monitor the pool for new services without being dependent on SSL implementation details.

4.4.5 ExamplesPlease refer to the alphabetical reference section and the relevant example programs for more details concerning these classes. Examples are presented for:

Type of Example Name Description Refer to...

Class AnsiPageSnapshotClient Simple page client component to get snapshot of page

section 4.4.6

Table 4.12: Page Stream Examples

SFC Developer’s Guide 159

Page 174: sfc

4.4 SFC MODELS

4.4.6 Example Class — Simple Page ClientThe purpose of this class is to print a snapshot of a page image on the standard output device. Bear in mind that page data contains embedded escape sequences for presentation on VT100 style terminals. This page client is not concerned with updates or any other events once the initial image as been extracted. The name of this class is AnsiPageSnapshotClient. In order to receive page events, this class is a descendant of RTRRTPageClient. This class must provide implementations of all pure virtual methods inherited from its ancestor. These methods correspond to the events that can be received from RTRRTPage. In this case, some of the event processing methods are implemented to do nothing because this class is not interested in the events in question.

This class processes the following events:

• StreamInfo

• StreamSync

• StreamInactive

This class ignores these events:

• StreamResync

• StreamStale

• StreamUpdate

• StreamRename - note that unlike the logical page model, renamed streams are not automatically re-requested by SFC

Application ansipagesnap.C Creates single instance of AnsiPageSnapshotClient

section 4.4.7

Class AnsiPageUpdateClient Monitors updates from page section 4.4.8

Application ansipageupd.C Creates single instance of AnsiPageUpdateClient

end of section 4.4.8

Type of Example Name Description Refer to...

Table 4.12: Page Stream Examples (Continued)

SFC Developer’s Guide 160

Page 175: sfc

4.4 SFC MODELS

4.4.6.1 Declaration of AnsiPageSnapshotClient (ansipagesnapclient.h)//// This file contains the declaration of AnsiPageSnapshotClient which// illustrates the basic techniques for processing page events. This// class is designed to take a snap-shot of the data for a single page.//

#ifndef _ansipagesnapclient_h#define _ansipagesnapclient_h

#include "rtr/rtpage.h"// Defines RTRRTPageClient

class AnsiPageSnapshotClient : public virtual RTRRTPageClient

{public:// Constructor

AnsiPageSnapshotClient(RTRRTPageService&, const char *);

// Destructor~AnsiPageSnapshotClient();

// Attributes - from RTRRTPageClientRTRRTPage *page();

// Event processingvoid processStreamResync(RTRBufferReadIterator& ) {};

// The stream has new image. It may still be stale. Clients should// check the condition of the stream. It is not relevant here, since // this class takes a snap-shot and teriminates the application.

void processStreamSync(RTRBufferReadIterator& iter);// The stream has an image. It may still be stale. Clients should check// the condition of the stream.

void processStreamStale() {};// The stream data is out-of-date. Stream state information is// available via text(). It is not relevant here, since this // class takes a snap-shot and teriminates the application.

SFC Developer’s Guide 161

Page 176: sfc

4.4 SFC MODELS

void processStreamNotStale() {};// The stream is no longer stale. It is not relevant here, since this // class takes a snap-shot and teriminates the application.

void processStreamInactive();// The stream is invalid. Drop all references immediately. Resources// consumed by the stream will be reclaimed by the service which // provided it.

void processStreamInfo();// The stream has new informational text. The state of the// stream has not changed.

void processStreamUpdate(RTRBufferReadIterator& ) {};// The stream has updated update event processing.// It is not relevant here, since this class// takes a snap-shot and teriminates the application.

protected:// Implementation attributes

RTRRTPage *_page;};

#endif

4.4.6.2 Definition of AnsiPageSnapshotClient (ansipagesnapclient.C)This constructor of this class illustrates the correct procedure to use in accessing pages from a service. In pseudo-code the procedure is as follows:

Get page referenceadd client to pageIf page active then

If page has image thenprocess image and data condition

elseclean up

SFC Developer’s Guide 162

Page 177: sfc

4.4 SFC MODELS

Page data is made available through an instance of RTRBufferReadIterator. For the purposes of page clients, this is a contiguous sequence of storage. The buffer iterator provides access to the storage and conveys the number of bytes in the message. The processStreamSync() method illustrates the technique for accessing the data. Notice that the buffer indexing is based on one, not zero. This class uses some simple escape sequences for cursor positioning when printing status messages.

//// This file contains the implementation of AnsiPageSnapshotClient//

#include "rtr/rtrnotif.h"// Access to event loop#include "rtr/rtpgsrv.h"// RTRRTPageService#include "pagesnapclient.h"

#define CLR_SCRN "\033[2J"#define STATUS_POSITION "\033[25;1H"

//// Constructor// AnsiPageSnapshotClient::AnsiPageSnapshotClient(

RTRRTPageService& service, const char *symbol){ // 1

cout << CLR_SCRN << flush;_page = &(service.rtPage(symbol));_page->addClient(*this);if ( _page->active() ){

if ( _page->imageAvailable() )processStreamSync(_page->imageData());

elseprocessStreamInfo();

}else{ // 2

cout << STATUS_POSITION << "Page inactive:" << _page->text() << flush;_page->dropClient(*this);_page = 0;

}}

SFC Developer’s Guide 163

Page 178: sfc

4.4 SFC MODELS

//// Destructor// AnsiPageSnapshotClient::~AnsiPageSnapshotClient(){// 3

if ( _page )_page->dropClient(*this);

}

RTRRTPage *AnsiPageSnapshotClient::page(){return _page;}

//// Event processing// void AnsiPageSnapshotClient::processStreamInactive(){

cout << STATUS_POSITION << "Page inactive:" << _page->text() << flush;_page->dropClient(*this);_page = 0;

}

void AnsiPageSnapshotClient::processStreamInfo() { // 4

cout << STATUS_POSITION << "Page info:" << _page->text() << flush;}

void AnsiPageSnapshotClient::processStreamSync(RTRBufferReadIterator& iter) { // 5

cout << iter.to_c(1) << flush;if ( _page->stale() )

cout << STATUS_POSITION << "Page stale:" << _page->text() << flush;_page->dropClient(*this);_page = 0;RTREventNotifierInit::notifier->disable();

}

SFC Developer’s Guide 164

Page 179: sfc

4.4 SFC MODELS

// 1 Pages should always be accessed in this manner// * Obtain a reference to the desired page// * Register a client with the page// * Test the state of the page// Services return references to pages, meaning that they are never// null. However, because clients should not retain references to inactive // pages, this class stores a pointer to the page. This so that the pointer// can be set to null in the event of the page being inactive.//// 2 Clients should never remain registered with pages in the inactive state//// 3 Be sure to un-register clients when clients are destructed//// 4 Pages provide informational text about their state.//// 5 The page "sync" event occurs when a page has image data available.// The data is accessed via the given buffer iterator. In this case// the iterator is used to obtained a pointer to the start of the // null-terminated data

4.4.7 Example Application — ANSI Page SnapshotAs would be expected, an application (pagesnap.C) which uses the AnsiPageSnapshotClient class is very similar to that which uses RecordSnapshotClient.

Like RTRDefaultRTRecordService, RTRDefaultRTPageService is an SSL based service which creates its own SSL session (an instance of RTRSSLDispatcher). The only difference is that it provides pages instead of records.

//// This application creates a single instance of a AnsiPageSnapshotClient// The program accepts two arguments: the name of the service and the symbol // of the page to retrieve. //// This application uses an instance of RTRDefaultRTPageService to// provide real-time page data. The class RTRDefaultRTPageService is// a specific implementation of the RTRRTPageService abstraction which// creates its own SSL session (an instance of RTRSSLDispatcher). It is// suitable for simple, single service applications such as this one.

SFC Developer’s Guide 165

Page 180: sfc

4.4 SFC MODELS

#include <iostream.h>

#include "rtr/selectni.h"// Defines RTRSelectNotifier#include "rtr/dfltrtps.h"// Defines RTRDefaultRTPageService#include "pagesnapclient.h"

int main(int argc, char **argv){

if (argc == 3){

// 1RTRDefaultRTPageService service("pageSnapApp", argv[1]);if ( service.active() ){

AnsiPageSnapshotClient snap(service, argv[2]);// 2

RTRSelectNotifier::run();return 0;

}else

cerr << "Service error: " << service.text() << endl;}else

cerr << "Usage: " << argv[0] << " service symbol " << endl;

return -1;}

// 1 The first argument of the RTRDefaultRTPageService is the "context id"// to be used by the service instance. In this case, its the name of the// application. The second argument is the name of the service and is// assumed to be the name of a service available via the SSL . Together// the context id and the name comprise the unique identifier for this servce// instance which is used for configuration purposes.// // 2 This application uses the RTRSelectNotifier as the main loop. It is// possible to use a different implementation.

SFC Developer’s Guide 166

Page 181: sfc

4.4 SFC MODELS

4.4.8 Example Class — ANSI Page UpdatesThis example class is similar to AnsiPageSnapshotClient but adds functionality to monitor the updates from the page of interest. Since the page will be monitored continuously, this class also provides processing for stale events and recovery.

In addition to the events processed by AnsiPageSnapshotClient, this class processes these events:

• StreamStale

• StreamNotStale

• StreamUpdate

4.4.8.1 Declaration of AnsiPageUpdClient (ansipageupdclient.h)//// This file contains the declaration of AnsiPageUpdateClient which// illustrates the basic techniques for processing page update events. This// class is designed to print the image of the requested page and then// monitor that page for updates. Simple ANSI escape sequences are used// for display purposes.//// This class is simlar to AnsiPageSnapshotClient but provides processing// for all events.//

#ifndef _ansipageupdclient_h#define _ansipageupdclient_h

#include "rtr/rtpage.h"// Defines RTRRTPageClient

class AnsiPageUpdateClient : public virtual RTRRTPageClient

{public:// Constructor

AnsiPageUpdateClient(RTRRTPageService&, const char *);

// Destructor~AnsiPageUpdateClient();

SFC Developer’s Guide 167

Page 182: sfc

4.4 SFC MODELS

// Attributes - fromt RTRRTPageClientRTRRTPage *page();

// Event processingvoid processStreamResync(RTRBufferReadIterator& iter);

// The stream has new image. It may still be stale. Clients should// check the condition of the stream.

void processStreamSync(RTRBufferReadIterator& iter);// The stream has an image. It may still be stale. Clients should check// the condition of the stream.

void processStreamStale();// The stream data is out-of-date. Stream state information is// available via text().

void processStreamNotStale();// The stream is no longer stale.

void processStreamInactive();// The stream is invalid. Drop all references immediately. Resources// consumed by the stream will be reclaimed by the service which // provided it.

void processStreamInfo();// The stream has new informational text. The state of the// stream has not changed.

void processStreamUpdate(RTRBufferReadIterator& iter);// The stream has updated update event processing.

protected:// Implementation attributes

RTRRTPage *_page;};

#endif

SFC Developer’s Guide 168

Page 183: sfc

4.4 SFC MODELS

4.4.8.2 Definition of AnsiPageUpdClient (pageupdclient.C)//// This file contains the implementation of AnsiPageUpdateClient//

#include "rtr/rtrnotif.h"// Access to event loop#include "rtr/rtpgsrv.h"// RTRRTPageService#include "pageupdclient.h"

#define CLR_SCRN "\033[2J"#define STATUS_POSITION "\033[25;1H"

// 1

AnsiPageUpdateClient::AnsiPageUpdateClient(RTRRTPageService& service, const char *symbol)

{cout << CLR_SCRN << flush;_page = &(service.rtPage(symbol));if ( _page->active() ){

_page->addClient(*this);if ( _page->imageAvailable() )

processStreamSync(_page->imageData());}else{

cout << STATUS_POSITION << "Page inactive:" << _page->text() << flush;_page = 0;

}}

AnsiPageUpdateClient::~AnsiPageUpdateClient(){

if ( _page )_page->dropClient(*this);

}

SFC Developer’s Guide 169

Page 184: sfc

4.4 SFC MODELS

RTRRTPage *AnsiPageUpdateClient::page() {

return _page;}

void AnsiPageUpdateClient::processStreamResync(RTRBufferReadIterator& iter) { // 2

processStreamSync(iter);}

void AnsiPageUpdateClient::processStreamSync(RTRBufferReadIterator& iter) {

cout << iter.to_c(1) << flush;if ( _page->stale() )

processStreamStale();}

void AnsiPageUpdateClient::processStreamStale() {

cout << STATUS_POSITION << "Page stale:" << _page->text() << flush;}

void AnsiPageUpdateClient::processStreamNotStale() {

cout << STATUS_POSITION << "Page ok:" << _page->text() << flush;}

void AnsiPageUpdateClient::processStreamInactive(){

cout << STATUS_POSITION << "Page inactive:" << _page->text() << flush;_page->dropClient(*this);_page = 0;

}

void AnsiPageUpdateClient::processStreamInfo() {

cout << STATUS_POSITION << "Page info:" << _page->text() << flush;}

SFC Developer’s Guide 170

Page 185: sfc

4.4 SFC MODELS

void AnsiPageUpdateClient::processStreamUpdate(RTRBufferReadIterator& iter){

cout << iter.to_c(1) << flush;}

// 1 It is assumed that the reader is familiar with the AnsiPageSnapshotClient// example.//// 2 Resync events are correspond to unsolicited images. The sync event is// a solicited event. Resync events are used to update a stale image.

An application which uses the AnsiPageUpdateClient can be found in ansipageupd.C. It is very similar to the previous example (section 4.4.7).

SFC Developer’s Guide 171

Page 186: sfc

4.5 SFC MODELS

4.5 Time-Series

4.5.1 Overview

4.5.1.1 Time-SeriesA time-series represents the historical record of market activity for some financial instrument. The history includes data for one or more fields of interest, e.g. price or trading volume over some period. A series is a time-ordered sequence of data samples. Each sample contains the values of the relevant fields at the point in time represented by the sample.

A periodic series provides samples which occur with a fixed frequency, e.g. daily or weekly, and which represent a summary of trading activity for the period between two samples. An aperiodic, or tick, series provides samples which represent actual market activity. The semantics of the two types of series is different. For example, in a periodic series volume would typically represent accumulated volume for the period, while in an aperiodic series, volume would represent the volume of a particular trade. The difference in semantics of the two series manifests itself in the field content of the series.

Samples are the constituent parts of a series. Each has a time-stamp and provides access to its constituent values. In some circumstances a sample may be invalid, e.g. a sample from a daily series which falls on a holiday. Each value has an identifier corresponding to that of the field which it represents. The semantics of the value is determined by the identifier.

Applications need to traverse some or all of the available samples in a series. They may need a fixed number of samples or all of the samples that fall within a certain time period. A client of a series must specify the range of samples which is required, i.e., the "view" which it will take. Retrieval of data for a given view may be synchronous or asynchronous. If asynchronous, a series may be in an incomplete state for some period of time. Once complete, the series is responsible for informing the client that the requested view has been established.

The SFC class representing time-series is RTRTimeSeries. Samples are of type RTRTimeSample, while clients are of type RTRTimeSeriesClient. The time-series client class provides the mechanism by which a series propagates state change events and informational messages to an interested application component.

SFC Developer’s Guide 172

Page 187: sfc

4.5 SFC MODELS

4.5.1.2 Time-Series ServicesTime-series are created by a time-series service whose responsibility is to shield applications from the implementation details associated with retrieving time-series data. Time-series services are descendants of the abstract base class RTRTimeSeriesService.

4.5.1.3 Simple Series When performing calculations, a simplified view of a time-series provides some convenience. An RTRSimpleSeries is similar to a time-series but has data for only a single field. It is derived from an RTRTimeSeries and provides a static representation whose scope is defined by the current view of the series. Access to data values and error checking are simplified.

4.5.2 Time-Series State DiagramTime-series state is defined by the values of two series attributes:

• complete

• error

State transitions are propagated to clients as events. Figure 4.16 shows snapshot time-series states and events causing state transitions.

NOTE: SFC provides two request types for time-series data model when Reuters disable the streaming (updating) TS1 capability. The *requestTS1RealTime configurable parameter is provided for users to change the primary record request behavior to request TS1 data in real-time as opposed to a snapshot. The default value is False.

SFC Developer’s Guide 173

Page 188: sfc

4.5 SFC MODELS

Figure 4.16: Snapshot Time-Series States and Variables

State transitions are propagated to clients as events. Figure 4.17 shows real-time time-serie states and events causing state transitions. The *requestTS1RealTime configurable option has to be set to True.

Complete Incomplete

Error

Error

Complete

(error = False, complete = True)Complete(error = False, complete = False)Incomplete(error = True, complete = XX)Error

SFC Developer’s Guide 174

Page 189: sfc

4.5 SFC MODELS

Figure 4.17: Real-Time Time-Series States and Variables

4.5.3 Class SummaryThis section provides a summary of the classes which comprise the model for time-series data. For more details please refer to the appropriate sections of the alphabetical class reference.

• RTRTimeSeries - This class represents the historical data for a given instrument. A time-series is "owned" by a particular client to whom data and state change events will be propagated. The scope of the data contained by the series is determined by the client. Series provide random (indexed) and sequential access to the data samples which comprise the series. The period (interval between samples) of a time-series is determined when the series is obtained from the providing service.

• RTRTimeSample - Samples are the constituent parts of a time-series and represent a time-stamped collection of values. Samples have state (they may be invalid) and provide random and sequential access to the values they contain.

Complete Incomplete

Error

ErrorError

Complete

(error = False, complete = True)Complete(error = False, complete = False)Incomplete(error = True, complete = XX)Error

InfoInfo/NewSample/NewEvent

SFC Developer’s Guide 175

Page 190: sfc

4.5 SFC MODELS

• RTRSeriesValue - Values contain the historical data values for a particular field of interest, e.g., trading volume for the interval represented by a sample.

• RTRTimeSeriesClient - This is the abstract base class for application components which can own a time-series and which will receive events relating to that time-series.

• RTRTimeSeriesService - This is the abstract base class for providers of time-series data.

• RTRSimpleSeries - A series which contains values for only a single field. Instances of this class are derived from a complete series and are used to provide simplified access to data for a particular field.

• RTRTSValDefDb - The database of field definitions used by a particular service.

• RTRTSValDefDbClient - This is the abstract base class for application components which need to know when the RTRTSValDefDb is completely populated and when it updates.

• RTRSeriesValueDefinition - Provides the description for a column in a time-series. A definition comprises the name, identifier, and type of column. The type determines the way in which the raw data should be interpreted; the name and identifier define the meaning of the field.

4.5.4 ImplementationCurrently, the SFC provides an implementation of the time-series model which relies on the TS1 data available over the Reuters datafeeds. Other implementations are possible. The TS1 implementation uses the abstract interface of either the snapshot or real-time (setting *requestTS1RealTime to True) record model to retrieve the encoded time-series data. While most application components should refer only to the base classes mentioned in the preceding section, the "main" routine or initialization section of an application must instantiate one or more implementation specific classes.

Typically, applications will create a single instance of a TS1 time-series service, which is described in as follows:

• RTRTS1TimeSeriesService - This implementation of RTRTimeSeriesService uses an instance of RTRRTRecordService to retrieve snapshot records or real-time records (setting *requestTS1RealTime to True) containing compressed time-series data in the TS1 format. Please refer to section 4.1.1 for more information on the real-time and snapshot record models and associated implementation classes. TS1 data may span multiple records and must be decompressed prior to use. The implementation relies on numerous underlying classes such as RTRTS1TimeSeries and RTRTS1TimeSample. A complete description of these and related implementation classes is beyond the scope of this manual.

SFC Developer’s Guide 176

Page 191: sfc

4.5 SFC MODELS

4.5.4.1 Multiple ServicesSome applications use more than one service. The connection and service pool factory classes make it easy to incorporate multiple services in a single application.

RTRSSLConnection and RTRTIBConnection can be used to fine tune the connection parameters for the implementation record services. They are described in detail in section 4.8.1.

RTRSSLServicePoolFactory and RTRTIBServicePoolFactory can bed used to manage the life-cycle of and share a single connection among several market data services. They are described in detail in section 4.8.2

4.5.5 ExamplesSFC includes several examples which highlight different parts of the time-series model. All of these examples can be found the sfc/examples/historical/ directory. These examples typically have two parts:

1. main() function that:

• parses command line arguments• creates a service pool factory or record service• creates a time-series client• creates the event control loop

2. SFC client implementation that is responsible for

• requesting a time-series• printing output to standard out

The following table summarized the time-series examples and details where more information about them can be found.

SFC Developer’s Guide 177

Page 192: sfc

4.5 SFC MODELS

4.5.6 TSDump ExampleThis section provides an example which illustrates the behavior of a typical time-series client. For simplicity, its functionality is limited to output. However, it does illustrate the correct way in which to access time-series data by specializing the RTRTimeSeriesClient abstraction. The functional requirements for this client are as follows:

• Given a symbol, retrieve the weekly data for that instrument and print some number of weeks worth of data on the standard output device.

• Print any errors to the standard error device.

• Terminate the application when the data is complete or an error occurs.

To implement these requirements this class must be designed so that:

• It has access to a time-series service. Ideally, this class is not concerned with the implementation of that service.

• It is a time-series client in order to receive events generated by a time-series.

Example Program Description Refer to...

TSDump creates a time-series client to get weekly data a speci-fied number of samples

section 4.5.6tsdump.Ctsbycount.*

TSDates creates a time-series client to get weekly data between the specified dates tsdates.C

tsbydate.*

TSAvg computes simple average of a specified number of weekly samples

tsavg.Csimpleclient.*

Table 4.13: Time-Series Examples

SFC Developer’s Guide 178

Page 193: sfc

4.5 SFC MODELS

4.5.6.1 Declaration of TSClientByCount (tsbycount.h)The example header file which follows declares a descendant of RTRTimeSeriesClient called TSClientByCount. This declaration provides implementations of the pure virtual event-handling methods which are inherited from RTRTimeSeriesClient. The implementation for this class follows the declaration.

//// This file contains the declaration of TSClientByCount which// illustrates the basic techniques for processing time series events. This// class is designed to print a number of samples for a single series.//// The number of samples printed is an argument to the constructor//

#ifndef _tsbycount_h#define _tsbycount_h

#include "rtr/tseries.h"// Defines RTRTimeSeries

class TSClientByCount :public virtual RTRTimeSeriesClient

{public:// Constructor

TSClientByCount(RTRTimeSeriesService&,// The service to useconst char *, // name of instrument to retrieveint // the number of samples to retrieve);

// Event processing - from RTRTimeSeriesClientvoid processSeriesComplete(RTRTimeSeries&);

// Process a "complete" event generated by the series.

void processSeriesError(RTRTimeSeries&);// Process an error event generated by the series.

void processSeriesInfo(RTRTimeSeries&);// Process an informational event generated by the series.

SFC Developer’s Guide 179

Page 194: sfc

4.5 SFC MODELS

protected:// Implementation attributes

RTRTimeSeries _series;};

#endif

4.5.6.2 Definition of TSClientByCount (tsbycount.C)The correct procedure to use in accessing time-series from a service can be represented in pseudo-code as follows:

Get time-seriesIf not time-series error then

If time-series complete thenprocess time-series complete

elseprocess time-series error

This is illustrated in the constructor of TSClientByCount.

//// This file contains the implementation of TSClientByCount.//#include "rtr/rtrnotif.h"// Access to event loop#include "tsbycount.h"//// Constructor//TSClientByCount::TSClientByCount(

RTRTimeSeriesService& service,const char *symbol,int numSamples)

: _series(service.timeSeries(symbol, RTRTimeSeriesService::Weekly, *this))// 1{// 2

// Specify the desired content of the series and check it’s state._series.setView(numSamples);

SFC Developer’s Guide 180

Page 195: sfc

4.5 SFC MODELS

if (!_series.error()){

if (_series.complete())processSeriesComplete(_series);

elseprocessSeriesInfo(_series);

}else

processSeriesError(_series);}

//// Event processing//void TSClientByCount::processSeriesComplete(RTRTimeSeries&) { // 3

cout << _series << endl;RTREventNotifierInit::notifier->disable();

}

void TSClientByCount::processSeriesError(RTRTimeSeries& s){

cerr << s.symbol() << " - Error :" << s.text() << endl;RTREventNotifierInit::notifier->disable();

}

void TSClientByCount::processSeriesInfo(RTRTimeSeries& s){

cerr << s.symbol() << " - Info :" << s.text() << endl;}

// 1 The series is requested with a symbol (the name of underlying instrument),// the desired period, and a client.//// 2 The constructor illustrates how to access the first ‘n’ samples in// a time-series.//// 3 A ostream operator is used here to dump the RTRTimeSeries.

SFC Developer’s Guide 181

Page 196: sfc

4.5 SFC MODELS

This class by itself does not comprise an application. A complete application must provide access to an implementation of RTRTimeSeriesService and must instantiate one (or more) instance of TSClientByCount. The next section illustrates such an application.

4.5.6.3 Example Application — Time-SeriesThis example application uses an RTRTS1TimeSeriesService, a descendant of RTRTimeSeriesService which uses TS1 encoded data extracted from snapshot or real-time records. The program takes three command line arguments: the name of the real-time record service to use (for TS1 data), the symbol for the record whose history is to be retrieved, and the number of samples to print.

This is the output of the program:

> -infra ssl -servicename IDN_SELECTFEED -symbol RTRSY.O -n 4 Date CLS OPN HI LOW VOL11/25/94 44 45.25 45.5 43.75 53480011/18/94 45.375 44.5 46.125 44.5 1.2441e+0611/11/94 45.125 46.5 46.75 45 1.0838e+0611/04/94 47 46.75 48 46.75 2.4099e+06>

This example only shows how to create a time series using a SSL record service. To run using the TIB record implementation, change the sslrtrs.h include and the record constructor to the TIB equivalents. For an example of a single application that can connect to either, see (tsdump.C).

//// This application creates a single instance of a TSClientByCount// The program accepts three arguments: the name of the service, the symbol // of the instrument (e.g. RTRSY.O), and the number of samples to retrieve.//// This application uses TS1 based data which is retrieved via an // implementation of RTRRTRecordService.//

#include <iostream.h>#include <stdlib.h>

#include "rtr/selectni.h"// Defines RTRSelectNotifier#include "rtr/sslrtrs.h"// Defines RTRSSLRTRecordService#include "rtr/ts1srvc.h"// RTRTS1TimeSeriesService

SFC Developer’s Guide 182

Page 197: sfc

4.5 SFC MODELS

#include "tsbycount.h"

int main(int argc, char **argv){

if (argc == 4){

// Allocate the real-time record service used by the// TS1 implementation of RTRTimeSeriesService

// 1RTRSSLRTRecordService rtService("tsDumpApp", argv[1], "");if (rtService.active()){

// Allocate the TS1 based time-series serviceRTRTS1TimeSeriesService tsService(rtService, "IDN_TS1");TSClientByCount client(tsService, argv[2], atoi(argv[3]));

// 2RTRSelectNotifier::run();return 0;

}else

cerr << "Service error:" << rtService.text() << endl;}else

cerr << "Usage: " << argv[0] << " service symbol #_of_samples" << endl;return -1;

}

// 1 A RTRTS1TimeSeriesService needs a RTRRTRecordService from which to request // its data. This example shows a RTRSSLRTRecordService. A RTRTIBRTRecordService// could also be used. The first argument of the RTRSSLRTRecordService is the// "context id" to be used by the service instance. In this case, it is the name // of the application. The second argument is the name of the service and is// assumed to be the name of a service available via the SSL . Together// the context id and the name comprise the unique identifier for this servce// instance which is used for configuration purposes. The third argument is// the username. Since the username is "", the host’s login name will be used. // // 2 This application uses the RTRSelectNotifier as the main loop. It is// possible to use a different implementation.

SFC Developer’s Guide 183

Page 198: sfc

4.5 SFC MODELS

4.5.6.4 Example Code — ostream Output MethodsWhile the TSDump example client illustrates the correct design of a client, it does not provide much detail on how to access the data contained by the series. The output routine used by the program is a good example of how to access samples from the series.

ostream& operator<<(ostream& os, RTRTimeSeries& series){

int hdrdumped = 0;if (series.count() > 0){

for (int i = series.lower(); i <= series.upper(); i++){

if (series[i].valid() && !hdrdumped){

os.width(8);os << "Date";RTRTimeSample& sample = series[series.lower()];for (int j = sample.lower(); j <= sample.upper(); j++){

RTRSeriesValue& value = sample[j];os.width(12);os << value.name();

}os << endl;hdrdumped = 1;

}os << series[i];if (i < series.upper())

os << endl;}

NOTES:

• The series provides array style access to its constituent samples.

• The series provides attributes which define the valid range of indices (upper() & lower()).

SFC Developer’s Guide 184

Page 199: sfc

4.5 SFC MODELS

}return os;

}

Likewise, the output routine used above to print values from a sample illustrates the proper technique to use when extracting values from a sample:

ostream& operator<<(ostream& os, RTRTimeSample& sample){

const RTRDateTime& dateTime = sample.dateTime();os.width(2);os << dateTime.monthNumber();os << "/";os.width(2);os.fill(‘0’);os << dateTime.dayOfMonth();os.fill(‘ ‘);os << "/";os << dateTime.year() - 1900;if (sample.valid()){

for (int i = sample.lower(); i <= sample.upper(); i++){

os.width(12);os << sample[i];

}}else

os << " :" << sample.text();return os;

}

And lastly, the value output routine is as follows:

NOTES:

• Like a series, a sample provides array style access to its constituent values.

• The sample provides attributes which define the valid range of indices (upper() & lower()).

SFC Developer’s Guide 185

Page 200: sfc

4.5 SFC MODELS

ostream& operator<<(ostream& os, const RTRSeriesValue& value){

if (value.valid())os << (float)value;

elseos << value.text();

return os;}

4.5.7 TSDates ExampleThis section illustrates how to implement a time-series client which extracts time-series data by date, rather than just using some number of the most recent samples. The new class is similar to TSClientByCount except that is takes two strings on the constructor rather than the integer value corresponding to the number of samples. These strings are dates using MM/DD/YYYY format.

4.5.7.1 Declaration of TSClientByDate (tsbydate.h)//// This file contains the declaration of TSClientByDate which// illustrates the basic techniques for processing time series events. This// class is designed to print a number of samples for a single series.//// The number of samples printed is determined by dates (as formatted // strings) passed to the constructor. Start dates are more recent than// end dates.//

#ifndef _tsbycount_h#define _tsbycount_h

NOTES:

• Access to the floating point representation of a value is only meaningful if the value is "valid".

• A value provides an operator which allows the application to cast the value as a floating point number (in this case, the explicit cast is required).

SFC Developer’s Guide 186

Page 201: sfc

4.5 SFC MODELS

#include "rtr/tseries.h"// Defines RTRTimeSeries

class TSClientByDate :public virtual RTRTimeSeriesClient

{public:// Constructor

TSClientByDate(RTRTimeSeriesService&,// The service to useconst char *, // name of instrument to retrieveconst char *, // string representing desired start dateconst char * // string representing desired end date);

// Event processing - from RTRTimeSeriesClientvoid processSeriesComplete(RTRTimeSeries&);

// Process a "complete" event generated by the series.

void processSeriesError(RTRTimeSeries&);// Process an error event generated by the series.

void processSeriesInfo(RTRTimeSeries&);// Process an informational event generated by the series.

protected:// Implementation attributes

RTRTimeSeries _series;};

#endif

4.5.7.2 Definition of TSClientByDate (tsbydate.C)The date strings are passed to the setView() method of RTRTimeSeries. This method takes two arguments of type RTRVariableDateTIme. Strings can be used because that class provides a constructor using strings in the required format. The use of strings in this context results in the creation of a temporary object(s). The programmer can, of course, provide date objects instead of strings.

// The definition of TSClientByDate.

SFC Developer’s Guide 187

Page 202: sfc

4.5 SFC MODELS

//

// 1

#include "rtr/rtrnotif.h"

#include "tsbydate.h"

//// Constructor//TSClientByDate::TSClientByDate(

RTRTimeSeriesService& service,const char *symbol,const char *startDate,const char *endDate)

: _series(service.timeSeries(symbol, RTRTimeSeriesService::Weekly, *this)){// 2

_series.setView(startDate, endDate);if (!_series.error()){

if (_series.complete())processSeriesComplete(_series);

elseprocessSeriesInfo(_series);

}else

processSeriesError(_series);}

//// Event processing//void TSClientByDate::processSeriesComplete(RTRTimeSeries&) {

cout << _series << endl;RTREventNotifierInit::notifier->disable();

}

SFC Developer’s Guide 188

Page 203: sfc

4.5 SFC MODELS

void TSClientByDate::processSeriesError(RTRTimeSeries& s){

cerr << s.symbol() << " - Error :" << s.text() << endl;RTREventNotifierInit::notifier->disable();

}

void TSClientByDate::processSeriesInfo(RTRTimeSeries& s){

cerr << s.symbol() << " - Info :" << s.text() << endl;}

// 1 This class is similar in most respects to the TSClientByCount class// of the previous example.//// 2 Here, the content of the series is specified by date, rather than by// count. The setView() method of RTRTimeSeries accepts objects of type// RTRVariableDateTime. Here, the arguments are of type const char * // which cause the compiler to generate temporary variables of type// RTRVariableDateTime, using the appropriate constructor.

The rest of the client implementation stays the same. Obviously, the application (tsdates.C) which uses this client is slightly different from the original application because it must provide two dates.

A modified version of the original application is required. It takes two string arguments instead of the integer. The original version extracted four weeks of data. The data for the same four weeks of the preceding year can be extracted using tsdates as follows:

> -infra ssl -servicename IDN_SELECTFEED -symbol RTRSY.O -d1 11/30/1993 -d2 11/01/1993

Date OPN CLS HI LOW VOL11/26/93 36.125 35.25 36.1875 34.875 2.0072e+0611/19/93 34.9375 36.5625 36.75 34 5.2614e+0611/12/93 36.5625 36.125 37.125 35.9375 2.6146e+0611/05/93 36.4375 36.4375 37.375 35.75 1.941e+06

4.5.8 TSAvg ExampleAs an example, suppose the requirement is to compute the n week simple average of some field from a time-series. The class which implements this is similar to TSClientByCount but takes an extra

SFC Developer’s Guide 189

Page 204: sfc

4.5 SFC MODELS

argument (in addition to the service, symbol, and number of samples arguments) to the constructor which specifies the name of the field on which to perform the computation.

4.5.8.1 Declaration of SimpleSeriesClient (simpleclient.h)//// This file contains the declaration of SimpleSeriesClient which// illustrates how to access a RTRSimpleSeries from an RTRTimeSeries. // A simple series contains the data for just one field from the original// series.//// The data is used to calculate an average.//// The number of samples printed is an argument to the constructor. The// field which is retrieved is also a constructor argument.//

#ifndef _simpleclient_h#define _simpleclient_h

#include "rtr/tseries.h"// Defines RTRTimeSeries

class SimpleSeriesClient :public virtual RTRTimeSeriesClient

{public:// Constructor

SimpleSeriesClient(RTRTimeSeriesService&,// the service to useconst char *, // name of instrument to retrieveint, // the number of samples to retrieveconst char * // name of the field to retrieve);

// Event processing - from RTRTimeSeriesClientvoid processSeriesComplete(RTRTimeSeries&);

// Process a "complete" event generated by the series.

void processSeriesError(RTRTimeSeries&);// Process an error event generated by the series.

SFC Developer’s Guide 190

Page 205: sfc

4.5 SFC MODELS

protected:// Implementation attributes

RTRTimeSeries _series;RTRString _fieldName;

};

#endif

4.5.8.2 Definition of SimpleSeriesClient (simpleclient.C)The processSeriesComplete() method illustrates the technique for accessing a simple series.

//// This file contains the implementation of SimpleSeriesClient.//

#include "rtr/rtrnotif.h"#include "simpleclient.h"

SimpleSeriesClient::SimpleSeriesClient(RTRTimeSeriesService& service,const char *symbol,int numSamples,const char *fieldName)

: _series(service.timeSeries(symbol, RTRTimeSeriesService::Weekly, *this)), _fieldName(fieldName)

{_series.setView(numSamples);if (!_series.error()){

if (_series.complete())processSeriesComplete(_series);

}else

processSeriesError(_series);}

SFC Developer’s Guide 191

Page 206: sfc

4.5 SFC MODELS

void SimpleSeriesClient::processSeriesComplete(RTRTimeSeries&) {

RTRSimpleSeries ss = _series.simpleSeries(_fieldName, _fieldName);float sum = 0;int n = 0;for (int i = ss.lower(); i <= ss.upper(); i++){

if (ss[i].valid()) sum += (float)ss[i];

n++;}if (n)

cout << "Average is : " << sum/n << endl;else

cout << "No valid data" << endl;RTREventNotifierInit::notifier->disable();

}

void SimpleSeriesClient::processSeriesError(RTRTimeSeries& s){

cerr << "Error - " << s.symbol() << ":" << s.text() << endl;RTREventNotifierInit::notifier->disable();

}

An application called tsavg uses the new class and produces the following output:

> -infra ssl -servicename IDN_SELECTFEED -symbol RTRSY.O -n 3 -field volAverage is : 954233>

SFC Developer’s Guide 192

Page 207: sfc

4.6 SFC MODELS

4.6 Inserts

NOTE: The insert model can only be used to contribute data to Triarch and RMDS. See section 5.5.9 for details on how to contribute on an RTIC-based RMDS infrastructure.

4.6.1 OverviewAn insert is used to pass information related to a particular market data item to a service associated with that item. An insert is passed to an insert service, where the insert may be accepted or denied.

An insert transaction starts when an insert is passed to an insert service and ends when the service accepts or rejects the insert. An insert client is the application component that is notified at the completion of an insert transaction.

The format and content of the information provided in an insert is service specific. Therefore, an application utilizing inserts must know how to format information for each insert service. Typically this format is Marketfeed. See the Reuters Marketfeed Reference Manual for details on the Marketfeed data format.

4.6.2 Insert ItemsAn RTRInsert is an abstract class that provides the functions needed to start an insert transaction. In particular, there are functions used to set the name of a market data item and to format the data that will be inserted for that item. Other functions are available to access information associated with the insert transaction. For example, the unique identifier and descriptive text can be set and accessed for each insert.

An RTRInsertClient has the ability to receive notifications regarding the completion of an insert transaction. An insert client is notified the success or failure of the transaction.

An insert transaction starts when an application component obtains a new insert object from an insert service via the newInsert() function of the RTRInsertService object. Note that an insert can have only one client, so a reference to a descendant of RTRInsertClient is passed the newInsert() call. Calling the removeInsert() function, on the other hand, will remove the insert.

The application component is responsible for setting the item name and data portions of the insert object to the appropriate values. The insert’s write() function is invoked to submit the insert. When the transaction is completed, the insert client is notified asynchronously that the insert transaction has ended and that the insert information was either accepted or rejected by the insert service.

SFC Developer’s Guide 193

Page 208: sfc

4.6 SFC MODELS

Note that upon completion of the transaction, all references to the insert must be released so that the insert object may be freed by the insert service.

4.6.3 Insert ServicesThe RTRInsert instance is obtained from a descendant of an RTRInsertService. The insert service provides functions to create and return a new insert object and to access the current state of the service. An insert service may transition between two states: stale and not stale. An insert service that is not stale can create new instances of RTRInsert and process new insert transactions. A stale insert service will complete any outstanding insert transactions, but will not accept any new ones.

An RTRInsertServiceClient has the ability to receive notifications regarding transitions in the state of an insert service.

4.6.3.1 Insert Service PoolsAn insert service may be obtained from an instance of RTRDefaultInsertServicePool.

4.6.4 Insert Request Server1

An insert server may repond to an insert publisher with acknowledgement on each insert received. This is only valid for an SSL insert server on the Market Data Hub. Insert publishers can be on either RMDS or SSL infrastructure. When receiving an insert from an insert publisher downstream, the insert server can indicateInsertSucceeded() or indicateInsertFailed() to the insert publisher. The insert server receives a request for the insert through RTRInsertRequest. The RTRInsertRequest contains the insert object and the methods for acknowledgement.

The implementation of the insert server is done on the RTRRTRecordServiceImplClient interface. The insert request server will receive an event called processInsertRequest(RTRInsertRequest&).The RTRInsertRequest object contains the methods for the insert request server to send acknowledgements. The default implementation for this event is sending an indicateInsertFailed() to the insert publisher.

When sending an indicateInsertFailed(), application may set the failure text by using setText2

1. Publishers are able to receive inserts; subscription clients are able to publish out inserts. In this section, ’insert pub-lisher’ is the subscription client. the ’insert request server’ is the publisher that is able to respond to inserts.

2. The setText method limits text length to 80 characters; the exceeded characters will be truncated.

SFC Developer’s Guide 194

Page 209: sfc

4.6 SFC MODELS

method. It may also set the failure code by using setNakCode method. See Reference Manual for more details.

If the default implementation is overriden, the insert request server must make sure to send acknowledgements in a timely fashion for the following reason. For each insert received, it is added to a list. When the insert request server sends a success or failure for an insert, that particular insert is then removed from the list and deleted. If the insert request server never sends success or failure for that insert, this insert will only be removed and deleted when the service is marked stale, at which time a failure for that insert will be sent.

A constraint for this insert request server is that if it never sends success or failure on a insert, the insert request server’s cache has the potential of running out of RAM; each insert received is put into the list. The insert request server application must keep track of inserts at all times.

4.6.5 Example Class — Insert ServerThis program will create a publishing service that sends an acknowledgement back to the insert sender whenever it receives an insert. This program is based on example program Simulator. See the Simulator example for more detailed description of a publishing application. This section will only explain how to implement the methods necessary to ensure inserts are received and acknowledgements are sent.

4.6.5.1 Creating an ApplicationThis section is the same as that for the Simulator example (see section 4.2.6.8). The insert request server is only supported on the Market Data Hub; therefore, the -pubinfra option must be set to "ssl" to run this application.

Header file...See Simulator code for simsrvc.h ...// along with processNewRecord(RTRRTRecordServiceImpl&, RTRRTRecordImpl&)// Insert Request Server need to implement the// processInsertRequest(RTRInsertRequest) method.

// ... continue from Simulator code

// inherited from RTRRTRecordServiceImplClientvoid processInsertRequest(RTRInsertRequest&);

Source file

SFC Developer’s Guide 195

Page 210: sfc

4.6 SFC MODELS

...See Simulator code for simsrvc.C ...// ... continue from Simultor code

void SimpleInsertReply::processInsertRequest(RTRInsertRequest& request){

if (request.length()>0)request.indicateInsertSucceeded();

elserequest.indicateInsertFailed();

}

4.6.5.2 Example Class — Insert ClientThis program will create an RTRDefaultInsertServicePool, create an RTRInsertService instance, wait for the service to become synchronized (not stale), then do one insert transaction and exit. Text is printed out to describe each action as it occurs.

The header file siminsrt.h contains the definition for class SimpleInsertExample. This class inherits from RTRInsertServiceClient and RTRInsertClient so it can receive event notifications from instances of RTRInsertService and RTRInsert. SimpleInsertExample takes at construction a reference to an insert service, the name of a data item, and insert data formatted into a string.

The function sendInsert() handles the task of obtaining an insert object, filling in the item name and data portions of the insert, and sending the insert to the insert service.

At construction, the program determines whether the service is stale or not. If the service is not stale, the insert is immediately formatted and sent. Otherwise this class becomes a client of the insert service so it can be notified when the service becomes not stale. Note that the service’s addClient() function is called to register interest in notifications for this insert service client. The dropClient() function is called to drop interest.

The insert object provides a buffer write iterator that is used to set the insert’s data.

4.6.5.3 Declaration for SimpleInsertExample (siminsrt.h)#include "rtr/rtrdefs.h"#include "rtr/sslinsrt.h"#include "rtr/insrtcli.h"#include "rtr/insrtscl.h"#include "rtr/rtstring.h"

SFC Developer’s Guide 196

Page 211: sfc

4.6 SFC MODELS

class SimpleInsertExample : public RTRInsertServiceClient, public RTRInsertClient

{protected:

RTRInsertService& _service;RTRString _itemName;RTRString _insertData;void releaseResources();

public:

// Constructor

SimpleInsertExample(RTRInsertService& service, RTRString& itemName,RTRString& data);

// Create an insert example that uses the given insert service// to send an insert to the given name with the given data.

// Destructor

virtual ~SimpleInsertExample();

void sendInsert();// Send an insert and wait for a response.

// Inherited from RTRInsertServiceClient

void processServiceSync(RTRInsertService& srvc);// The given service is capable of processing inserts.

void processServiceStale(RTRInsertService& srvc);// The given service is temporarily unable to process inserts.

void processServiceInfo(RTRInsertService& srvc);// New descriptive text is available for the given service.

// Inherited from RTRInsertClient

SFC Developer’s Guide 197

Page 212: sfc

4.6 SFC MODELS

void processInsertSucceeded(RTRInsert& insert);// The given insert request succeeded.

void processInsertFailed(RTRInsert& insert);// The given insert request failed.

};

4.6.5.4 Definition for SimpleInsertExample (siminsrt.C)#include <iostream.h>#include "simple.h"#include "rtr/selectni.h"#include "rtr/dfltispl.h"#include "rtr/objid.h"#include "rtr/rtxfdb.h"

SimpleInsertExample::SimpleInsertExample(RTRInsertService& service, RTRString& itemName, RTRString& data)

: _service(service),_itemName(itemName),_insertData(data)

{// If the given service is already synchronized, send the insert.// Otherwise add this instance as a client of the service so// a notification can be received when the service becomes// synchronized.

if (!service.stale()){

cout<<"Service "<<_service.name()<<" is ok."<<endl<<endl;sendInsert();

}else{

cout<<"Service "<<_service.name()<<" stale. Waiting...";cout<<endl<<endl;service.addClient(*this);

}};

SFC Developer’s Guide 198

Page 213: sfc

4.6 SFC MODELS

SimpleInsertExample::~SimpleInsertExample(){;};

void SimpleInsertExample::sendInsert(){

cout<<"Sending insert for item "<<_itemName<<" and data "<<_insertData;cout<<" to service "<<_service.name()<<endl<<endl;

// Obtain an insert from the service and// fill in the item name. //

RTRInsert& insert = *(_service.newInsert(*this));insert.setItemName(_itemName);

// Set the insert data. Note that this is a simple example// that sets the data to a string value. The buffer write// iterator provides functions to write formatted data,// like Marketfeed, into the buffer.//

RTRBufferWriteIterator it = insert.dataWriteIterator();it.appendString(_insertData);it.writingCompleted();

// Write the insert to the service. Notification// regarding the success or failure of the insert// transaction comes via callback to the processInsertSucceeded()// or processInsertFailed() functions inherited into// this class from RTRInsertClient.//

insert.write();};

void SimpleInsertExample::processServiceSync(RTRInsertService& srvc)// The given service is capable of processing inserts.

{cout<<"Service "<<srvc.name()<<" is now OK. Doing insert"<<endl<<endl;

// Drop as a client of this service and send the insert// now that the service is active.

SFC Developer’s Guide 199

Page 214: sfc

4.6 SFC MODELS

srvc.dropClient(*this);sendInsert();

};

void SimpleInsertExample::processServiceStale(RTRInsertService& srvc)// The given service is temporarily unable to process inserts.

{cout<<"Service "<<srvc.name()<<" is now STALE."<<endl<<endl;cout<<"Service Text: "<<srvc.text()<<endl;

};

void SimpleInsertExample::processServiceInfo(RTRInsertService& srvc)// New descriptive text is available for the given service.

{cout<<"Service "<<srvc.name()<<" has new INFO."<<endl<<endl;cout<<"Service Text: "<<srvc.text()<<endl;

};

void SimpleInsertExample::processInsertSucceeded(RTRInsert& insert)// The given insert request succeeded.

{cout<<"The insert for item "<<insert.itemName()<<" succeeded."<<endl;cout<<"Text: "<<insert.text()<<endl<<endl;cout<<"TEST COMPLETE"<<endl;

releaseResources();};

void SimpleInsertExample::processInsertFailed(RTRInsert& insert)// The given insert request failed.

{cout<<"The insert for item "<<insert.itemName()<<" failed."<<endl<<endl;cout<<"Text: "<<insert.text()<<endl;cout<<"TEST COMPLETE"<<endl;

releaseResources();};

void SimpleInsertExample::releaseResources(){

SFC Developer’s Guide 200

Page 215: sfc

4.6 SFC MODELS

// For the purposes of this example, just do nothing.};

4.6.6 Example Application — InsertsThe application setup (in simpleinsert.C) includes the following

#include "siminsrt.h"#include "rtr/selectni.h"// RTRSelectNotifier#include "rtr/tsaisrvc.h"// RTRTSAInsertService#include "rtr/sslinsrt.h"// RTRSSLInsertService

RTRObjectId appId("SimpleInsert");RTRInsertService *insertService = 0;void cleanup(int, char * = 0);void setup(int, char **);void createLogger(int, char **);RTRString infra, servicename, symbol, servicePort, daemon, network, value;

int main(int argc, char **argv){

// Parse the command line arguments and create a configDb setup(argc, argv);

// Create a logger. createLogger(argc, argv);

// Select which architecture to consume from if (infra == "tsa")

{ insertService = new RTRTSAInsertService(appId, servicename servicePort,

network, daemon); }

else if (infra == "ssl") {

insertService = new RTRSSLInsertService(appId, servicename, ""); }

elsecleanup(-1, argv[0]);

// value is the data to insert SimpleInsertExample example(*insertService, symbol, value);

SFC Developer’s Guide 201

Page 216: sfc

4.6 SFC MODELS

RTRSelectNotifier::run();

cleanup(0, argv[0]); return 0;}

SFC Developer’s Guide 202

Page 217: sfc

4.7 SFC MODELS

4.7 Session

NOTE: The session model is independent of infrastructure. It does not use Rrendezvous or Triarch.

4.7.1 Message Session

4.7.1.1 The ModelApplications that need to communicate with other application processes may utilize a wide variety of communication protocols and their associated utilities (e.g. TCP/IP, UDP/IP, NETBIOS, WinSock, etc.). Each of these protocols and associated utilities provide benefits to an application given constraints of machine type, network type or specific application requirements.

While the capabilities provided by these protocols are quite similar, the programming interfaces used to access them are not. Changing from one protocol to another in a user application typically means substantial changes in application code. Most applications that utilize inter-process communications would benefit from being able to use the same interface for passing messages between peers.

An object oriented analysis of this problem domain yields the concept of a message session, which has the following characteristics:

• A message session provides message based communication between two peer components.

• A message session transmits messages reliably. Messages are checked for errors and will not be lost.

• A message session preserves message boundaries. Messages received from a peer have the same size as when they are sent since message fragmentation and re-assembly is handled by the message session.

• A message session has a single client that receives asynchronous event notifications. In particular, a message session client is notified whenever a new message becomes available and whenever the state of the message session changes.

• A message session is established and may eventually be terminated.

• A message session is uniquely identified from other sessions.

The message session cluster contains classes that encapsulate these characteristics. The main benefits of using the SFC message session classes is they:

SFC Developer’s Guide 203

Page 218: sfc

4.7 SFC MODELS

• provide one simple interface (RTRMessageSession) for exchanging messages between two peer application components,

• provide implementation classes of the abstract interface that utilize particular communication protocols and shield the user from the intricacies of learning how to code to these protocols interfaces.

The abstract message session interface defines the message exchange portion of peer-to-peer communication while the specific implementation classes, like a TCP Client Session, define and implement the abstract interface by using a particular communication protocol and determine how a message session is created and how associations are made to a peer application component.

4.7.1.2 Message Session AbstractionThe RTRMessageSession class provides an abstract interface that allows application components to send and receive messages.

Messages are sent to a peer by allocating a message and obtaining a message write iterator of type RTRMessageWriteIterator that is used to format a message. The iterator’s send() function is called to send the message to the peer session. If an outgoing message cannot immediately be sent to the peer, the sending session queues the message and sends it when the peer is able to accept more messages. The session can queue all the messages that the session can allocate.

Messages received from a peer are obtained from the message session by calling the session’s lastMessageReceived() function which returns a message read iterator of type RTRMessageReadIterator. The message read iterator provides functions to access message data as different sized numerics and as variable sized strings. The user will always receive a full message as sent by the peer session, since fragmentation and reassembly of a message is handled by the message session.

A descendant of RTRMessageSessionClient receives asynchronous event notifications from a RTRMessageSession instance whenever a new message is available from its peer and whenever the state of the session has changed. A message session will have one and only one client.

The connected() method indicates whether the session is currently connected to its peer. The RTRMessageSessionClient is notified when the peer connection is lost and must release all session references.

SFC Developer’s Guide 204

Page 219: sfc

4.7 SFC MODELS

4.7.2 Example — Simple Message Session ClientsThe next two sections provide a pair of examples which illustrate the behaviour of typical programs that use message sessions to communicate with each other. In particular, these sections illustrate how to implement a message session client, how to read messages from the message session, and how to write messages to the message session. For simplification, the output of the classes is limited to printing on the standard output device.

4.7.2.1 Basic Requirements for Reply ClassThe hypothetical functional requirements for this client are as follows:

• An instance of this class is a message session client and receives events whenever a new message is available for reading and when the state of the message session becomes disconnected.

• An instance of this class waits to receive a message from its peer via the message session.

• The expected message contains the string "HELLO. ARE YOU THERE?" and a message number.

• Upon receiving a message from the peer, the message information is printed and a reply message is formatted and sent to its peer via the message session. The reply message contains the string "YES. I AM HERE?" and the message number received from the peer.

• When the session’s peer disconnects, it causes the message session to indicate that the message session has become disconnected. The message session and this class instance are then terminated.

To implement these requirements, this class must be designed so that:

• It is given a reference to a message session.

• It is a message session client so it can be notified whenever a message is available and whenever the session state changes.

• It cleans up properly after the peer terminates communications.

The example header file which follows declares a descendant of RTRMessageSessionClient called Reply. RTRMessageSessionClient declares several pure virtual methods which must be implemented by descendants. The Reply class declares implementations of these methods, which are: processSessionMessage(), processSessionDisconnected(), and processSessionAllocationReady().

SFC Developer’s Guide 205

Page 220: sfc

4.7 SFC MODELS

The implementation for this class follows the declaration. It illustrates the correct procedure to use in reading and writing messages with a message session. In pseudo-code, the procedure for writing a message is:

Allocate message from message sessionIf message available from session then

Get a write iterator for the allocated messageFormat data into the messageSend the message

elseWait for allocation ready event from message session or take other action

In pseudo-code, the procedure for reading a message when the processSessionMessage() function is called is:

Obtain from message session a read iterator to the new messageUse the iterator methods to extract message information

4.7.2.2 Declaration for Reply (reply.h)

#ifndef _reply_h#define _reply_h

#include "rtr/rtrdefs.h"#include "rtr/msgsess.h"// Message session

class Reply: public virtual RTRMessageSessionClient

{public:// Constructor

Reply();

// Destructorvirtual ~Reply();

// From RTRMessageSessionClientvoid processSessionMessage(RTRMessageSession& session);

// This method is invoked when a new message has been // received from the session. The method

SFC Developer’s Guide 206

Page 221: sfc

4.7 SFC MODELS

// session.lastMessageReceived() is invoked to retrieve// the message.

void processSessionDisconnected(RTRMessageSession& session);// This method is invoked when the session becomes // disconnected from its peer. This is a permanent // condition and requires that the session resources // be cleaned up.

void processSessionAllocationReady(RTRMessageSession& session);// This method is invoked when the session is again // capable of allocating messages after a // session.allocateMessage() call had failed.

// Locally introduced method(s)void setSession(RTRMessageSession* session);

// Set the message session used for peer communication.

RTRBOOL hasSession();// Is a session set for this instance?

protected: void sendReply();

// Format and send the reply message "YES. I AM HERE" // to the given peer session.

void releaseResources();// Release all resources held by this instance.

RTRMessageSession *_session; // Session for communication.static RTRString responseString; // String sent in reply message.u_16 _messageCount; // Last message count received.

};

#endif // _reply_h

4.7.2.3 Definition for Reply (reply.C)

#include <iostream.h>

SFC Developer’s Guide 207

Page 222: sfc

4.7 SFC MODELS

#include "reply.h"

Reply::Reply(): _session(0)

{};

Reply::~Reply(){

releaseResources();};

void Reply::processSessionMessage(RTRMessageSession& session){

// Get an iterator to the message just received.RTRMessageReadIterator msg = session.lastMessageReceived();

// Set message iterator to start of message.msg.start();

// Parse out the length field for the string part.u_32 _stringPartLength = msg.getUnsigned32();

// Move read cursor to next message element.msg.forth();

// Parse out the string part.RTRString tmpStr = msg.getString( _stringPartLength );msg.forth();

// Parse out the message count._messageCount = msg.getUnsigned16();

cout<<"Reply: Got message "<<_messageCount<<" from peer ";cout<<session.name()<<": \""<<tmpStr<<"\""<<endl;

// Send a reply containing the message count received from the// requestor.

sendReply();};

SFC Developer’s Guide 208

Page 223: sfc

4.7 SFC MODELS

void Reply::processSessionDisconnected(RTRMessageSession& session){

// Session is no longer viable. This is a permanant condition, // so release resources and delete this instance.

cout<<"Reply: Session "<<session.name();cout<<" has DISCONNECTED. Terminating this Reply instance."<<endl;delete this;

};

void Reply::processSessionAllocationReady(RTRMessageSession& session){

// Message may be allocated again, so attempt to // send the reply message.

cout<<"Reply: Session "<<session.name()<<" ready for writing."<<endl;sendReply();

};

void Reply::setSession(RTRMessageSession* session){

RTPRECONDITION( !hasSession() );_session = session;

};

RTRBOOL Reply::hasSession(){

return _session != 0 ? RTRTRUE : RTRFALSE;};

void Reply::sendReply(){

// Allocate a new message write buffer._session->allocateMessage();

// Check if allocation succeeded.if (_session->isMessageAllocated()){

// Get a write iterator to the message buffer.RTRMessageWriteIterator msg = _session->lastAllocatedMessage();

SFC Developer’s Guide 209

Page 224: sfc

4.7 SFC MODELS

// Format the string part length.msg.appendUnsigned32(responseString.count());

// Format the string part.msg.appendString(responseString);

// Format the message countmsg.appendUnsigned16(_messageCount);

// Send the message to the peer requestor.msg.send();if (_session->connected()){

cout<<"Reply: Sending reply to session ";cout<<_session->name()<<endl<<endl;

}else

processSessionDisconnected(*_session);}else

// The processSessionAllocationReady() method will be // invoked by the message session when more messages // can be sent.

cout<<"Reply: Unable to send message! Waiting..."<<endl;};

void Reply::releaseResources(){

// Delete the session.if (_session != 0){

_session->terminate();_session = 0;

}};

RTRString Reply::responseString = RTRString("YES. I AM HERE.");

SFC Developer’s Guide 210

Page 225: sfc

4.7 SFC MODELS

4.7.3 Example — Another Simple Message Session ClientThe class described in this section is the sender of the messages expected by the Reply class. This class is also a message session client and has the following functional requirements:

• An instance of this class has a message session that is used to send request messages to a peer Reply instance.

• A message containing the string "HELLO. ARE YOU THERE?" and a message count are formatted and sent to the peer via the message session.

• An instance of this class then waits for a reply message. Upon receiving a message from the peer, the message information is printed and a timer is set to go off in 5 seconds.

• When the timer goes off, another message is sent to the peer.

• When a reply with a message count value of 10 is received, the message session and this class instance are terminated.

To implement these requirements, this class must be designed so that:

• It is given a reference to a message session.

• It is a message session client so it can be notified whenever a message is available and whenever the session changes state.

• It cleans up properly after it receives the tenth message.

• It inherits from timer command in order to do timing

The following example header file request.h is similar to the reply.h header file in that it declares a descendant of RTRMessageSessionClient and then declares implementations of the pure virtual methods inherited from RTRMessageSessionClient. However, this class (called Request) class also inherits from the RTRTimerCmd class. The RTRTimerCmd class provides methods to set timing events and a pure virtual method that is invoked when the timer expires. The implementation for this class follows the declaration.

4.7.3.1 Declaration for Request (request.h)

#include "rtr/rtrdefs.h"#include "rtr/rtstring.h"#include "rtr/msgsess.h"#include "rtr/tcpssvr.h"

SFC Developer’s Guide 211

Page 226: sfc

4.7 SFC MODELS

class Request: public virtual RTRMessageSessionClient, public virtual RTRTimerCmd

{public:// Constructor

Request();

// Destructorvirtual ~Request();

// From RTRMessageSessionClientvoid processSessionMessage(RTRMessageSession& session);

// This method is invoked when a new message has been // received from the session. The method // session.lastMessageReceived() is invoked to retrieve// the message.

void processSessionDisconnected(RTRMessageSession& session);// This method is invoked when the session becomes // disconnected from its peer. This is a permanent // condition and requires that the session resources // be cleaned up.

void processSessionAllocationReady(RTRMessageSession&);// This method is invoked when the session is again // capable of provided messages after a // session.allocateMessage() call had failed.

// From RTRTimerCmdvoid processTimerEvent();

// This method is invoked when the timer goes off.

// Locally introduced method(s)void setSession(RTRMessageSession* s);

// This class also writes messages to its peer and // needs access to the message session. This method // sets the message session, which is then owned by

SFC Developer’s Guide 212

Page 227: sfc

4.7 SFC MODELS

// this instance. // REQUIRE: !hasSession()

RTRBOOL hasSession();// Is a session set for this instance?

void start();// Start sending request messages.// REQUIRE: hasSession()

protected:

void sendRequest();// Start sending request messages.

void activateTimer();// Activate the timer to go off in 5 seconds.

void releaseResources();// Release all resources held by this instance.

RTRMessageSession *_session; // Session for communication.static RTRString _requestString; // String sent in request message.u_16 _messageCount;// Current number of messages sent.

};

#endif //_request_h

4.7.3.2 Definition for Request (request.C)

#include <iostream.h>#include "rtr/selectni.h" // Notifier#include "rtr/tcpcsess.h" // Tcp client session#include "rtr/tcpidimp.h" // Socket identifier#include "request.h" // Request

Request::Request() : RTRTimerCmd(),

SFC Developer’s Guide 213

Page 228: sfc

4.7 SFC MODELS

_session(0), _messageCount(1){};

Request::~Request(){ releaseResources();};

void Request::processSessionMessage(RTRMessageSession& session){

// Get an iterator to the message just received. RTRMessageReadIterator msg = session.lastMessageReceived();

// Set message iterator to start of message. msg.start();

// Parse out the length field for the string part. u_32 _stringPartLength = msg.getUnsigned32();

// Move read cursor to next message element. msg.forth();

// Parse out the string part. RTRString tmpStr = msg.getString( _stringPartLength ); msg.forth();

// Parse out the message count. u_16 _returnCount = msg.getUnsigned16();

// Print a message to standard output device. cout<<"Requestor: Got response message "<<_returnCount; cout<<" from peer "<<session.name()<<": \""<<tmpStr;

cout<<"\". Waiting 5 seconds..."<<endl<<endl;

// Terminate when the tenth response is received. if (_returnCount >= 10) { cout<<endl<<"Requestor: Received tenth reply. Terminating."<<endl;

SFC Developer’s Guide 214

Page 229: sfc

4.7 SFC MODELS

delete this; }

// Otherwise activate the timer to send another message in 5 seconds. else activateTimer();};

void Request::processSessionDisconnected(RTRMessageSession& session){

// Session is no longer viable. This is a permanant condition, // so release resources and delete this instance.

cout<<"Requestor: Session "<<session.name();cout<<" is DISCONNECTED. Deactivating now."<<endl;

delete this;};

void Request::processSessionAllocationReady(RTRMessageSession&){

// Messagess are now available, so attempt to send the // request message.

sendRequest();};

void Request::processTimerEvent(){

// The 5 second timer has expired. Send another request message. sendRequest()};

void Request::setSession(RTRMessageSession* s){

// Precondition enforces the fact that the session // for this instance can only be set once.

RTPRECONDITION( !hasSession() ); _session = s;};

RTRBOOL Request::hasSession(){ return _session != 0 ? RTRTRUE : RTRFALSE;

SFC Developer’s Guide 215

Page 230: sfc

4.7 SFC MODELS

};

void Request::start(){ RTPRECONDITION( hasSession() ); sendRequest();};

void Request::sendRequest(){ RTPRECONDITION( _session != 0 );

cout<<"Requestor: Sending request message "<<_messageCount; cout<<" to Reply peer instance "<<_session->name()<<endl<<endl;

// Allocate a message from the message session _session->allocateMessage();

// Check if message is allocated. if (_session->isMessageAllocated()) {

// Obtain an iterator to the allocated message RTRMessageWriteIterator msg = _session->lastAllocatedMessage();

// Format the length of the string part msg.appendUnsigned32(_requestString.count());

// Format the string part. msg.appendString(_requestString);

// Format the message number msg.appendUnsigned16(_messageCount++);

// Send the message to the peer. msg.send();

// Check that session is still connected after the // message write. If not, then this session is // permanently disconnected, so process like a // disconnect.

SFC Developer’s Guide 216

Page 231: sfc

4.7 SFC MODELS

if (!_session->connected()) processSessionDisconnected(*_session); } else

// The processSessionAllocationReady() method will be // invoked by the message session when more messages // can be sent.

cout<<"Requestor: Unable to send message! Waiting..."<<endl;};

void Request::activateTimer(){

// Set the time, in seconds, for the timer and activate. setTimerOffset((long)5, (short)0); activate();};

void Request::releaseResources(){

// Delete the session. if (_session != 0) { _session->terminate(); _session = 0; }

// If timer is active, deactivate it. if (active()) deactivate();};

RTRString Request::_requestString = RTRString("HELLO. ARE YOUR THERE?");

4.7.4 TCP/IP Socket Implementation of Message Session

4.7.4.1 The ModelThe RTRMessageSession class is an abstract class that defines methods for sending and receiving messages with a peer session. Decisions regarding any communication protocols and mechanisms

SFC Developer’s Guide 217

Page 232: sfc

4.7 SFC MODELS

that may be used to implement the abstract interface are determined by RTRMessageSession descendants.

One such descendant relies upon the TCP/IP protocol suite and sockets to implement a message session. TCP presents users with a client/server model in which a server is established on a well known port and clients connect to that port to start a communication session. When the TCP server receives a connection attempt, a new socket is allocated for communications with the TCP client.

The TCP implementation of the message session classes use a similar model. A TCP session server, (RTRTcpSessionServer) is a TCP server that accepts connections from TCP client session instances and propagates to its event client an event indicating that a new message session is available.

A TCP client session (RTRTcpClientSession) is a message session descendant that attempts to establish a connection with a specific TCP session server instance. If the connection to the server succeeds, the message session is considered established and messages may be passed between itself and a peer session.

A TCP server session (RTRTcpServerSession) is a message session descendant that is created by the TCP session server whenever another session connects to the session server. Upon creation, the session is used to exchange messages with a peer TCP client session.

4.7.4.2 TCP Session Server Event Client TypesA TCP session server propagates events to a particular type of event client called a TCP session server client (RTRTcpSessionServerClient). User defined classes inherit from a TCP session server client and define appropriate actions to take when an event occurs. When a descendant of a TCP session server client is notified of the availability of a new message session, it has the option to accept or reject the new message session. A new message session is accepted by obtaining from the TCP session server a TCP server session instance that will communicate with the peer TCP client session. A new message session is rejected by simply ignoring the event notification. In this case the TCP client session making the connection attempt will be left in a disconnected state.

The following section provides an example of a TCP session server client. Sample applications that use this example and the Request and Reply classes defined in section 4.7.1 are provided after the next section.

SFC Developer’s Guide 218

Page 233: sfc

4.7 SFC MODELS

4.7.5 Example — A Simple TCP Session Server ClientThis section provides an example that illustrates the behavior of a typical TCP session server client. Note that this example makes use of the Reply class defined in section 4.7.2. The hypothetical functional requirements for this client are as follows:

• An instance of this class monitors a single TCP session server, waiting for new sessions to become available.

• An instance of this class always accepts a new message session when one becomes available.

• Whenever a new message session becomes available, an instance of this class creates a Reply instance and provides it the message session.

• Reply instances will wait for messages from the peer Request instance and respond to the messages received. The Request instance terminates communications after the tenth message is returned by the peer Request instance.

To implement these requirements, this class must be designed so that:

• It creates a TCP session server instance.

• It is a TCP session server client and becomes the client for the TCP session server it creates.

• It exists in an error state if the TCP session server instance is in error.

For the purposes of this example, the TCP session server client implementation assumes that each new message session is meant for a Reply instance and that each Reply instance will terminate itself.

The example header file which follows declares a descendant of RTRTcpSessionServerClient called ReplyServer. RTRSessionServerClient declares one pure virtual method which must be implemented by descendants. The ReplyServer class declares an implementation of this method, which is: processNewSession(). This method passes two parameters: the TCP session server that propagated the event and an identifier used to obtain the new message session from the TCP session server.

The implementation for this class follows the declaration. It illustrates the correct procedure for obtaining a new message session from a RTRTcpSessionServer instance. Note that a new message session may only be obtained while the thread of control is in the processNewSession() method.

4.7.5.1 Declaration for Reply Server (replysvr.h)

#ifndef _reply_server_h#define _reply_server_h

SFC Developer’s Guide 219

Page 234: sfc

4.7 SFC MODELS

#include "rtr/rtrdefs.h"#include "rtr/rtstring.h"// String#include "rtr/msgsess.h"// Message session#include "rtr/tcpssvr.h"// Tcp Session Server

class ReplyServer: public virtual RTRTcpSessionServerClient

// Inherit TCP session server client to receive event notification.{public: // Constructor

ReplyServer(RTRTcpSocketIdentifier& identifier);

// Destructor~ReplyServer();

// From RTRMessageSessionServerClientvoid processNewSession(RTRTcpSessionIdentifier& id,

RTRTcpSessionServer& svr);// This method is invoked when a new message session is // available from the session server.

// Locally introduced method(s)RTRBOOL error();

// Is the server in an error state? True if unable // to create session server.

const char *errorText();// Text describing the error.

protected: RTRTcpSessionServer _server;

// Session server instance};

#endif // _reply_server_h

SFC Developer’s Guide 220

Page 235: sfc

4.7 SFC MODELS

4.7.5.2 Definition for Reply Server (replysvr.C)

#include "rtr/selectni.h"#include "rtr/tcpidimp.h"// Tcp socket identifier #include "replysvr.h"// Reply server#include "reply.h"// Reply

ReplyServer::ReplyServer(RTRTcpSocketIdentifier& identifier): _server(identifier.to_c(),

identifier, *this)

{// The Tcp Session Server is created with this instance as // the event client. Note that default values will be used // for configurable variables of the message session instances// created by this session server.

};

ReplyServer::~ReplyServer(){};

void ReplyServer::processNewSession(RTRTcpSessionIdentifier& id, RTRTcpSessionServer& svr)

{Reply *_newReply = new Reply;

// Create new Reply instance for the peer Request // instance.

RTRString sessionName("ReplySession");

RTRTcpServerSession::setDefaultNumberWriteMessages(5);RTRTcpServerSession::setDefaultWriteMessageSize(200);

// Create a message session for use by Reply instance // to communicate with peer.

RTRMessageSession* _session = svr.createSession( id,*_newReply);

// Give new message session to the Reply instance.

SFC Developer’s Guide 221

Page 236: sfc

4.7 SFC MODELS

_newReply->setSession(_session);

cout<<"ReplyServer: New Requestor added to communicate with Request instance at "<<_session->name()<<endl;

};

RTRBOOL ReplyServer::error(){

// Reply server’s error is based on state of it’s // TCP session server.

return _server.error();};

const char* ReplyServer::errorText(){

// Reply server’s error text based on TCP session // server’s error text.

return _server.errorText();};

4.7.6 Example — A Simple Application Using ReplyServerThis section provides the text of an application that uses the ReplyServer class from section 4.7.5 and the Reply class from section 4.7.2. This text is also found in the file replysvr.C.

main(int argc, char **argv){

if (argc == 2){

// Create a tcp socket identifier that identifies the // port number this Tcp Session Server will establish // itself on.

RTRTcpSocketIdentifierImpl _serverSocketId(argv[1]);if (_serverSocketId.isValid()){

// Create the client for the Tcp Session ServerReplyServer _replyServer(_serverSocketId);

// Check that ReplyServer instance started // properly.

SFC Developer’s Guide 222

Page 237: sfc

4.7 SFC MODELS

if (!_replyServer.error()){

cout<<endl<<"Reply server ready for requests"<<endl;

// Enable the "main loop"RTRSelectNotifier::run();return 0;

}else

cout<<"ReplyServer error: "<<_replyServer.errorText()<<endl;}else{

cout<<"TcpSocketIdentifier error: ";cout<<_serverSocketId.errorText()<<endl;

}}else

cout<<"Usage: "<<argv[0]<<" service_name"<<endl;

return -1;}

4.7.7 Example — A Simple Application Using a TCP Client SessionThis section provides the text of an application that uses the RTRTcpClientSession class and the Request class from section 4.7.3. This text is also found in the file request.C.

// The main text of an application that uses a Request class. This // program instantiates an instance of RTRTcpClientSession using the // host name and server name provided on the program command line.

main(int argc, char **argv){ if (argc == 3) { RTRString _sessionName("tcpClientSession"); // Name of the session. RTRString _hostName(argv[1]); RTRString _serviceName(argv[2]);

// Create a tcp socket identifier that identifies the // host id and port number of the peer session that

SFC Developer’s Guide 223

Page 238: sfc

4.7 SFC MODELS

// this Tcp Client Session will communicate with. RTRTcpSocketIdentifierImpl _socketId(_hostName, _serviceName);

if (_socketId.isValid()){

// Create the client of the Tcp Client Session.Request *_requestor = new Request();

RTRTcpClientSession *_session;

RTRTcpClientSession::setDefaultWriteMessageSize(300);RTRTcpClientSession::setDefaultNumberWriteMessages(2);RTRTcpClientSession::setDefaultReadBias(3);

// Create a Tcp Client Session that will attempt to establish // communications with a peer Tcp Server Session specified by // _socketId. The client for this message session, _requestor, // will be notified whenever a message is received from its // peer and whenever the state of the session changes._session = new RTRTcpClientSession( _socketId,

*_requestor);if (_session->connected()){

cout<<"Client: Activating requestor..."<<endl;

// This client will also send messages and therefore // needs access to the message session.

_requestor->setSession(_session);

// Start sending request messages._requestor->start();

// Enable the "main loop"RTRSelectNotifier::run();;return 0;

}else{

cout<<"Session error: "<<_session->text()<<endl;

SFC Developer’s Guide 224

Page 239: sfc

4.7 SFC MODELS

// Clean up delete _session;_session = 0;

}}else

{ cout<<"Socket identifier invalid : "<<_socketId.errorText()<<endl; } } else cout<<"Usage: "<<argv[0]<<" host_name service_name"<<endl;

return -1;}

SFC Developer’s Guide 225

Page 240: sfc

4.8 SFC MODELS

4.8 Support

This cluster describes the SFC "infrastructure" models:

• connection classes (section 4.8.1)

• service pool factory classes (section 4.8.2)

• the event loop abstraction and implementation (section 4.8.3)

• configuration classes (section 4.8.5)

• event logging classes (section 4.8.6)

• command line classes (section 4.8.7)

• international character support (section 4.8.8.7)

4.8.1 Connection

4.8.1.1 OverviewThe connection classes provide a way to control and monitor the connection between SFC and a market data infrastructure. The abstract base class for connections is RTRMDConnection. Market data connections are created internally by most market data services and by service pool factories (section 4.8.2), so SFC applications typically do not have to use them directly. Connection classes can be useful in the following circumstances.

• The application needs to monitor the status of the connection. A class which inherits from RTRMDConnectionClient can register to receive status and information events from a connection.

• Multiple services need to share a connection. The connection can be created and passed into the constructors of the services. Most of the time, it’s easier to use a service pool factory. However, this approach is especially useful for sharing a RTRTIBConnection between consuming and publishing services, since publishing services are not maintained by service pool factories.

• The application needs fine-tuned control over connection parameters. Some parameters can be controlled through parameters on services or service pool factories. Most parameters can also be controlled through configuration. The connection classes can be used to directly set the mount parameters without using a configuration file. All mount parameters must be set before calling connect() which puts the connection in an initalized state.

SFC Developer’s Guide 226

Page 241: sfc

4.8 SFC MODELS

4.8.1.2 ImplementationSFC includes three implementations of RTRMDConnection: RTRSSLConnection, RTRSSLConnectionServer, and RTRTIBConnection. Each implementation class has unique mount parameters and connection values that are type specific. See the SFC Reference Manual for details on these parameters.

When entitlements are enabled, RTRTIBConnection represents both the RVD connection and the connection to the DACS daemon. An entitled TIB connection is only connected when both connections have been established. RTRTIBConnection can connect to a Rendezvous network using either the SASS2 protocol or the SASS3 protocol. By default, it uses RTRTIBConnection::SASS3. It can be changed on a per connection basis using:

RTRTIBConnection::protocol(RTRTIBConnection::Protocol p)

When entitlements are disabled, a RTRSSLConnectionServer is connected as long as the well-known listen port could be opened. Note that no other application needs to actually be "connected."

When entitlements are enabled, RTRSSLConnectionServer is only connected when both the well-known port is open and the connection to the DACS daemon has been established. If the user login to the DACS daemon fails, the well-known port will be closed.

For information on the specific mount parameters for each implementation, see the SFC Reference Manual and section 5.5.10 in this manual.

4.8.1.3 ExamplesThe following code shows how to create a TIB connection. Most of the connection parameters can be set in the constructor.

RTRObjectId _instanceId("appId");RTRTIBConnection _connection(_instanceId, "TIBConnection",

service, network, daemon);_connection.connect();

Additional connection parameters are needed when using a TMF in an RMDS infrastructure (Appendix E).

This second example shows how to create a TIB connection with a TMF session. All of the TMF session parameters can be set through the setUpdateSession() method.

RTRObjectId _instanceId("appId");RTRTIBConnection _connection(_instanceId, "TIBConnection",

SFC Developer’s Guide 227

Page 242: sfc

4.8 SFC MODELS

service, network, daemon);_connection.setUpdateSession(updateService, updateNetwork, updateDaemon);_connection.connect();

This third example shows how to create an SSL connection. Since SSL has more connection parameters, they cannot be set on the constructor. Instead, they are set individually before calling connect().

RTRObjectId _instanceId("appId");RTRSSLConnection _connection(_instanceId, "sslDispatcher");_connection.userName("jsmith");_connection.serverList("sinkdistmach1 sinkdistmach2");_connection.port(8102);

// all mount parameters must be set before calling connect_connection.connect();

4.8.2 Service Pool Factory

4.8.2.1 OverviewService pool factories make it easier to create and manage the life-cycle of market data connections, FID databases, services, and service pools. A service pool factory is responsible for creating and destroying its connection, services, and pools. The abstract base class for service pool factories is RTRMDServicePoolFactory.

The RTRMDServicePoolFactory is responsible for specifying the service pool factory interface and generic configuration. From this service pool factory, a program can retrieve RTRecord, Page, RTPage, and TimeSeries service pools. The pools are created with lazy initialization. Since a factory has a single connection, all of the pools uses that same, shared connection.The service pool factory classes follow the Abstract Factory pattern [6] . RTRMDServicePoolFactory has two infrastructure-specific subclasses: RTRSSLServicePoolFactory and RTRTIBServicePoolFactory.

The Composite pattern [6] is used by RTRCompositeServicePoolFactory to provide a way of merging service pools from multiple factories into a set of pools. For example, this feature can be used to automatically create a single RTRRTRecordServicePool that contains services from two SSL and one TIB connection. If there is a service name conflict, services are included in the composite pool on a first-come, first serve basis. Conflicts are also logged.

SFC Developer’s Guide 228

Page 243: sfc

4.8 SFC MODELS

4.8.2.2 ImplementationWhile the abstract class for service pool factories has an infrastructure-agnostic interface, some implementation details should be considered.

• On Triarch, services can be dynamically discovered. To disable this feature, enableDynamic*ServicePool configuration variables were added to RTRMDServicePoolFactory to turn this functionality on and off. By default these values are enabled by RTRSSLServicePoolFactory. However with RTIC (SASS2), all services names must be known by the application. So, these values are disabled and ignored by RTRTIBServicePoolFactory.

• Since services cannot be dynamically determined on RTIC (SASS2), they must be specified with configuration or by calling one of the install*Service(const char*) methods. It may be useful to note that theses services are generic, so they can be add services when dynamic services are disabled on Triarch, or they can be used to ensure certain services are listed first in the pool.

• Page stream services are not available on RTIC (SASS2), so rtPageServicePool() returns 0. In general, the return values of pageServicePool(), timeSeriesServicePool(), and rtRecordServicePool() should always be checked if they are null before being used.

• RTRSSLServicePoolFactory and RTRTIBServicePoolFactory each have some additional configuration variables that can be used to customize their connections.

4.8.2.3 ExamplesThe following example code shows how SSL and TIB service pool factories are created and how a composite factory can be used:

RTRObjectId instanceId("appId");

RTRCompositeServicePoolFactory factory( instanceId, "compositePool");

RTRSSLServicePoolFactory sslFactory( instanceId, "pool");factory.addFactory(sslFactory);

RTRTIBServicePoolFactory tibFactory( _instanceId, "pool");factory.addFactory(tibFactory);

// At this point, all of the service pools don’t exist because they are// created with lazy initialization.

SFC Developer’s Guide 229

Page 244: sfc

4.8 SFC MODELS

tibFactory.installRTRecordService("RSF");// A RTRTIBRTRecordService named RSF is created and added to the new // RTRRTRecordServicePools in _tibFactory and _factory.

RTRRTRecordServicePool *pool = factory.rtRecordServicePool();// The RTRRTRecordServicePool is created in the ssl factory.// _pool already contains RSF. SSL services will be added when// they are asynchronously discovered from Triarch.

More ExamplesThe connection and factory models and the single service constructors were designed for both flexibility and ease of use. While on the surface, the wide variety of these examples may seem complicated, they are shown here as a demonstration of SFC’s initantiation flexibiliy. Please keep in mind, for most purposes, a factory or single service constructor will work with minimal setup.

These examples may use the following includes and declarations:

#include "rtr/objid.h" // RTRObjectId #include "rtr/tibrtsvc.h"// RTRTIBRTRecordService #include "rtr/sslrtrs.h" // RTRSSLRTRecordService #include "rtr/tconnect.h"// RTRTIBConnection #include "rtr/sconnect.h"// RTRSSLConnection #include "rtr/sslconns.h"// RTRSSLConnectionServer#include "rtr/tibsplf.h" // RTRTIBServicePoolFactory #include "rtr/sslsplf.h" // RTRSSLServicePoolFactory#include "rtr/fldtossl.h"// RTRRTFieldToSSLRecordService#include "rtr/fldtotib.h"// RTRRTFieldToTIBRecordServiceRTRObjectId appId("appId");

1. Single SASS3 service

RTRTIBRTRecordService service(appId, "RSF");

2. Single SASS3 service with mount parameters

RTRTIBRTRecordService service(appId, "RSF", "7501", "tcp:rvdhost:7500");

3. Single SASS2 service

RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2; RTRTIBRTRecordService service(appId, "RSF");

4. Single SASS2 service with mount parameters

SFC Developer’s Guide 230

Page 245: sfc

4.8 SFC MODELS

RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2;RTRTIBRTRecordService service(appId, "RSF", "7501", "", "tcp:rvdhost:7500");

5. Single SSL service, using sslapi.cnf or ipcroute for mount location

RTRSSLRTRecordService service(appId, "IDN_SELECTFEED", "");

6. Single SSL service, customizing mount location

RTRSSLRTRecordService service(appId, "IDN_SELECTFEED", "sinkDistHost1sinkDistHost2");

7. Customizing connection for single SASS3 service

RTRTIBConnection connection(appId, "tibconnection", "7501");connection.userName("mylogin"); connection.connect();RTRTIBRTRecordService service(appId, "RSF", connection);

8. Customizing connection for single SASS3, TMF service

RTRTIBConnection connection(appId, "tibconnection", "7501");connection.setUpdateSession("7502", "", "");connection.connect();RTRTIBRTRecordService service(appId, "RSF", connection);

9. Customizing connection for single SASS2 service

RTRTIBConnection connection(appId, "tibconnection", "7501");connection.enableEntitlements(RTRFALSE);connection.protocol(RTRTIBConnection::SASS2); connection.connect(); RTRTIBRTRecordService service(appId, "RSF", connection);

10.Customizing connection for single SSL service

RTRSSLConnection connection(appId, "sslconnection");connection.userName("mylogin");connection.protocol(RTRTIBConnection::SASS2); connection.connect();

11.Two SASS3 services from factory

RTRTIBServicePoolFactory factory(appId, "factory");// the next two lines are not needed if the config file includes// *appId.factory : RSF, RDF

SFC Developer’s Guide 231

Page 246: sfc

4.8 SFC MODELS

factory.installRTRecordService("RSF");factory.installRTRecordService("RDF");RTRRTRecordServicePool *pool = factory.rtRecordServicePool();RTRRTRecordService *s1 = pool->service("RSF");RTRRTRecordService *s2 = pool->service("RDF");

12.Two SASS2 services from factory

// The next two lines could be replaced with// RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2;

RTRTIBConnection connection(appId, "tibconnection", "7501");connection.protocol(RTRTIBConnection::SASS2);RTRTIBServicePoolFactory factory(appId, "factory", connection);

// the next two lines are not needed if the config file includes// *appId.factory : RSF, IDN_RDF

factory.installRTRecordService("RSF");factory.installRTRecordService("IDN_RDF");RTRRTRecordServicePool *pool = factory.rtRecordServicePool();RTRRTRecordService *s1 = pool->service("RSF");RTRRTRecordService *s2 = pool->service("IDN_RDF");

13.Two SSL services from factory

RTRSSLServicePoolFactory factory(appId, "factory");// the next two lines are not needed if the config file includes// *appId.factory : IDN_SELECTFEED, IDN_RDF

factory.installRTRecordService("RSF");factory.installRTRecordService("IDN_RDF");RTRRTRecordServicePool *pool = factory.rtRecordServicePool();RTRRTRecordService *s1 = pool->service("IDN_SELECTFEED");RTRRTRecordService *s2 = pool->service("IDN_RDF");

OR

// AppRecSrvcPoolClient client, subclass of RTRRTRecordServicePoolClientRTRSSLServicePoolFactory factory(appId, "factory");RTRRTRecordServicePool *pool = factory.rtRecordServicePool();pool->addClient(client);

// Release control to SFC’s event loop. Wait for service table// to be downloaded asynchronously from sink distributor.

void AppRecSrvcPoolClient::processRTRecordServiceAdd(RTRRTRecordServicePool & pool, RTRRTRecordService & srvc)

SFC Developer’s Guide 232

Page 247: sfc

4.8 SFC MODELS

{if (srvc.name() == "IDN_SELECTFEED")

s1 = &srvc;else if (srvc.name() == "IDN_RDF");

s2 = &srvc;}

14.Two SASS3 services with two connections

RTRTIBRTRecordService s1(appId, "RSF");RTRTIBRTRecordService s2(appId, "RDF");

15.Two SASS2 services with separate connections

RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2; RTRTIBRTRecordService s1(appId, "RSF");RTRTIBRTRecordService s2(appId, "RDF");

16.Two SSL services with two connections

RTRSSLRTRecordService s1(appId, "IDN_SELECTFEED", "");RTRSSLRTRecordService s2(appId, "IDN_RDF", "");

17.Two SASS3 service with one connection

RTRTIBRTRecordService s1(appId, "RSF");RTRTIBConnection &connection = s1.connection();RTRTIBRTRecordService s2(appId, "RDF", connection);

18.Two SASS2 service with one connection

RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2; RTRTIBRTRecordService s1(appId, "RSF");RTRTIBConnection &connection = s1.connection();RTRTIBRTRecordService s2(appId, "RDF", connection);

19.Two SSL services with one connection

RTRSSLRTRecordService s1(appId, "IDN_SELECTFEED", "");RTRSSLConnection &connection = s1.connection();RTRSSLRTRecordService service(appId, "IDN_RDF", connection);

20.Single SSL pub service

RTRRTFieldToSSLRecordService s1(appId, "MY_SRVC1")

SFC Developer’s Guide 233

Page 248: sfc

4.8 SFC MODELS

21.Two SSL pub services with separate connections

// triarch_sink and triarch_sink2 must be configured to be different // ports, or else the second connection server will not be able to // open the port to listen for incoming connections.RTRSSLConnectionServer sslconnsvr1(appId, "connection1", "triarch_sink");RTRRTFieldToSSLRecordService s1(appId, "MY_SRVC1", sslconnsvr1);RTRSSLConnectionServer sslconnsvr2(appId, "connection2", "triarch_sink2");RTRRTFieldToSSLRecordService s2(appId, "MY_SRVC2", sslconnsvr2);

22.Two SSL pub services with one connection

RTRRTFieldToSSLRecordService s1(appId, "MY_SRVC1");RTRSSLConnectionServer & connectionServer = s1.connectionServer();RTRRTFieldToSSLRecordService s2(appId, "MY_SRVC2", connectionServer);RTRRTFieldToTIBRecordService pubsrvc(appId, "MY_SRVC", connection);

23.SASS3 sub and pub services with same connection

RTRTIBRTRecordService subsrvc(appId, "RSF");RTRTIBConnection & connection = subsrvc.connection();RTRRTFieldToTIBRecordService pubsrvc(appId, "MY_SRVC", connection);

24.SASS2 sub and pub services with same connection

RTRTIBConnection::DefaultSassVersion = RTRTIBConnection::SASS2; RTRTIBRTRecordService subsrvc(appId, "RSF");RTRTIBConnection & connection = subsrvc.connection();

25.Changing connection parameters for a service pool factory

RTRSSLConnection connection(appId, "connection");connection.userName("myusername");connnection.connect();RTRSSLServicePoolFactory factory (appId, "pool", connection);

26.Multiple infrastructure services from single pool

RTRCompositeServicePoolFactory factory( appId, "compositePool");RTRSSLServicePoolFactory sslFactory( appId, "pool");factory.addFactory(sslFactory);RTRTIBServicePoolFactory tibFactory( appId, "pool");factory.addFactory(tibFactory);tibFactory.installRTRecordService("RSF");RTRRTRecordServicePool *pool = factory.rtRecordServicePool();

SFC Developer’s Guide 234

Page 249: sfc

4.8 SFC MODELS

4.8.3 Event LoopThis model defines the abstract and implementation classes for an event dispatching loop. The SFC abstraction for an event loop is represented by the class RTREventNotifier. The purpose of the notifier is to allow application components to use system resources (I/O, timers) in a cooperative way, without being dependent on any particular implementation of a "main loop". Application designers may choose the event loop implementation which best suits their requirements.

There can be only one event loop (RTREventNotifier) in an application. SFC classes access the notifier implementation via a static data element of type RTREventNotifierInit. This static data element is made available to an application component by including the file rtr/rtrnotif.h. The actual implementation used depends on how the application is constructed (what main() looks like) and how the application is linked. Usually, the main() is "notifier specific". This is because, in most applications, main() must invoke the instructions which cause the application to enter the loop and such instructions couple the main with a particular implementation of notifier. For example, the applications described in this manual use the RTRSelectNotifier. Example source files that define main() include the header file rtr/selectni.h and invoke RTRSelectNotifier::run() to enable the control loop.

In a Windows NT environment, several options are available for the event loop:

• Use the RTRSelectNotifier, as described above. However, due to a bug in the operating system, NT’s select() call can only poll 64 file descriptors. This limit applies to incoming and outgoing socket descriptors.

• In a GUI application, use the RTRWindowsNotifier. To use this notifier, simply link libwinml.lib into the executable, or compile the winni.cpp provided into the program. The RTRWindowsNotifier will use Windows’ event dispatching loop automatically, so run() does not need to be called.

• Use the RTRWindowsNotifier explicitly in a console application. Since a window dispatching loop does not exist in a console application, the application must have its own dispatch loop:

#include <windows.h>int main(){

// ...application setupMSG msg;void *notif = RTREventNotifierInit::notifier;static RTRWindowsNotifier * wnotif =

((RTRWindowsNotifier*)notif->instance()

SFC Developer’s Guide 235

Page 250: sfc

4.8 SFC MODELS

while (GetMessage(&msg, 0, 0, 0) && wnotif->enabled() )DispatchMessage(&msg);

// ...cleanup}

• The RTRWindowsNotifier can be used when MFC is used. If MFC is used and the event loop is to be compiled into a DLL, use libmfcml.lib.

4.8.3.1 I/O EventsThe base class for components which need to be informed of I/O events is RTRIOClient. This class provides event handling methods for each of three types of I/O event available on file descriptors.

• A Read event indicates to interested clients that there is data to be read on a given file descriptor.

• A Write event indicates that a given file descriptor is now available for output.

• An Exception event indicates that there is an exception condition on a given file descriptor.

Descendants of RTRIOClient may register for each type of I/O event with an instance RTREventNotifier. Only one client may register for a particular event on any one file descriptor.

Since RTRIOClient does not detect the loss of I/O events, the application should handle it in the application level. For example, if the application implements RTRIOClient for a READ event on a given file descriptor, the application should check its status continuously and call the method below in processIORead() if the I/O event is closed or lost.

RTREventNotifierInit::notifier->dropReadClient(fd)

This will protect the application from sending processIORead events in an infinite loop.

4.8.3.2 Timer EventsTimer events allow application components to give up control of the thread of execution in the program until a specified amount of time has elapsed. RTRTimerCmd is the base class that allows application components to initiate and receive timer events. This base class provides methods used to set the timer interval (offset) and activate or deactivate the timer. Descendants of RTRTimerCmd provide an implementation of the processTimerEvent() method. This method is called when the timer expires.

SFC Developer’s Guide 236

Page 251: sfc

4.8 SFC MODELS

Timers have minimal resolutions set by the operating systems. The default minimal resolution is set at 10ms. Some operating systems round off timers, so setting a timer for 23 ms may actually set a timer of 30ms.

Applications can set a repeating timer by calling activate() inside processTimerEvent(). This sets a timer event to execute in a user determined amount of time in the future. If the timer set in the processTimerEvent() is a null timer, this timer will be automatically set to the minimal resolution time (10ms). This is also true for timers set inside of a windows event callback.

4.8.3.3 Custom Event LoopOne may implement a custom event loop to use in place of SFC’s event loop; however, this implementation of event loop must consider all of these issues:

• Timers can be set from many parts of SFC, including, but not limited to, request retry and timeout, reconnection delays, cleanup.

• Null timers must be handled correctly and effeciently. Null timers are often introduced during cleanup to let the call stack safely unwind before calling the destructor. Not handling null timers efficiently could result in extremely slow recovery.

• Multiple callbacks from application to the notifier must be handled correctly.

• Callbacks within callbacks must be handled correctly

• I/O and Timer events must be handled correctly.

See section 4.8.4 for more information on timers.

4.8.4 Example — I/O and TimingThis section presents an example class that utilizes both the I/O and timing events. IOTimerClient is a descendant of both RTRIOClient and RTRTimerCmd. The purpose of this class is to read data from the standard input device. That data is interpreted as an interval, in seconds, which is used as the interval to be timed. When new data is received, the current timer event, if any, is canceled and the timer event is re-activated with the new interval. If the timer expires, a message is printed to the standard output device.

NOTE: For performance reasons, the SFC notifier implementations only check the current time once through a notifier loop. This means that timers set at the beginning and end of a callback will be set to fire at the same system time.

SFC Developer’s Guide 237

Page 252: sfc

4.8 SFC MODELS

Each of the examples which follows uses a different version of the notifier and instantiates one instance of IOTimerClient.

4.8.4.1 Declaration of IOTimerClient (iotimerclient.h)//// This file contains the declaration for IOTimerClient, a simple class // which uses both I/O and timing events. It reads the standard input for // line of data. The data is converted to an integer value and is used to // set a timer. When the timer expires, the message "HELLO WORLD, AGAIN" is // printed to the standard output. Existing timers are canceled prior to// installation of new timers. A timer value of 0 causes this class to // stop waiting for input.//

#include "rtr/timercmd.h"#include "rtr/ioclient.h"

class IOTimerClient :public RTRTimerCmd,public RTRIOClient

{public:// Constructor

IOTimerClient(char *);

// Destructor~IOTimerClient();

// Event processing - from RTRIOClientvoid processIORead(int fd);

// Event processing - from RTRTimerCmdvoid processTimerEvent();

protected:// Implementation attributes

int fd;};

SFC Developer’s Guide 238

Page 253: sfc

4.8 SFC MODELS

4.8.4.2 Definition of IOTimerClient (iotimerclient.C)//// This file contains the implementation of IOTimerClient//

#ifndefIBMRS#include <sys/unistd.h>#endif#include <unistd.h>#include <fcntl.h>#include <iostream.h>#include <stdlib.h>

#include "rtr/rtrnotif.h"#include "iotimerclient.h"

IOTimerClient::IOTimerClient(char *fnm) {

fd = open(fnm, O_RDWR);RTREventNotifierInit::notifier->addReadClient(*this, fd);cout << "Enter time:" << flush;

}

IOTimerClient::~IOTimerClient(){

RTREventNotifierInit::notifier->dropReadClient(fd);}

void IOTimerClient::processIORead(int){

char buf[100];int len = read(fd, buf, 10);buf[len] = ‘\0’;

int s = atoi(buf);if (active()){

cout << "Canceling current event" << endl;deactivate();

SFC Developer’s Guide 239

Page 254: sfc

4.8 SFC MODELS

}if ( s > 0 ){

cout << "Adding event for " << s << " seconds" << endl;setTimerOffset(s, 0);activate();

}else{

if ( active() )deactivate();

RTREventNotifierInit::notifier->dropReadClient(fd);}

}

void IOTimerClient::processTimerEvent(){

cout << "HELLO WORLD, AGAIN" << endl << "Enter time:" << flush;}

4.8.4.3 Example Application - Select based (selecttest.C)//// This application creates a single instance of a IOTimerClient.// It uses the RTRSelectNotifier as the main loop implementation.//

#include "rtr/selectni.h"// Defines RTRSelectNotifier

#include "iotimerclient.h"

void main(){

IOTimerClient client("/dev/tty");RTRSelectNotifier::run();

}

SFC Developer’s Guide 240

Page 255: sfc

4.8 SFC MODELS

4.8.4.4 Example Application - Xt based (xttest.C)RTRXtNotifier has a static data member of type XtAppContext called appContext. This must be declared and initialized by the application. The main loop is started in the usual manner by calling XtAppMainLoop().

//// This application demonstrates the use of the RTRXtNotifier. It// creates a single instance of a IOTimerClient and creates a simple// X application.//

#include <stdio.h>

#include "rtr/xtenimp.h"#include "iotimerclient.h"

#define XTFUNCPROTO 1

#include <X11/Intrinsic.h> /* Intrinsics Definitions */#include <X11/IntrinsicP.h> /* Intrinsics Definitions */#include <X11/StringDefs.h> /* Standard Name-String definitions */#include <X11/Xaw/Command.h> /* Athena Command Widget */

#define MAXLEN 50

static void IncrementCount(Widget w, XtPointer clientData, XtPointer CallData){

char string[MAXLEN];static int count;Arg args[3];int i;

sprintf(string, "click me: %d", ++count);

i = 0;XtSetArg(args[i], XtNlabel, string); i++;XtSetValues(w, args, i);

}

XtAppContext RTRXtNotifier::appContext = 0;

SFC Developer’s Guide 241

Page 256: sfc

4.8 SFC MODELS

int main(int argc, char **argv){

XtAppContext app_context;Widget topLevel, hello;Arg arg;char *p;

topLevel = XtAppInitialize(&app_context,"XClickcount", /* Application class */NULL, /* Resource Mgr. options */0, /* number of RM options */

#if (XtSpecificationRelease < 5)(Cardinal *)&argc, /* number of args */

#else&argc, /* number of args */

#endifargv, /* command line */NULL,&arg,0);

hello = XtCreateManagedWidget("click me", /* arbitrary widget name */commandWidgetClass, /* widget class from Label.h */topLevel, /* parent widget*/NULL, /* argument list */0 /* arg list size */);

XtAddCallback( hello, XtNcallback,(XtCallbackProc) IncrementCount,(XtPointer) NULL );

XtRealizeWidget(topLevel);XtResizeWidget(topLevel, 120, 80, 10);

RTRXtNotifier::appContext = app_context;

SFC Developer’s Guide 242

Page 257: sfc

4.8 SFC MODELS

IOTimerClient client("/dev/tty");

XtAppMainLoop(app_context);}

4.8.4.5 Example Application - XView based (xvtest.C)RTRXViewNotifier has a static data member of type Frame called baseFrame. This must be declared and initialized by the application. The main loop is started in the usual manner by calling xv_main_loop().

#include "rtr/xvenimp.h"

#include "iotimerclient.h"

#define __sys_unistd_h#define __SIGNAL_H

extern "C" {#include <xview/xview.h>#include <xview/panel.h>#include <xview/openmenu.h>}

intselected(Panel_item item, Event *){

printf("%s selected\n", xv_get(item, PANEL_LABEL_STRING));return XV_OK;

}

voidmenu_proc(Menu, Menu_item){}

Frame RTRXViewNotifier::baseFrame = 0;

int main(int argc, char **argv){

SFC Developer’s Guide 243

Page 258: sfc

4.8 SFC MODELS

Panel panel;Menu menu;Frame base_frame;

xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);base_frame = (Frame)xv_create(NULL, FRAME, NULL);panel = (Panel)xv_create(base_frame, PANEL, NULL);

menu = (Menu) xv_create(NULL, MENU,MENU_NOTIFY_PROC, menu_proc,MENU_STRING, "YES", "No", "Quit", NULL,NULL);

(void) xv_create(panel, PANEL_BUTTON,PANEL_LABEL_STRING, "Click me",PANEL_NOTIFY_PROC, selected,PANEL_ITEM_MENU, menu,NULL);

window_fit(panel);window_fit(base_frame);

RTRXViewNotifier::baseFrame = base_frame;IOTimerClient client("/dev/tty");

xv_main_loop(base_frame);}

4.8.5 Configuration

4.8.5.1 OverviewIn general, configuring software components is a matter of assigning values to named variables. Reusable software, and in particular, object-oriented software, makes the problem more complicated. The primary concern is avoiding name conflicts. Variable names must be chosen without knowledge of the entire application. Another aspect of the problem is the complex composition of the end product, and the fact that the same component may appear in many different applications. The SFC provides a model to address these problems.

The SFC configuration model is derived from the following analysis:

SFC Developer’s Guide 244

Page 259: sfc

4.8 SFC MODELS

• An application consists of a number of components.

• Each component is an instance of some type or class.

• The class of a component determines the set of variables whose values may be configured.

• Each variable has a name.

The model provides the means to assign values to variables by class identity and by instance identity. Configuration by instance identity requires that the run-time composition of the application be known. Configuration by class identity is more generalized and therefore easier, but does not provide as much control; it is not as precise.

The class RTRConfigDb is the abstract base class for a database of configuration variables. Variables are retrieved from the database on the basis of three pieces of information: a class identifier, an instance identifier, and a variable name. Both identifiers are of type RTRObjectId, which essentially is an encapsulation of a compound string. Configuration variables are of type RTRConfigVariable, which provides convenient mechanisms for interpreting the value in different ways. RTRConfigDb allows the requesting component to specify a default value which will be used when no explicitly configured value is available. The use of default values is optional. It is a design issue. Variables for which there is no value and no default will be in an error state.

Class identifiers are assigned to components by the class designer. They are compiled into the software. All instances of a particular type (class) will have the same class identifier. Instance identifiers are generated at run-time. The manner in which instance identifiers are assigned is an application design issue. No two components should have the same instance identifier. The next two sections provide some guidelines on how to go about assigning class and instance identifiers.

4.8.5.2 Assigning Class IdentifiersClass identifiers are arbitrary values which should usually correspond fairly closely to the C++ class types of the component in question. Why reinvent the wheel? Most of the time, this is a fairly straightforward problem. Difficulties arise when using inheritance, especially when the class in question has multiple ancestors which need access to configuration data. A certain amount of foresight is required by the base class designers.

A simple example:

The TickerMonitor class from the ticker example program has a static data member of type RTRObjectId. It is called _classId and is used as a class identifier in configuration queries. The value assigned to it (in tickmon.C) is "TickerMonitor". This technique works well enough for this

SFC Developer’s Guide 245

Page 260: sfc

4.8 SFC MODELS

class, but is not very extensible. Suppose TickerMonitor had a descendant called Foo, also needing configuration. The class identifier should be "TIckerMonitor.Foo". Foo can declare its own instance of RTRObjectId and initialize it appropriately. The problem is that when the method Foo::processRTRecordServiceAdd is invoked, it will use the class identifier from the ancestor (TickerMonitor) not the identifier of the descendant (TickerMonitor.Foo).

Solving this problem requires a change in design of the TickerMonitor class. The class identifier should not be hard-coded. One solution is to provide a constructor argument which has a default value and use that to initialize a class identifier object. The new constructor for TickerMonitor would be declared as follows:

TickerMonitor(const RTRObjectId&, const char *,RTRRTRecordServicePool&,const char* classId = "TickerMonitor");

....protected:

RTRObjectId _classId;

Then the initialization list needs an entry:

_classId(classId)

The descendant class Foo then invokes the constructor with the fourth argument set to "TickerMonitor.Foo".

4.8.5.3 Assigning Instance IdentifiersThe purpose of an instance identifier is to uniquely identify a component. Why not use the address in memory of that component, or perhaps use a counter to generate numeric identifiers? The problem with these techniques is that they do not yield intuitive results and they are not predictable, making these techniques impractical from an administrator’s perspective.

A reasonable solution is to create an identifier in the application which is the basis for all the other identifiers. Each component of the application is given that identifier and a unique, meaningful name. The application’s identifier is the context in which that name is unique. Each component can then pass its own identifier into sub-components and assign them unique names, and so-on and so-on. This process is more predictable and yields unique, meaningful names.

SFC Developer’s Guide 246

Page 261: sfc

4.8 SFC MODELS

The examples in this manual use this technique. For example, the ticker application (ticker.C) which creates an instance of TickerMonitor has an application identifier of "ticker". This is passed to the instance of TickerMonitor along with a unique name, in this case "ticker_monitor". The service pool in this application can also be configured; its unique name is "pool". This means that the instance of TickerMonitor has an instance identifier of "ticker.ticker_monitor", and the pool has an instance identifier of "ticker.pool".

This technique works well in most cases but has some flaws. If two of these applications run on the same system and use the same configuration file, there is no way to tell them apart. The application designer may want to ensure uniqueness by providing a command line argument which gives this application its name. Further more, in distributed systems, it may be appropriate to use the hostname as the first level of identification.

4.8.5.4 An Implementation Using X-Window Resource FilesThe SFC provides a file-based implementation of RTRConfigDb called RTRXFileDb which parses files that use the same syntax as X-Window resource specification files. This syntax allows the administrator to use wildcards in the specification of class and instance identifiers, making the configuration task simpler.

4.8.5.5 RTRXFileDb ExampleThis sample program shows some simple uses for the configuration database. This example uses the "X" file implementation of the configuration database which uses X library functions to read in configuration variables from a disk file. These examples use meaningless identifiers and pass literal strings instead of creating instances of RTRObjectId. The use of strings is acceptable because RTRObjectId provides a constructor which accepts a string.

This small program creates an instance of RTRXFileDb, giving it the path of a configuration file ./config_file. Configuration variables are then obtained from the configuration database for four different cases. The variable() function is used to obtain an RTRConfigVariable reference. The parameters on the variable() function call are:

• the Class Identifier which identifiers the type of the component that is to match an entry in the configuration database

• the Instance Identifier which identifies a particular instance of a component

• the name of the variable

SFC Developer’s Guide 247

Page 262: sfc

4.8 SFC MODELS

• a default value that is returned if a variable cannot be found in the database that matches either of the identifiers

Note that the query for "var4" does not provide a default value. The returned variable must therefore be checked for an error.

#include "rtr/rtxfdb.h"

int main(){

RTRXFileDb configDb("./config_file");if (!configDb.error()){

// Example of full expanded nameRTRConfigVariable var1 = configDb.variable(

"RequestQueue","machine2.sink_distributor.request_queue","queueSize","500");

// Example of wildcarded idRTRConfigVariable var2 = configDb.variable(

"RequestQueue","machine30.sink_distributor.request_queue","queueSize","500");

// Example of using default valueRTRConfigVariable var3 = configDb.variable(

"SessionManager","mySessionClient.session_manager","maxSessions","30");

// Example of no default and no valueRTRConfigVariable var4 = configDb.variable(

"RrmpManager","machine22.V301.sink_distributor.rrmp_manager","rrmpAddress");

cout<<"Value of variable ‘var1’ is ‘";cout<<var1.value().to_c()<<"‘"<<endl;

cout<<"Value of variable ‘var2’ is ‘";

SFC Developer’s Guide 248

Page 263: sfc

4.8 SFC MODELS

cout<<var2.value().to_c()<<"‘"<<endl;

cout<<"Value of variable ‘var3’ is ‘";cout<<var3.value().to_c()<<"‘"<<endl;

if (var4.error()){

cerr << "Error: No value for ‘var4’" << endl;}

}else

cout<<"Config db error: "<<configDb.errorText()<<endl;}

Given the following configuration file entries in file./config_file:

machine2.sink_distributor.request_queue.queueSize : 1000*queueSize : 200

the program output is:

Value of variable ‘var1’ is ‘1000’Value of variable ‘var2’ is ‘200’Value of variable ‘var3’ is ‘30’Error: No value for ‘var4’

The value of var1 is 1000 because it matches.

Configuration variable var3 shows how the default value is used if a value cannot be found in the configuration database.

Configuration variable var4 is returned with error() set to True because no value is found in the configuration database and no default value was provided.

4.8.5.6 An Implementation Using the Microsoft Windows NT RegistryOn the Microsoft® Windows NT™ operating system, the registry stores all system, application, and user configuration information. A user or administrator usually does not access the registry directly, although they can using the Registry Editor (regedt32.exe). However, improper use of this tool can damage the system configuration settings and prevent the operating system from starting or running properly. Therefore, each application should provide a user interface to view or edit important configuration settings.

SFC Developer’s Guide 249

Page 264: sfc

4.8 SFC MODELS

The SFC provides an implementation of RTRConfigDb called RTRRegistryDb which applications can use to access configuration data in the registry. This implementation provides the RTRConfigDb interface for reading configuration variables from the database and also provides new functions to allow writing values for variables into the configuration database.

The convention for storing software configuration information in the registry is to store configuration values in a tree in the HKEY_LOCAL_MACHINE hive whose key name is of the form:

SOFTWARE\<Vendor>\<Application>\<Version>

The hive and key name may be specified by the application programmer when creating an instance of RTRRegistryDb (or the default values of HKEY_LOCAL_MACHINE and SOFTWARE\Reuters\SFC\CurrentVersion may be used). Within this tree, RTRRegistryDb uses two separate sub-trees with key names Class and Instance to store values for configuration by class and instance, respectively.

When a configuration variable is accessed from the RTRRegistryDb, the specified class and instance object ID names for the variable are converted to key names using backslashes to separate the components of the object ID names. These key names are then used as sub-keys in the registry configuration tree under the Instance and Class sub-trees.

When a variable is retrieved using the variable() function, the Instance sub-tree is searched before the Class sub-tree.

4.8.5.7 RTRRegistryDb ExampleThe following sample program shows the use of the RTRRegistryDb implementation of the configuration database to access values stored in the registry. This small program creates an instance of RTRRegistryDb, specifying that the application data will be stored in the HKEY_LOCAL_MACHINE hive in the tree whose key is SOFTWARE\MyCompany\MyApplication\CurrentVersion. A configuration variable is obtained from the configuration database, a new value for the configuration variable is written to the database, and the variable is then read from the database again to show that the value has changed.

The variable() function is used to obtain an RTRConfigVariable reference. The parameters on the variable() function call are:

• the Class Identifier which identifiers the type of the component that is to match an entry in the configuration database

• the Instance Identifier which identifies a particular instance of a component

SFC Developer’s Guide 250

Page 265: sfc

4.8 SFC MODELS

• the name of the variable

• a default value which is returned if a variable cannot be found in the database that matches either of the identifiers

The putInstanceVariable() function is used to write a new value into the configuration database. The parameters on the putInstanceVariable() function call are:

• the Instance Identifier which identifies a particular instance of a component

• the name of the variable

• the value

#include "rtr/regdb.h"

int main(){

RTRRegistryDb configDb(HKEY_LOCAL_MACHINE, "SOFTWARE\\MyCompany\\MyApplication\\CurrentVersion");if (!configDb.error()){

// Retrieve initial configuration valueRTRConfigVariable var1 = configDb.variable("RequestQueue", "machine2.sink_distributor.request_queue", "queueSize", "500");cout<<"Value of variable ‘var1’ is ‘";cout<<var1.value().to_c()<<"‘"<<endl;

// Put new configuration value into databaseconfigDb.putInstanceVariable(

"machine2.sink_distributor.request_queue", "queueSize", "600");

// Retrieve new configuration valuevar1 = configDb.variable("RequestQueue",

"machine2.sink_distributor.request_queue", "queueSize", "500");cout<<"Value of variable ‘var1’ is ‘";cout<<var1.value().to_c()<<"‘"<<endl;return 0;

}else {

SFC Developer’s Guide 251

Page 266: sfc

4.8 SFC MODELS

cout<<"Config db error: "<<configDb.errorText()<<endl;return 1;

}}

Assuming that the following entry has been created in the registry under the key using the Registry Editor (regedt32.exe):

Key Name:HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MyApplication\CurrentVersion\Instance\machine2\sink_distributor\request_queue

Value Name: queueSizeData Type: REG_SZString: 300

the program output is:

Value of variable ‘var1’ is ‘300’Value of variable ‘var1’ is ‘600’

4.8.5.8 Global Access using RTRConfigThe class RTRConfig provides global access to the current configuration database by means of static member functions. The class is designed to provide simplified and consistent access to the configuration database. RTRConfig provides methods to both set and retrieve the current database. Unless specifically overridden, RTRConfig provides access to an instance of RTRDefaultConfigDb.

NOTE: Unlike file configuration variables, which permit wildcarding, registry configuration variables must be fully specified. For example the configuration variable logger.defaultFileAction.selector can be set in a file as:

*logger*selector: *.debug

In the registry, the full variable name:

\\HKEY_LOCAL_MACHINE\SOFTWARE\MyComp\MyApp\Version\logger\defaultFileAction\selector

must be used.

SFC Developer’s Guide 252

Page 267: sfc

4.8 SFC MODELS

4.8.6 Event Logging

4.8.6.1 OverviewThe event logging cluster addresses the problem of allowing components to generate events without being concerned with application context. For example, it may not be appropriate for a library component to arbitrarily print error messages on the standard error device. Application designers may want those errors to be displayed somewhere else, perhaps in a dialogue box of a windowing system. The event logging cluster provides an extensible event logging mechanism which allows the application designer to decide how events are handled.

The class representing an event is RTRMgmtEvent. Components allocate instances of RTRMgmtEvent and assign it identity, severity and text. The event can then be logged as necessary. The component generating the event does not determine what to do when the event is created. "Actions" are objects which decide how to process events. For example, a file action could write an event to a log file, and a stderr action could write a message on the standard error device.

An application has a single instance of an event router. This centralized component is informed by an event when it needs to be distributed. The router passes the events to all actions that have registered with it.

Actions choose which events they will process with a filter. An action’s filter keeps track of a list of "selection pairs". A selection pair consists of a component name and a severity level. The selection pair list defines the log events that the log action instance will process. To generate a match, the component name of the selection pair must match the identity of the component generating the event. In addition, the severity level of the selection pair must match the severity level of the even

The identity used in generating log events is an arbitrary value set by the designer of the component. The technique used in assigning instance identities in configuration (section 4.8.5.3) is also appropriate for logging events. Severities have one of the following values (listed from lowest severity to highest):

1. Debug

2. Info

3. Notice

4. Warning

5. Error

SFC Developer’s Guide 253

Page 268: sfc

4.8 SFC MODELS

6. Critical

7. Alert

8. Emergency

Through the use of wild-carded selection pairs, actions can be configured to trap log events in a number of ways:

• from a particular component with any type of severity

• from all components with a specific severity (and higher)

• from a particular component and severity pair

• or from all components and all severity types

4.8.6.2 Implementation ClassesThe RTRDefaultLogger class is a utility that instantiates and installs two actions: a file action and a stderr action.

4.8.6.3 Simple ExampleThe following example shows how a typical client application would utilize log events. In the main() of the client application, an instance of RTRDefaultLogger is created. Note that a configuration database is also created and installed. Assuming that the default configuration is used with this default logger, a file log action is automatically created and installed in the event router. This default file log action is set up to log all events that have severity level values from "Info" to "Emergency", inclusive.

#include "rtr/rtxfdb.h"#include "rtr/dfltlog.h"#include "rtr/config.h"

int main(){

RTRXFileDb configDb("./config");RTRConfig::setConfigDb(configDb);

NOTE: Events are logged for all events that are the specified severity level and higher. So, if the Info severity level is specified, all events will be logged except Debug events.

SFC Developer’s Guide 254

Page 269: sfc

4.8 SFC MODELS

RTRDefaultLogger logger("application_name", "logger", "application_name");...}

At this point, the default logger contains a file log action. A component class can use the default logger by including the appropriate header, creating a log event, setting up the log event, and logging a message as follows:

#include "rtr/mgmtevnt.h"

MyClass::doSomething(){

RTRMgmtEvent logEvent;

// Set up the component name, text and severity of// the log event.

logEvent.setComponent("my_component_name");logEvent.setText("This is a critical message to be logged");logEvent.setSeverity(RTRMgmtEvent::Critical);logEvent.log();

}

Given that the configuration file was empty and the default actions were installed, then the following message will appear in the file log.out when method "MyClass::doSomething" is invoked:

<my_component_name: Critical:Fri Mar 25 14:30:30 1994>This is a critical message to be logged<END>

4.8.6.4 Configuration ExamplesThis section shows several different ways to configure the RTRDefaultLogger. There are quite a few configuration variables for the various logging components. The intent of this section is to provide a number of typical configurations. These examples assume that an instance of RTRDefaultLogger exists in the system and that the configuration database it uses is based on the particular configuration file example.

For each of the sample configurations, the instance ID of the default logger will be "logger". The instance ID of its file logger is always "defaultFileAction", and the instance ID of its stderr action is always "defaultStdErrorAction".

SFC Developer’s Guide 255

Page 270: sfc

4.8 SFC MODELS

• Configuration file for a system with a default file action and a default stderr action:

logger.install_stderr_logger: True

By adding this line to the configuration file, the default logger will automatically create and install a default stderr action to go along with the default file log action. Since there are no special configurations for either the file action or the stderr action, some special default characteristics specific to these default log actions are put into place. Specifically, the stderr action and file action will each process log events for any component name and for severity levels "info" to "emergency".

The other default configuration options for default logger’s file action are shown in the following table.

The other default configuration options for both default logger’s stderr action and default logger’s file actions are shown in the following table.

Variable Name Type Default Use

max_bytes integer 10000 The file size which, when exceeded, will cause the file to be saved to a ".old" file

truncate boolean False If True, an existing log file will be truncated

file string log.out The pathname of the log file

flush boolean True Enable/disable the flushing of output immediately after writing

Variable Name Type Default Use

priority integer 100 Sets the priority of this action with respect to other actions

enable boolean True Enables/disables this action

SFC Developer’s Guide 256

Page 271: sfc

4.8 SFC MODELS

• Configuration file for a system with only a default file action and with selector overrides and overrides for log file name and log file size:

*logger.defaultFileAction.file: /var/triarch/my_log_file*logger.defaultFileAction.max_bytes: 100000*logger.defaultFileAction.selector: *.info

This configuration causes the default logger to create and install a file action that uses the file /var/triarch/my_log_file to log event text, sets the maximum number of bytes the file will contain to 100,000, and accepts log events that are from any component and have a severity of "info" or higher.

• Configuration file for a system with only a default stderr action with selector overrides:

*logger.install_file_action: False*logger.install_stderr_action: True*defaultStdErrorAction.selector: *.*

With this configuration, the default logger will automatically create and install a stderr action that will accept log events that are from any component and have any severity. Notice that the "*" notation is used with the instance ID of the stderr action configuration.

• Configuration file for a system with win32 event logging:

*install_system_action: True

This configuration allows you to monitor SFC’s events via Windows event viewer.

4.8.7 Command Line

4.8.7.1 OverviewThe command line classes are utility classes that make it easier to specify and parse command line arguments. They are used extensively in the example programs. All of the command line classes

selector list N/A A comma separated list of instance/severity "dot" pairs which define the matching criteria for events on which this action should act. All events higher than the lowest severity level will be logged.

Variable Name Type Default Use

SFC Developer’s Guide 257

Page 272: sfc

4.8 SFC MODELS

begin with RTRCmdLine-. The base class representing the entire command line is RTRCmdLine. Only one RTRCmdLine will be in an application, so the static variable RTRCmdLine::cmdLine should be used to access it.

All of the command line arguments are descendent from RTRCmdLineArg. They can be strings, numerics, flags, or a list. Each command line variable consists of a tag, a name, a purpose. For some types of variables, a default value must be specified. By default, all variables are required, although variables can be made optional using an extra argument in the constructor. When a variable is specified on the command line, its tag should be pre-pended with ‘-’. See section 4.8.8.6 for more information on the type of command line arguments. See the SFC Reference Manual for more detailed information about the classes that implement the various types for command line arguments.

The RTRCmdLineFlag -? is always included in RTRCmdLine. When the -? command line argument is specified, usage information for the application will be printed. This information is derived from the tags, names, and purposes specified in the command line variable constructors.

4.8.7.2 UsageFive typical steps are taken when using the command line model.

1. Declare the static RTRCmdLine::cmdLine.

2. Declare and specify all of the command line variables.

3. Call RTRCmdLine::cmdLine.resolve(argc, argv).

4. Check the command line proper usage.

5. Access each variable’s typed data.

The following example code shows the steps listed above.

#include <iostream.h>#include "cmdline.h"RTRCmdLine RTRCmdLine::cmdLine; // Create static first//other includes

int main(int argc, char **argv){

RTRCmdLineString string("config", "file_name", "config file");RTRCmdLineFlag flag("d", "enable debug");RTRCmdLineNumeric i("instance", "#", "instance number to use", 1);RTRCmdLineList files("files", "input files");

SFC Developer’s Guide 258

Page 273: sfc

4.8 SFC MODELS

RTRCmdLine::cmdLine.resolve(argc, argv);if ( RTRCmdLine::cmdLine.error() ){

RTRCmdLine::cmdLine.printUsage(cerr, argv[0]);return -1;

}cout << "outFiles are ";const RTRDLinkList<RTRCmdLineData, RTRDLink0>& l = files.values();for (RTRCmdLineData *d = l.first(); d; d = l.next(d) ){

cout << *d; if ( d != l.last() )

cout << ",";}cout << endl;return 0;

}

For this example, the command:

a.out -d -config config.cnf -i 24 file1.txt file2.txt file3.txt

would result in debugging on, config.cnf used as a configuration file, 24 as the instance number, and a file list that includes file1.txt, file2.txt, and file3.txt. Note that the ‘-d’ command line flag does not have a sub-argument. When a command line flag is followed immediately by another command line argument, its sub-argument is optional.

The command line arguments can be in any order. The following command is equivalent to the first.

a.out -config config.cnf -d true file1.txt file2.txt file3.txt -i 24

Note that all extra arguments (file*.txt) are added to the list. The ‘true’ sub-argument for -d is needed to make sure file1.txt is not picked up as the optional sub-argument of -d.

4.8.8 Class Summary

4.8.8.1 Connection• RTRMDConnection - This class is the abstract base class for implementing connections to

market data infrastructure.

SFC Developer’s Guide 259

Page 274: sfc

4.8 SFC MODELS

• RTRMDConnectionClient - This class defines the interface by which a subclass can receive state and informational events about an RTRMDConnection.

• RTRTIBConnection - This class encapsulates a Rendezvous session. RTRTIBConnection is also listens to all advisory messages.

• RTRSSLConnection - This class encapsulates a connection to an upstream SSL component.

• RTRSSLConnectionServer - This class encapsulates a well-known listen port. RTRMDConnectionClients are notified if a DACS connection is lost or established.

4.8.8.2 Service Pool Factory• RTRMDServicePoolFactory - This class defines the abstract interface for service pool factories.

Service pool factories are designed to make it easy to create and manage multiple services over the same connection. So, service pool factories will often create implementation objects automatically as they are needed.

• RTRTIBServicePoolFactory - This implementation of RTRMDServicePoolFactory knows how to connect to an RMDS infrastructure with a TIBCO Rendezvous Distribution Layer and install services. RTRecord, Page, and TimeSeries services pools are all supported. RTPage services are not supported on an RMDS infrastructure with a TIBCO Rendezvous Distribution Layer, so use Page services instead. TIB services cannot be dynamically loaded.

• RTRSSLServicePoolFactory - This implementation of RTRMDServicePoolFactory knows how to connect to an SSL infrastructure and dynamically install services. RTRecord RTPage, Page, and TimeSeries services pools are all supported. By default, all service pools are loaded dynamically.

• RTRCompositeServicePoolFactory - This implementation of RTRMDServicePoolFactory aggregates service pools from multiple service pool factories into a single service pool.

4.8.8.3 Control Loop• RTREventNotifier- This is the abstract base class for the application control loop. Application

components which are descendants of RTRIOClient can register with the notifier to receive I/O events.

• RTRIOClient - This is the abstract base class for application components which wish to register with the control loop in order to receive I/O notification events.

SFC Developer’s Guide 260

Page 275: sfc

4.8 SFC MODELS

• RTRTimerCmd - This is the abstract base class for timers, i.e. commands which will be executed after a specified interval.

• RTRSelectNotifier - This is an implementation of a control loop based on the select() system call.

• RTRXtNotifier - This is an implementation of a control loop which uses the facilities provided by the Xt library.

• RTRXViewNotifier - This is an implementation of a control loop which uses the facilities provided by the XView library.

• RTRWindowsNotifier- This is an implementation of a control loop which uses facilities of the Windows API.

4.8.8.4 Configuration• RTRConfigDb- This is the abstract base class for a database of configuration variables.

Variables are accessed by means of three keys: the class identifier of the requesting component, the instance identifier of the requesting component, and the name of the variable. An additional parameter, the default value to be assigned to the variable, is optional.

• RTRConfigVariable - This descendant of RTRString (via RTRExternalValue) is the basic unit of configuration. A configuration variable accessed from the database will be in an error state if a value has not been explicitly configured and no default is provided. A configuration variable provides various mechanisms by which the underlying data may be converted to some other form.

• RTRObjectId - This class is used for both class and instance identifiers. It is can be thought of as a compound string.

• RTRExternalValue - This descendant of RTRString is an ancestor of RTRConfigVariable and provides the means to transform the underlying data into other representations, e.g., into a list of values based on a given delimiter.

• RTRListOfExternalValue - This class is the result of interpreting a configured value as a delimited list of values.

• RTRConfig - This class provides static functions which allow access to a "global" configuration database. Unless otherwise specified by the application, the database to which access is provided is of type RTRDefaultConfigDb.

SFC Developer’s Guide 261

Page 276: sfc

4.8 SFC MODELS

• RTRXFileDb - This implementation of RTRConfigDb loads an X resources style file of configuration information.

• RTRRegistryDb - This implementation of RTRConfigDb is implemented to use the Windows NT registry database.

• RTRDefaultConfigDb - Variables from this database have default values, where given; otherwise the variable is returned in an error state. This version of the database is typically used in simple programs where configuration is not required and default values are appropriate.

4.8.8.5 Event Logging• RTRMgmtEvent - Application components use this class to generate log events which are then

processed by the centralized event logging mechanism.

• RTRDefaultLogger - This utility class instantiates one default file action and one default stderr action. The matching criteria of the actions are set by default to trap everything except debug messages. This behavior can be changed via configuration variables.

4.8.8.6 Command Line• RTRCmdLine - All command line variables register with an object of this. Then this class will

parse argc and argv, assigning the appropriate values to each command line variable.

• RTRCmdLineString - A simple command line variable that takes a single sub-argument. This variable can be cast to a RTRString.

• RTRCmdLineList - When a RTRCmdLineList is used, all command line arguments not assigned to another command line variable are added to this list. A RTRCmdLine can only have one command line list.

• RTRCmdLineNumeric - This command line variable takes a single sub-argument, which must be a number. The sub-argument is type-checked and can be cast to a long.

• RTRCmdLineFlag - This command line variable can take a single sub-argument, which must be true or false. The variable can be cast to a RTRBOOL. If the flag is specified without a sub-argument, it defaults to RTRTRUE.

SFC Developer’s Guide 262

Page 277: sfc

4.8 SFC MODELS

4.8.8.7 International Characters• RTRUTF8String - This class provides a convenient and efficient way for applications to represent

RMTES, Unicode, and ASCII characters in UTF-8 format.

SFC Developer’s Guide 263

Page 278: sfc

5 SFC IMPLEMENTATION DETAILS

5.1 SSL and TIB Implementations

SFC has two implementations (TIB and SSL) that support two infrastructures (RMDS and Triarch). The RMDS infrastructure consists of the RRDP Market Data Hub along with a TIBCO Rendezvous Distribution Layer. The TIB implementation can be used with the RMDS infrastructure along with a TIBCO Rendezvous Distribution Layer. The SSL implementation can be used with the Triarch infrastructure and with the RRDP Market Data Hub in the RMDS infrastructure. This chapter discusses some of the differences between the infrastructures and provides details for some important implementation and usage issues.

Implementation information about publishing services can also be found in section 4.2.4 and Table 4.9.

These documents may be useful in helping to more fully understand these issues and the context in which they are found:

[1] Reuters SSL 4.1 Architecture Overview - DocID: SSL411SD.990 or Core RMDS Distribution Architecture , June 2001

[2] SSL Infrastructure 4.1.2 Software Installation Manual - DocID: SSL412IP.000 or Reuters Market Data Hub - Source Infrastructure 4.2 Software Installation Manual - DocID: SSL420IP.010

[3] DACS 5.2 Reference Manual - DocID: DACS520UM.040

[4] TIBCO Information Cache Administrator’s Guide -Software Release 10.0.3- System Release 4.1.0, March 2001

[5] TIB Entitlements Administrator’s Guide - Software Release 6.2.9 - System Release 4.0.1, September 2000

[6] CMON/DQA System Administrator’s Guide - Software Release 2.1.0 - System Release 4.0.1, September 2000

[7] TIB/Rendezvous Administrator’s Guide 6.7, June 2001

[8] TIB/Rendezvous Concepts 6.7, June 2001

[9] Selectfeed Plus User Guide or Selectserver User Guide (for information on the construction of Reuters Instrument Codes)

[10] Marketlink Contribution Server Administrator’s Guide - Software Release 3.2.0 - System Re-lease 3.9 , March 1998

SFC Developer’s Guide 264

Page 279: sfc

5 SFC IMPLEMENTATION DETAILS

5.2 Implementation Classes

Typical SFC applications will only need implementation-specific code in one place. This code consists of the initialization process that connects to an infrastructure and creates services. So, most of the SFC implementation classes never need to be used. The following table lists some of the useful implementation classes. It also shows the correlation between TIB and SSL implementation classes. See the SFC Reference Manual for more information on these classes.

Triarch & RMDS MarketData Hub class header Rendezvous & RMDS

Distribution Layer class header

RTRSSLRTRecordService rtr/sslrtrs.h RTRTIBRTRecordService rtr/tibrtsvc.h

RTRSSLPageService rtr/sslpgsrvc.h RTRTIBPageService rtr/tibpgsrvc.h

RTRRTFieldToSSLRecordService rtr/fldtossl.h RTRRTFieldToTIBRecordService rtr/fldtotib.h

RTRSSLServicePoolFactory rtr/sslsplf.h RTRTIBServicePoolFactory rtr/tibsplf.h

RTRSSLConnection (sub)RTRSSLConnectionServer (pub)

rtr/sconnect.h rtr/sslconns.h

RTRTIBConnection (sub & pub) rtr/tconnect.h

RTRSSLDispatcher rtr/ssldisp.h N/A N/A

N/A N/A RTRTIBCustomizer rtr/tibcus-tomizer.h

RTRSSLFidDb (network) RTRFileFidDb (file)

rtr/sslfiddb.hrtr/ufdb.h

RTRTIBFidDb rtr/tfdb.h

RTRSSLInsertService rtr/sslinsrt.h RTRRTFieldToTIBRecordService (TIB)RTRTSAInsertService (RMDS)

rtr/fldtotib.h rtr/tsaisrvc.h

Table 5.1: Useful SFC Implementation Classes

SFC Developer’s Guide 265

Page 280: sfc

5 SFC IMPLEMENTATION DETAILS

5.3 Entitlements

The SFC has the ability to interact with a permissioning system to ensure that users can only access data for which they are entitled. By default, this capability is disabled. If a permissioning system is available at your site, your SFC applications will need to be enabled to take advantage of entitlements support. See section 5.3.2 for details on enabling entitlements.

There are several different types of entitlements that are supported by the SFC. Following is a description of each type:

• User Based Entitlements - This type of entitlement determines if the user is allowed to gain access to any infrastructure resources. The application is not allowed to access any services until the SFC has successfully “logged in” with the permissioning system. SFC services will remain in the stale state until the login occurs. Each user has a profile which determines a user’s level of entitlements. A username is passed to the permissioning system to match the application with the proper entitlements profile. See section 5.3.3 for details on how the username is set in an SFC application.

• Subject Based Entitlements (SBE) - This type of entitlement determines if the user is allowed to access data from or publish/insert data to a particular data service and data item based on the user’s profile. Examples of services are specific feed handlers or third party publishing applications. An example of a data item is the quote data for the symbol “IBM” from the NYSE exchange. Just before the item is to be requested from the infrastructure, the subject based entitlement check will be made. If the check fails, an Inactive event is propagated to the subscriber indicating that entitlements are denied. In the case of publishing applications, a message is logged indicating that the item cannot be published. In the case of inserts, an InsertNak event is propagated to the insert initiator.

• Content Based Entitlements (CBE) - This type of entitlement determines if the user is allowed to access a particular data service and data item based on entitlement data specific to that data item. The entitlement data typically contains codes that map into various entitlement categories, such as products, exchanges or vendors which are set up in the permissioning system database. The permissioning system is able to use the codes to check whether a given user is allowed to access the data item based on their entitlements in each category. The entitlement data is received from the infrastructure in conjunction with an image. The content based entitlement check is done before the image is forwarded to the subscriber. If the check fails, an Inactive event is propagated to the subscriber indicating that entitlements are denied.

SFC Developer’s Guide 266

Page 281: sfc

5 SFC IMPLEMENTATION DETAILS

• Publishing Entitlement Data - This is not so much an entitlement type as it is a mechanism used by publishing applications to provide entitlement data to downstream infrastructure clients for use in CBE checks. Entitlement data is provided before the initial image so that CBE checks can be performed before image data is processed. See section 4.2.2.11, Publishing Entitlement Data, for details. For information on how to create DACS access locks, refer to Appendix G, DACS LIBRARY FUNCTIONS.

In most cases, the entitlement checks occur within the SFC library at the desktop using profile data that is obtained from the permissioning system at start-up. The profile data is cached in the SFC library for quick access. In the case of SSL subscription, the entitlement checks occur in the Triarch infrastructure.

The DACS permissioning system is supported with the RMDS infrastructure (RRDP Market Data Hub and RMDS Distribution layer using SASS3) and the Triarch infrastructure.

5.3.1 Supported ConfigurationsThe types of entitlements supported in a given SFC implementation will depend on the infrastructure and protocol being used. Table 5.2 shows which permissioning system and entitlement type is supported by each SFC implementation. A blank indicates that the feature is not applicable. "N/S" indicates that the feature is not supported.

SFC Developer’s Guide 267

Page 282: sfc

5 SFC IMPLEMENTATION DETAILS

5.3.2 Enabling Data Entitlements in SFCIn the SFC, permissioning system access is handled in the RTRMDConnection class. The particular permissioning system used by the connection is tied to the infrastructure and protocol type; DACS is used for all RMDS and Sink Distributor.

Since the RTRTIBConnection, RTRSSLConnectionServer and RTRSSLConnection classes inherit from the RTRMDConnection class, each class uses the same mechanism for enabling data entitlements.

By default, data entitlements are disabled for RMDS (SASS2) but can be enabled either through SFC configuration files or by application code through methods available in the connection classes.

SFC-supported Infrastructure

User Based

Subject Based

Content Based

Publish Data3

RMDS SASS3 subscription DACS DACS DACS1

RMDS SASS3 publication DACS DACS DACS4

RMDS SASS3 inserts DACS DACS

RMDS Hub publication DACS DACS DACS

SSL subscription2 DACS DACS DACS1

SSL publication DACS DACS DACS

SSL inserts2 DACS DACS

Table 5.2: Supported DACS Entitlements Types in SFC 1. DACS Access Lock entitlement data is used for content based permissioning with DACS.2. DACS entitlements is performed in the Sink Distributor.3. Due to restrictions in the DACS permissioning system, it is not possible for a publishing application to both publish entitlement data and use subject based entitlements to control which items are published.4. Capable with RTIC 11.1 or newer.

SFC Developer’s Guide 268

Page 283: sfc

5 SFC IMPLEMENTATION DETAILS

By default, data entitlements are enabled for SSL publication and RMDS (SASS3), but can be disabled either through SFC configuration files or by application code through methods available in the connection classes

To enable or diasble entitlement through configuration, use the following parameter in the SFC configuration file *enableEntitlements with a value of "True" or "False" (case insensitive). (See section 5.5.10.1 and 5.5.10.2.)

To enable or disable entitlements programmatically, explicitly create a connection and pass it to the service or service pool factory:

RTRObjectId appId("appId");RTRTIBConnection connection(appId, "connection");

//to disable entitlements the following line//should be RTRFALSE

connection.enableEntitlements(RTRTRUE);connection.connect();RTRTIBRTRecordService service(appId, "RSF", connection);

The RTRMDConnection base class has an entitlementsEnabled() state attribute. This attribute has different semantics for the SSL than for RMDS or TIB implementations. On RTIC-based RMDS, this attribute reflects whether entitlement checking will be performed in the SFC or not. On SSL subscription, this attribute has no meaning since all subscription entitlements are performed in the Triarch infrastructure.

In the RTRTIBConnection and RTRSSLConnectionServer classes, the enableEntitlements(RTRBOOL) method is available in both classes to enable or disable entitlement checking for that connection. Entitlements can also be enabled through configuration with the *enableEntitlements variable.

When entitlements are enabled for TIB implementations, the SFC services will remain in a Stale state and will not request data until connection has successfully logged the user into the permissioning system. The login process is initiated when the connect() method is invoked on an instance of RTRTIBConnection or RTRSSLConnectionServer.

When entitlements are enabled for TIB implementations, the system will block until all entitlements information is loaded in from the permissioning system. This entitlement profile from the permissioning system is loaded after the data dictionary is complete. This means the connect() call will block and SFC services will not be available during that time.

SFC Developer’s Guide 269

Page 284: sfc

5 SFC IMPLEMENTATION DETAILS

5.3.3 Setting the UsernameIn any environment where the DACS permissioning system is in use, the SFC library must have a valid username to pass to the permissioning system. The username consists of several informational elements including the machine name where the application is running, an application identifier and the name of the user running the application. The username is used by the permissioning system to associate an entitlement profile with this application so entitlement checks can be performed on all SFC item accesses.

In typical usage, the username is determined automatically in the SFC, with default values obtained from the operating system (like hostname and username). However, some or all of the elements found in the username can be also be set from application code or via configuration.

For convenience, this username can be set on many of the SFC service constructors. If an application creates its own RTRSSLConnection, RTRTIBConnection or RTRSSLConnectionServer, the username can be set directly using the username(const char *) method any time before the connect() method is called. The username can also be set through configuration using the “*username” configuration variable.

The username is a null-terminated character string that is used to convey entitlement information. The string is composed of several fields delimited by the ‘+’ character. The string format is defined as follows using BNF notation:

<user_name> ::=<User_name> |<User_name>+<Application_ID> |<User_name>+<Application_ID>+<Position>

More fields may be defined in the future. They will be appended to the end of the string in a similar manner. The string should not contain any extraneous white space characters.

The User_name field identifies a particular person who has been assigned a unique name for access to the infrastructure (e.g., “E_DICKINSON”). The SFC does not attempt to verify the supplied name

NOTE: Backus-Naur Form (BNF) notation consists of the following symbols:<> encloses token elements + concatenates elements | exclusive OR ::= is assigned to

SFC Developer’s Guide 270

Page 285: sfc

5 SFC IMPLEMENTATION DETAILS

beyond ensuring that the name corresponds to an actual user. The length of the User_name field must not exceed 255 characters. If this field is omitted, the SFC assigns the default user name which is the name that the owner of the current process used to log into the operating system. This default is suitable for most applications. The explicit specification of the user name is needed mainly for applications that handle multiple users in a single process.

The Application_ID field provides the identity of the SSL application. The application ID must be an integer in the range 1 to 511. The SFC will verify that the application ID is in this range.

Application IDs are assigned by the Reuters International Product Manager for Entitlements. A unique ID should be obtained if the application is to be used at more than one client site. For site-specific applications, select any ID in the range 257-511. If this field is omitted, the SFC assigns the default application ID number, which is 256.

In the case of a single user running the same application on the same machine, the Position field can be used to uniquely identify the sink application. The length of the Position field must not exceed the 239 (255 - 16. Note that 16 bytes must be reserved for the IP address, which is added to this field by the SFC.) If this field is omitted, the SFC assigns the default Position “net”. The Position is used in conjunction with the IP address of the machine on which the process is running to check entitlements based upon physical location.

Some examples of valid UserName strings are as follows:

1. V_Kandinsky+7+13”

This means the user V_Kandinsky is running application number 7 on position 13 of this machine.

2. “C_Monet+7”

User C_Monet is running application number 7; the position takes the default value.

3. “+8”

The user name takes the default value. The application ID is 8. The position takes the default value.

4. “”

The user name, application ID, and position all take the default values. This is the most common usage.

SFC Developer’s Guide 271

Page 286: sfc

5 SFC IMPLEMENTATION DETAILS

5.3.4 Publishing DACS Access LocksWith this version of SFC, some configuration is necessary to ensure that your DACS formatted entitlement data will be published properly to the RRDP Market Data Hub (Source Distributor). Specifically, the SFC library needs to have a mapping of service names to service identifiers. This mapping can be supplied either by configuration for simple cases or by directly installing a map entry into the SFC for locks created by different services.

If your publishing application is creating its own DACS access locks, your application must pass to the DACS access lock creation function the same service type (also called service ID) that is used by the DACS system for your published service name. This service type is embedded into the access lock and is used by subscription applications to make CBE checks against that service. The administrator for the DACS system sets the service ID.

Furthermore, the service mapping table in the SFC must contain a mapping for that service ID to the name of the published service. This is required by the SFC so the access lock can be translated into a format acceptable by the Source Distributor. Your publishing application has several options for setting the service ID/service name mapping entry.

• Allow the SFC to automatically add the mapping entry via configuration variable.

This will only work if the DACS access locks were created with a service ID that maps to the service name that is being published to the Source Distributor. The SFC will look for the entry "*<service_name>*serviceId : <id>" in the SFC configuration file, where <service_name> is the name of your published service and <id> is the service ID associated with that service name in the DACS system and in the Source Distributor.

An example configuration entry is "*MY_SOURCE*serviceId : 123". This same service ID must also be set in the Source Distributor configuration file for the service name "MY_SOURCE".

• Add one or more service ID / service name mappings to the SFC directly.

This method should be used if your application does not use the SFC configuration file or if your DACS access locks contain a service ID that does not map to the same service name that is being published. For instance, if you create an access lock or compound lock that contains the service ID 13033 which represents service name "IDN_RSF", but your application is publishing to service name "MY_SOURCE" which has a service ID of 123 (as determined in the DACS system

WARNING: If a mapping does not exist for the services associated with a given DACS access lock, the entitlement data will not be published and an error message will be logged in the SFC log file.

SFC Developer’s Guide 272

Page 287: sfc

5 SFC IMPLEMENTATION DETAILS

and the Source Distributor configuration file), then your application needs to add a new SFC map entry for service ID 13033 and service name "IDN_RSF".

The following code shows how this mapping entry is added to the SFC from application code:

#include "rtr/sslinterface.h"

int serviceId = 13033;char* serviceName = "IDN_RSF";RTRServiceIdNamePair* entry = 0;

entry = RTRSSLInterface::ServiceIdMap.getPair(serviceName);if (entry == 0){

cout<< "Adding service map entry for "<< serviceName;cout<< " and id "<< serviceId << endl;RTRSSLInterface::ServiceIdMap.addEntry( serviceName, serviceId );

}else{

cout<< "Already have entry for " << entry->serviceName();cout<< " with service id " << entry->serviceId() << endl;

}

5.3.5 DACS Implementation DetailsFollowing are some details regarding the way that DACS is used in the SFC which may be helpful in understanding the general architecture.

When a RTRTIBConnection or RTRSSLConnectionServer object is created, the connection will attempt to establish a TCP/IP connection to a DACS Daemon process which is running on the same

NOTE: The service ID used in the SFC service name mapping table must be the same as the ser-vice ID set in the DACS system and the service ID set in the Source Distributor configuration file for this published service name. If not set correctly, the published entitlement data will not make it through the RRDP Market Data Hub.

NOTE: Publishing DACS access lock to RTIC does not need mapping.

SFC Developer’s Guide 273

Page 288: sfc

5 SFC IMPLEMENTATION DETAILS

machine as the application. Once the connection is established, the SFC will attempt a login to the DACS permissioning system using the information available in the username (see section 5.3.3). If this succeeds, a profile for that user is passed back to the SFC and cached there. At this point all data services will become available in the normal fashion, depending on availability from the infrastructure.

As new items are requested, items are published, or inserts are made, the SBE and CBE checks are invoked and the results handled as described at the top of this section.

If exceptional conditions occur, the SFC will handle them as follows:

Error event SFC Action

Connection to DACS Daemon is lost

The SFC will automatically attempt to reconnect to the DACS Daemon at 60-second intervals. The interval is configurable via the DACS_retry_connection_interval configuration parameter. While the connection is down, entitlements checks will continue using the existing user profile cached in the SFC. Furthermore, by default, no interruption in data service will be seen. After the reconnection to DACS is successful, all entitlements will be re-checked in case the user profile has been changed.

The SFC behavior is able to be configured by using new configuration parameters: *stopSubscriptionWhenDACSDowns and *stopPublica-tionWhenDACSDowns. The *stopSubscriptionWhenDACSDowns is for subscription while the *stopPublicationWhenDACSDowns is for pub-lication and contribution. The default values are False. If the configuration is set to True, the data service will be interrupted. After the reconnection to DACS is successful, all entitlements will also be re-checked in case the user profile has been changed.

Table 5.3: Error Handling of DACS Exception Cases

SFC Developer’s Guide 274

Page 289: sfc

5 SFC IMPLEMENTATION DETAILS

5.3.5.1 DACS Thread Aware OptionSFC has bundled DACS 5.2 that thread aware feature is implemented. This allows a multi-thread process to have SFC embedded within it. Each multi-thread process can perform desktop permissioning.

To enable the DACS thread aware option, add the following commands to the startup script for the target process:

DACSAPI_THREAD_AWARE=true; export DACSAPI_THREAD_AWARE

Login to DACS Daemon fails

The SFC will automatically retry the login at 1-second intervals. This inter-val is configurable via the DACS_user_login_retry_interval config parameter. While the SFC is not successfully logged into the DACS per-missioning system, no access will be allowed to the infrastructure services. All subscription services will remain in the Stale state during this time. Pub-lishing applications will not publish records to the infrastructure during this time because the connection server will not be activated until the login suc-ceeds. All insert services will be in the Stale state until the login succeeds.

DACS system changes the profile for a user

The SFC will receive an event from DACS to re-verify all items. Both SBE and (where feasible) CBE checks will be made. Subscription items that fail the entitlements check will be transitioned to the Inactive state. All publish-ing items that fail the entitlement check will stop propagating data to the infrastructure and log a message to the SFC log file. Note that publishing applications may not receive a notification of this event except for an indi-cation that no more clients are watching the item. All services that fail the check will be transitioned to the Stale state as will all items associated with the service.

DACS system un-entitles a user

The SFC will receive an event indicating the user login is no longer valid. All data services will be transitioned to the Stale state. All data items will be transitioned to the Stale state with appropriate text indicating that the user login failed. No attempts are made to re-login. It is up to the application to do this via the RTRMDConnection::connect() method.

Error event SFC Action

Table 5.3: Error Handling of DACS Exception Cases

SFC Developer’s Guide 275

Page 290: sfc

5 SFC IMPLEMENTATION DETAILS

For Windows [NT, 2000, XP or 2003], an environment variable can be set at the system level by using the normal Windows facility for setting environment variables.

Variable Name: DACSAPI_THREAD_AWAREVariable Value: true

5.3.6 Entitlements ConfigurationThe following configuration parameters can be used to change the behavior of the DACS entitlements implementation:

• *<serviceName>*serviceId : This parameter is used to set the service ID value for a particular service name. This can be used when publishing entitlement data. The SFC requires that a mapping is available for each service ID that will be found in the entitlements data if that data uses the DACS access lock format. The <serviceName> must be the name of the service as it is published to the system. The value of this parameter must match the service type / service ID found in the DACS access lock and must match the service ID in the DACS database and in the Source Distributor configuration file for this service name.

• *<serviceName>*serviceID - This is an alternative to the serviceId parameter explained above. This configuration parameter takes precedence over the serviceId parameter if both exist in the SFC configuration file. This parameter matches a parameter previously used in the sslapi.cnf by the SSL ‘C‘ API and remains for compatibility uses. The instanceId parameter should be used in typical usage scenarios.

• *username - Determines the username that is used by the permissioning system. See section 5.3.3 for details.

• *permField - defines the data field to use to generate DACS lock in a TIB SASS3 infrastructure. The default value is PROD_CATG.

• *dacsHashTableSize - OBSOLETE. Determines the size of the hash table that holds entries associated with each item that is currently being watched or published. Increase this value if your application will be subscribing or publishing to > 1000 items.

NOTE: *number_of_items should be used instead of dacsHashTableSize.

• *DACS_retry_connection_interval - Sets the number of seconds to wait before trying to reconnect to the DACS sink daemon. The default value is 60 seconds. This value should not be set too low because attempting to connect to the DACS sink daemon is a blocking call.

SFC Developer’s Guide 276

Page 291: sfc

5 SFC IMPLEMENTATION DETAILS

• *DACS_user_login_wait_period - Sets the number of seconds to wait for a reply to a login request before giving up. The default value is 60 seconds.

• *DACS_user_login_retry_interval - Sets the number of seconds after a login timeout before trying to login again. The default value is 1 second.

• *DACS_log_file_size - This parameter is the size that the usage data file can grow too, after which a message is sent to the DACS Server to pick up the usage file. This parameter is interparated to be in kilobytes. The default value is 255.

• *DACS_log_file_path - This parameter defines the location where the usage and backup usage file will reside. The default location is the current directory.

• *DACS_log_flush_interval - Sets how often the DACS log information is flushed to disk. The default is 60 seconds.

For the RMDS infrastructure, see section 5.5.10 for additional configuration for enabling entitlements.

SFC Developer’s Guide 277

Page 292: sfc

5 SFC IMPLEMENTATION DETAILS

5.4 Performance Tuning and Tracing

SFC’s performance depends on a variety of factors. As with most other computer software, SFC has a CPU time versus memory space tradeoff. In some instances, SFC also has a CPU time versus cross-infrastructure compatibility tradeoff. Additionally, SFC’s performance can depend on the type and configuration of the infrastructure, the responsiveness of the network, and the format of the data. This section discusses how to manage the tradeoffs and what can be done by the application developer and the system administrator to maximize SFC’s performance. See section 4.8.3.3 for performance implications with custom event loops.

5.4.1 General Guidelines

5.4.1.1 Use Libraries Without AssertionC++ Edition includes two optimized libraries, one with assertions enabled (i.e. the -a libraries) and one without assertion enabled. The assertion libraries are built with preconditions and post conditions to help detect when the library is used incorrectly. Some of the assertion checks are very time consuming, so the assertion libraries should not be used in performance intensive applications.

5.4.1.2 Disable TracingFor optimal performance, tracing should always be disabled. Tracing is off by default. See section 5.4.6 for details on tracing.

File and stderr logging can also affect performance. Debug-level logging is useful when developing an application, but it can be overkill for applications that are working. The following configuration will minimize logging in applications that are working normally:

*selector: *.warning*install_stderr_action: false

To completely disable logging, do not create a RTRDefaultLogger in the application and set the following configuration:

*sslLogFileSize: 0

SFC Developer’s Guide 278

Page 293: sfc

5 SFC IMPLEMENTATION DETAILS

5.4.2 Optimizing CodeSFC provides value-added functionality to market data, including request queuing, parsing, caching, and callback dispatching. While this functionality reduces the work that must be done by the application, it does take some time. Some of the most expensive operations in SFC are:

• Accessing a market data item from a service

• Accessing a field from a record

• Setting the contents of a field

• Sending an image or an update

Whenever reasonable, SFC applications should try to minimize those operations to improve performance.

5.4.2.1 Accessing a Market Data Item from a ServiceSFC’s data cache improves application performance when the same records are accessed repeatedly by eliminating the need to re-request the record from the infrastructure. Arbitrary access to a record involves a hash table look-up using the RIC. While SFC uses an efficient hashing function, the speed of the hash table look-up depends on the loading factor of the hash table. SFC’s hash tables use linked lists for collisions, so when the hash table is overloaded, item retrieval is not constant.

If SFC’s performance degrades with a large number of items, then the hash table size may need to be increased. By default the hash table size defaults to 503 for consuming services and 101 for publishing services. The hash table size can be configured using the *number_of_items configuration variable. This variable can be configured on a per service basis by scoping with the service name. For example:

*RSF*number_of_items: 1453*MY_SERVICE*number_of_items: 142857

Also, this variable can be configured with a specific ClassId (see section 5.6.2). For example:

*TIBRTRecordService*number_of_items: 100000*SSLPublisherRecordService*number_of_items: 150000

However, configuring *number_of _item per ClassId will be overrided by setting of *number_of_item and *number_of_items per service.

If RTRRTRecordServiceIterator is used to iterate through all cached records, be sure to use the fastNext() method instead of forth(). See the Reference Manual for details.

SFC Developer’s Guide 279

Page 294: sfc

5 SFC IMPLEMENTATION DETAILS

When SFC does not have an item cached, the time that it takes to provide data images via sync events depends on the infrastructure and on SFC’s request queue. If the infrastructure does not have items cached, then the image rate will be slower and the CPU utilization by SFC will be slower. For information on how the request queue affects image rates, see section 5.4.4.

5.4.2.2 Accessing a Field from a RecordApplications can improve performance by controlling how and when field lookups are performed. Deciding the best way to access fields depends on the application’s deployment infrastructures, design, and memory footprint.

Lookups by FID (i.e. RTRRTRecord::field(int)) are more efficient than by field name (i.e. fieldByName(const char *)). However, since FIDs are not consistent across infrastructures, using field names is more portable. If an application is only going to be used in one infrastructure, then FID lookups can be used.

Alternatively, if a small number of fields are used by an application, it could look up the FIDs for the field names dynamically at initialization using a RTRFidDb. Then it could cache the FIDs and use them when processing updates and images for efficiency. For a small number of records, references to the RTRRTField objects could be maintained in the application.

To avoid field look-ups completely, an application can implement RTRRTFieldClients. Then, SFC will dispatch field update events to the application during parsing, thereby completely avoiding a field look-up in the application.

If the application is interested in most of the fields, then RTRRTRecordIterator and RTRRTRecordUpdateIterator should be used instead of dozens of RTRRTFieldClients. Since the fields are sorted, the record iterators provide consistent and efficient access to all of the fields.

5.4.2.3 Setting the Contents of a FieldSFC’s RTRField objects store data in a character array. When the publisher changes the data, it must use one of several set methods to copy the new data into the field. When many fields update very frequently, data copying becomes one of the most expensive operations in a publisher application. RTRField provides several set methods, each designed to optimally handle different types of data. SFC uses all of these methods internally when parsing and caching consumer data:

• RTRField::setData(const char*, int) uses strncpy to write the data directly in a field’s string storage.

SFC Developer’s Guide 280

Page 295: sfc

5 SFC IMPLEMENTATION DETAILS

• RTRField::set(double) and RTRField::set(int) use sprintf to write numbers into a field’s string storage.

• RTRField::set(const char *, int) searches the data for character repetition, partial field update, and RMTES escape sequences. Alphanumeric Marketfeed data may include these escape sequences. This method is less efficient then setData().

• RTRField::setFromExpandedValue(const char *) is a convenience method that converts an expanded string to an enumeration integer and then writes the integer to the field’s string storage.

• RTRField::use(char *) is a utility method that can be used for rippling fields efficiently. The char * argument is swapped for the field’s internal storage. The old storage is returned and the application must be sure to clean up the field. No data copying is done, so this data is very efficient. The following code shows how the method can be used to ripple fields:

// RTRRTRecord _record// RTRRTField * fld; // a field that ripplesRTRRTField * rfld = fld;char * tmpfld = (char *) fld->to_c();while (rfld->rippleDefinition()){

rfld = _record.field(rfld->rippleDefinition()->fid());if (!rfld)

break;tmpfld = rfld->use(tmpfld);

}fld->use(tmpfld);fld->setData("new data");

After setting a field’s data for an update, the field must be added to a RTRRTFieldUpdateList. This class includes several methods for adding the field: putFieldByName(const char*), putFieldByFid(int), and putField(RTRRTField&). putFieldByName(const char *) looks up the FID and calls putFieldByFid(int), which searches for the field in the record and then calls putField(RTRRTField&). So putField(RTRRTField&) is the most efficient of the three methods.

RTRRTFieldUpdateList and RTRRTRecordImpl maintain fields in a sorted array. So fields should be added using putField(RTRRTField&) in FID order whenever possible to avoid resorting.

SFC Developer’s Guide 281

Page 296: sfc

5 SFC IMPLEMENTATION DETAILS

5.4.2.4 Sending an Image or an UpdateRTRRTRecordImpl::indicateSync() and RTRRTRecordImpl::indicateUpdateComplete() are expensive methods because they format a message for the network and send the message to the low-level communication library (SSL, SASS3, or MDAPI). Depending on the batching features supported by the low-level library, the message may also be sent to the network during the indicate call.

Image and update messages will not be sent to the network unless the publisher service is up. So to pre-load SFC’s cache, create all records and call RTRRTRecordImpl::indicateSync() on those records before calling RTRRTRecordServiceImpl::indicateSync().

When SSL publishers are in source-driven mode, SFC will pace sending images to the network. See section 5.4.5 for details.

SFC’s SSL and TIB publishing implementations do not require RTRRTField::indicateFieldUpdated() to be called for updated fields. Publisher applications only need to call that method if a RTRRTFieldToFieldRecordService is used to publish data in the same process to be used by other components in the same application.

5.4.3 Reducing Memory UsageMost of the memory used by an SFC application is from the fields cached for each record. This section discusses several options for controlling how much memory is used by cache.

Previous versions of SFC used the *fids_per_record configuration variable to set the field array size of a record. This variable is no longer needed, as SFC will now dynamically size the field array of each record using the record’s image. Leaving *fids_per_record set to the default (-1) will minimize memory usage.

5.4.3.1 Use SFC’s CacheApplications should try to take advantage of SFC’s data cache. SFC’s cache can be leveraged in several ways:

• if the application design permits, it should not keep its own copy of the data

• use service iterators to access the item in SFC’s cache instead of maintaining a separate watchlist in the application

• a single object can be a client of multiple market data items

SFC Developer’s Guide 282

Page 297: sfc

5 SFC IMPLEMENTATION DETAILS

5.4.3.2 Reducing Consumer MemoryIf all of the applications only need a subset of the data, the infrastructure can be used to filter the data. All cache applications will have a smaller cache footprint and will also have better performance from smaller messages.

When a RTRRTFieldClient is added to a RTRRTField, additional storage is allocated for the field. So memory can be saved by not using RTRRTFieldClients. When the first field client is added to a field, approximately 32 bytes are used. So using RTRRTFieldClients is only an issue when the application has thousands of records, each with many field clients.

When Triarch and RMDS consuming applications only need a small percentage of the fields in the record, but using a filtering component in the infrastructure is not an option, the applications can save memory by using a custom appendix_a. If a FID definition is not in the appendix_a, SFC will not cache the field. If a custom appendix_a is used, several guidelines should be followed:

• SFC will create a Notice log event for fields with no definition, so the logging selector should be set to *.warning to avoid performance degradation.

• Fields removed from appendix_a must also be removed from enumtype.def.

• A custom appendix_a should only be used by the application that requires it. Do not change the system appendix_a and enumtype.def in /var/triarch. The SFC application can use the *fid_file_path and *enum_file_path configuration variables to set the location of a private data dictionary.

5.4.3.3 Reducing Publisher MemorySFC publishing applications allocate the character arrays used to store field data. Normally, the size of the allocated array is the FID definition + 1 (for the termination character). If the application knows that the FID definition is larger than necessary for a particular field (e.g. the DSPLY_NAME is "ZZZ Inc.", which is much less than the FID definition size of 16), then it could allocate the maximum field size + 1.

5.4.4 Request Queueing and TimingSFC uses request queuing to avoid thrashing and to ensure that an SFC client application behaves in a reasonable manner. If a client application requests a large number of items at the same time, the item images could be returned about the same time. If the client application cannot process the images fast enough, the network channel will overflow, causing the application to be disconnected. When the

SFC Developer’s Guide 283

Page 298: sfc

5 SFC IMPLEMENTATION DETAILS

client tries to recover, it will again request all of the items, thereby repeating the problem. This situation is often called thrashing.

Sometimes, requests for valid market data items take a longer period of time, especially when they are not cached by the infrastructure. SFC uses request timing to ensure that a few slow pending items do not prevent other queued requests from waiting an unreasonable amount of time.

Many of the properties, such as queue sizes and request time-out intervals, can be customized. Most client applications can use the defaults. However, depending on factors such as client machine speed and network bandwidth, some applications may see better behavior by changing the request properties.

The request queuing and timing implementations are the same for both the SSL and the TIB implementations of SFC.

5.4.4.1 Request QueueThe request queue is used to queue pending requests which are descendants of RTRRequestItem. The request queue has a limit on the current number of outstanding requests. This is called the pending limit. In the SFC, the request queue implementation will adjust its pending limit to maximize request processing. There are three configuration parameters that affect the current value of the pending limit:

• *initial_pending_limit: the base value of the pending limit

• *max_pending_limit: the maximum value of the pending limit

• *limit_multiplier: current pending limit * limit_multiplier = new pending limit

• *pending_resize_trigger: the size of the pending list when the resize is applied

Initially, the pending limit is set to initial_pending_limit. At any one time, there can be at most pending limit number of requests outstanding. If the number of requests outstanding hits the pending limit, the pending limit will be raised to the value:

(current pending limit * limit_mulitplier)

when the last pending request is completed successfully. Then pending limit number of requests may be made.

If any pending request fails (due to no response, for instance), the pending limit is reset to initial_pending_limit. The pending limit will never exceed the value max_pending_limit.

SFC Developer’s Guide 284

Page 299: sfc

5 SFC IMPLEMENTATION DETAILS

In light request traffic, the pending limit will remain at its current level and requests will go out as they are received. When a large burst of requests causes the pending limit to be hit, the limit will be raised and a new set of requests will be made upon the successful completion of the last pending request.

Normally the pending list is only resized when it is empty. However, if a few of the requests take a very long time to receive images or inactive events, requests in the waiting list will not be sent, and image throughput will suffer. If pending_resize_trigger is set to be > 0, the slow items will not prevent the queue from resizing and additional requests from being made. When the pending list reduces to the size of the resize trigger, the queue resize algorithm described above will be used.

5.4.4.2 Request TimingIn the SFC, the request item implementation will make its own requests for data via the SSL and will interact with the request queue. When requests fail, the item will attempt to retry the request.

There are four configuration parameters associated with timing requests and timing request retries:

• *timeout_seconds: time to wait for a response to a request

• *retry_seconds: initial amount of time to wait before a request retry is attempted

• *retry_cap_seconds: maximum amount of time to wait before a request is retried

• *retry_multiplier: current retry time * retry_multiplier = new retry time

Upon making a request, the item will be pending in the request queue. The request item schedules its data request and will eventually take itself out of the pending queue if a response is not received within timeout_seconds.

Upon timing out or receiving a data response that indicates the data cannot be accessed at the moment, an item will wait retry time (seconds) before re-requesting. Initially, the retry time is set to retry_seconds. If the next request attempt fails, the retry time is set to (current retry time * retry_multiplier). This continues until the request is successfully completed or the item becomes inactive. The maximum value of the retry time is retry_cap_seconds.

5.4.4.3 ConfigurationThe following parameters can be set in the SFC configuration file:

*request_queue*initial_pending_limit : 10*request_queue*max_pending_limit : 100*request_queue*limit_multiplier : 2

SFC Developer’s Guide 285

Page 300: sfc

5 SFC IMPLEMENTATION DETAILS

*request_queue*pending_resize_trigger : 0*request_item_config*timeout_seconds : 100*request_item_config*retry_seconds : 10*request_item_config*retry_cap_seconds : 5000*request_item_config*retry_multiplier : 3

All of the values shown above are the defaults.

This configuration assumes that the application creates an instance of RTRXFileDb and makes this instance the global configuration database by calling RTRConfig::setConfigDb() and passing the new RTRConfigDb instance.

5.4.5 Image Publishing

5.4.5.1 Relationship between SFC and Source Distributor Cache SizeThe SFC configuration variable *number_of_items controls the size and efficiency of SFC’s cache and also may affect a 4.2 Source Distributor or later. The Source Distributor has a configuration variable called *maxCache that sets the maximum hash table size for the Source Distributor’s cache list and a configuration variable called openLimit (which can be set on a per service basis) that sets the hash table size for the Source Distributor’s cache list. The Source Distributor will set its cache size to the lesser of these two values.

The Source Distributor’s *cacheType configuration variable (sinkDriven or sourceDriven) and the Source Distributor’s *preemptionLocation (none, SSL, srcApp) configuration variable specify how the cache list should be managed.

• If the *cacheType is sinkDriven and the *preemptionLocation is none or SSL, the Source Distributor controls the size of the cache list.

• If the *cacheType is sourceDriven or the preemptionLocation is srcApp, SFC controls the size of the cache list. The *preemptionLocation parameter is only applicable to sinkDriven applications.

When the Source Distributor controls the size of the cache list, it checks the maxCache whenever it attempts to add an item to the cache list (and preempts an item if necessary and so configured).

NOTE: Make sure you include the "*" in front of the "request_queue" portion of the identifier. (See section 4.8.5 for details.)

SFC Developer’s Guide 286

Page 301: sfc

5 SFC IMPLEMENTATION DETAILS

When the source application controls the size of the cache list and maxCache is configured as 0 (zero) or not present in the Source Distributor’s configuration file, the SFC source application’s publisher service *number_of_items value will be used as the maximum cache size. If the Source Distributor’s *maxCache is configured to greater than 0 (zero) in the Source Distributor’s configuration file, the SFC source application’s publisher service’s *number_of_items value will be used as the Source Distributor’s openLimit value. So, in this case the Source Distributor will set its cache size for this service to the lesser of the Source Distributor’s maxCache and SFC’s *number_of_items.

More information is available in the Reuters Market Data Hub - Source Infrastructure 4.2 Software Installation Manual.

5.4.5.2 Source-Driven PublishersSee Table 4.9 (Section 4.2.4) for more information on which implementations support sink and source-driven publishing.

5.4.5.3 Image PacingIf a publishing application preloads its cache, SFC will pace the publishing of images to the infrastucture component. SASS2 and SASS3 local publishers will automatically take advantage of this feature to reduce the flood of images to the network and normallize CPU usage on the application’s host. On an RMDS Market Data Hub and a Triarch infrastructure, source-driven publishers have the ability to preload the cache of a 4.2 or later Source Distributor in the similar manner. This can improve performance by decreasing publisher to subscriber latency and reducing request traffic between the Source Distributor and the publishing application.

While an RTIC will not need to be configured to take advantage of image pacing, a Source Distributor will need the following configuration parameters set in the Source Distributor’s triarch.cnf file (see Source Distributor documentation for full details):

<servicename>*cachelocation: ssl<servicename>*cachetype: sourceDriven

There are two infrastructure independent configuration parameters available to the SFC source application user that allow for configuration of some behavioral aspects of image pacing. The following parameters can be set in the source application’s configuration file:

*imagesPerInterval : 30 ! default*imageInterval: 100 ! default; in milliseconds

SFC Developer’s Guide 287

Page 302: sfc

5 SFC IMPLEMENTATION DETAILS

When the source application completes a connection to an infrastucture component, the source application will issue the images for all of the items in a service over a period of time. This set of images is broken down into subsets (defined by *imagesPerInterval) and sent to the Source Distributor at intervals (defined by *imageInterval) which would, by default, publish 300 images per second. These parameters allow the user to avoid sending out a very large number of images in a very short period of time, which could lead to overloading socket connection or Rendezvous daemon.

.

When publishing to a Source Distributor it is important to have the Source Distributor configured to handle a very large number of images.The Source Distributor also has a parameter called "open window". This specifies the maximum number of outstanding image requests allowed at any given time. Currently, the default is 40. The configuration variable to set the Source Distributor’s open window is *initialOpenLimit. This is a configuration variable found in the triarch.cnf file. Please see the Source Distributor’s documentation for more details.

5.4.5.4 Performance and Record TemplatesSFC publishers have the ablility to add a new field during a Record resync event (see section 4.2.2.5 for details). There is a performace tradeoff however. Adding a field does not work if a record template is used, but the infrastucture performace is slower if the infrastucture does not use record templates.

5.4.6 TracingSFC provides several mechanisms for tracing that can aid in troubleshooting the network configuration and the application.

To turn on tracing, the debug filter must first be enabled in the selector configuration variable:

*selector : *.debug

5.4.6.1 RMDS/SSL Publishing and RMDS SubscriptionIn the configuration file, tracing can be enabled with:

NOTE: In source-driven mode, a source application should pre-load its cache before a Source Dis-tributor connects to it or it connects to an RV daemon. Otherwise, the pacing algorithm described above will not be used. To pre-load SFC’s cache, create and populate all records before calling RTRRTRecordServiceImpl.indicateSync().

SFC Developer’s Guide 288

Page 303: sfc

5 SFC IMPLEMENTATION DETAILS

*traceLevel : <level>

which will begin logging debug messages to the logger. <level> is an integer bitmask used to set various levels of tracing. Valid values are created by adding the integer values of each level that is to be logged.

1= service level tracing

2 = basic item level tracing

4 = full item level tracing

8 = item image/update data tracing

In the TIB implementation, level 8 sends the full parsed TIBMsg to stderr.

The "debug" filter must also be enabled in the *selector configuration variable.

For example, to turn on service level and item image and update data tracing, the following entries would be used:

*selector: *.debug*traceLevel: 9

5.4.6.2 SSL SubscriptionIn the configuration file, SSL client-side tracing can be enabled with:

*item_debug : true

The "debug" filter must also be enabled in the *selector configuration variable.

5.4.7 Low-level Tracing and Error MessagesProtocol-level error messages are not sent to the SFC logging mechanism. Instead, they are output to protocol-specific files.

SSL library error messages are sent to SSL.log. The name of the SSL log file can be set with SFC’s *sslLogFile configuration variable. This file will include additional tracing of the sink mount parameter if SFC’s *mountTrace configuration variable is set to True. The maximum size of the file can be set with *sslLogFileSize.

SFC Developer’s Guide 289

Page 304: sfc

5 SFC IMPLEMENTATION DETAILS

Additionally, IPC messages to Triarch and the Market Data Hub can be traced using the sslapi.cnf configuration variables *eventLogging, *messageTracing, and *functionLogging, described in section B.6.3. The IPCTRACE file created with this configuration is always in the local directory.

For RMDS, SASS3 library error messages are sent to SASS3.log. The name of the SASS3 log file can be set with the *tiblogfile configuration variable.

The following configuration summarize these configuration variables with their defaults:

*sslLogFile : SSL.log*sslLogFileSize : 10000*mountTrace : False*tiblogfile : SASS3.log

SFC Developer’s Guide 290

Page 305: sfc

5 SFC IMPLEMENTATION DETAILS

5.5 Implementation Issues

This section discusses miscellaneous infrastructure details and compatibility issues. Throughout this section, references to an RTIC assume a standard RMDS configuration, using Marketfeed and not using tss_records.cf. For more details on how an RTIC behaves when configured with tss_records.cf and tss_fields.cf, see Appendix E.

5.5.1 Cross-infrastructure CompatibilityThe C++ Edition has made considerable effort to try to hide compatibility issues between infrastructures. In most circumstances, the startup code in the main() routine selects an implementation and the rest of the application is infrastructure independent. In some circumstances, it does not hide those differences. The following table lists the potential issues and the sections that discuss the issue in greater detail.

Issue Section

Entitlement system used section 5.3.1

Data format details section 5.5.2

Record template numbers section 5.5.3

Data dictionaries used section 5.5.4

Dynamic service availability section 5.5.6

Subjects for news headlines section 5.5.7.6

RIC to subject mapping section 5.5.7

Page attribute encoding section 5.5.8.2

Model to use for inserts section 5.5.9

Rendezvous 6 interoperability section 5.5.11

Rendezvous 5 interoperability section 5.5.12

Table 5.4: Cross-infrastructure Compatibility Index

SFC Developer’s Guide 291

Page 306: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.2 Data FormatSFC supports two data dictionary formats: Marketfeed data dictionary (appendix_a and enumtype.def) and TSS data dictionary. The Marketfeed data dictionary is originated from Triarch infrastructure and supported in Triarch and RMDS infrastructures. The TSS data dictionary is originated from TIB infrastructure and currently supported only RMDS infrastructure.

The RMDS and Triarch market data infrastructures encode the same data in different ways regarding the dictionary formats used. While SFC hides most of these differences, some of these differences come through the interface. The two primary differences that an SFC developer will need to be concerned with for cross-infrastructure compatibility are FIDs and record templates.

• The FIDs used in Marketfeed-based and in TSS-based are usually different. The field names, however, are the same. For example, the FID for the field "BID" is 22 on Marketfeed-based, but it could be 10720 on a TSS-based. To be safe, use RTRRTRecord::fieldByName(const char *) when accessing fields in a record.

• Fields in TSS-based do not have long names (the DDE acronym column in Triarch’s and RMDS’s appendix_a), so RTRField::longName() will just return the same value as RTRField::name().

• Custom field definitions added to the appendix_a are required to have a negative FID. TSS-based does not have this restriction.

• In TSS-based, field names can contain whitespace. In Marketfeed-based, however, they cannot. The simplest workaround is to replace the whitespaces with underscores on both infrastrucures. If they are absolutely needed, then write your application to use RTRField::longName() and put the full field name in the DDE acronym column of the appendix_a:

ACRONYM DDE ACRONYM FID RIPPLES TO FIELD TYPE LENGTH------- ----------- --- ---------- ---------- ------NEW_FIELD "NEW FIELD" -1 NULL ALPHANUMERIC 10

• Both dictionaries must at least know the FID definitions for all of the field names that will be published. If SFC does not have a FID definition for a field, it will throw it out. If the infrastructure cache does not have a FID definition for a field, it may also throw it out.

• The size of a price field is hardcoded to 17 bytes causing price fields which are larger than 17 bytes to be truncated. On Marketfeed-based this can be solved by modifying appendix_a. To increase the size while using a TSS-based dictionary, SFC provides the configuration variable *decimalSize to work around this issue. TSS-based format has an opaque data type that supports binary data for a fixed size. SFC translates that type to RTRFidDefinition::Binary.

SFC Developer’s Guide 292

Page 307: sfc

5 SFC IMPLEMENTATION DETAILS

However, the Marketfeed data format used by Triarch and RMDS is limited to a 182-character set. Binary fields in the appendix_a are actually base64 encoded in Marketfeed; RTRField’s setFromBinaryData() and binaryData() methods can be used to encode and decode binary data for all infrastructures.

• Page data in the Triarch and RMDS infrastructures is delivered as a stream of ANSI data. While SFC parses the ANSI data and makes it available in a logical model, sometimes status text messages also have ANSI escape sequences in them. SFC does not parse these ANSI escape sequences, so the text in processInfo events will still contain the sequences.

• When using TSS dictionary format, SFC now allows consumers access to the SEQ_NO FID. Previously SFC dropped this field. If it is necessary to have SFC automatically drop this field, set *dropSeqNo to True. *dropSeqNo is False by default and will only need to be changed in rare cases.

• When publishing to an RTIC(SASS2) infrastructure, SFC automatically create fields for "SYMBOL" and "Output Ticker Symbol". Those fields are populated with the RIC for the item. The configuration parameter *sendSymbolFields allows the publisher to disable the publishing of SYMBOL and Output Ticker Symbol fields. The default value for this configuration parameter is true for publishing SYMBOL and Output Ticker Symbol.

• When publishing chain over RTIC(SASS3) infrastructure, SFC configuration variable *enableNextChainHeaderAsString must be set to True; otherwise, the size of chain elements on the subscriber side would not be changed.

*enableNextChainHeaderAsString = True

• On the SASS3 protocol, SFC publisher can be configured to encode the published data to MF data format by setting the configuration variable *mfencoder to True.

5.5.2.1 Enumerations

ConsumersWhen using SFC with Marketfeed-based program, both enumerated and expanded values will be available for all enumerated fields. If the datafeed is expanding the enumerated fields upstream, SFC will not look up the enumerated value if the configuration variable srcExpandsEnumFields is set to True. The srcExpandsEnumFields configuration variable can be set on a per service basis.

SFC Developer’s Guide 293

Page 308: sfc

5 SFC IMPLEMENTATION DETAILS

TSS-based program expands all enumerations upstream and does not provide a way of looking up the original enumerated value. No RTRRTEnumeratedFields will be created by the TIB implementation of SFC. They will instead be of type RTRRTAlphanumericField.

For compatibility between the models, first check the type of the field. If it is enumerated, use RTRRTEnumeratedField::expandedValue(). Otherwise use RTRField::string() to access the value.

// RTRRTRecord & record;

if (record.hasFieldByName("RDN_EXCHID"){

RTRField *field = record.fieldByName("RDN_EXCHID");if (field->type() == RTRFidDefinition::Enumerated)

cout << ((RTRRTEnumeratedField *)field)->expandedValue();else

cout << field->string();}

PublishersPublishing enumerated fields presents some challenging tradeoffs. The issue centers around sending data in the format (either enumerated or expanded) that the consuming program expects.

• If the publisher will only be used in a single infrastructure, then it can use the format expected in that infrastructure.

• If the consumer is also an SFC-based program, then one of the consumer workarounds described above can be used.

• If the publisher will be publishing to consuming applications that cannot be changed or configured, then the publisher may need to add conditional code or configuration to change what it publishes in the infrastructure in which it is deployed.

The following code shows how to conditionally publish an enumerated field as either Enumerated or Alphanumeric:

// RTRRTRecordImpl & record;// RTRFidDb & fidDb;

RTRFidDefinition * fidDef = fidDb.defByName("RDN_EXCHID");if (fidDef){

SFC Developer’s Guide 294

Page 309: sfc

5 SFC IMPLEMENTATION DETAILS

char * farea = new char[fidDef->length() + 1];RTRRTField * fld;if (fidDef->type() == RTRFidDefinition::Enumerated){

fld = new RTRRTEnumeratedField(*fidDef, farea, 0,*fidDb.enumTableByName("RDN_EXCHID"));

fld->set("2", 1);// Note that only the enumerated value is set. The consumer// will be responsible for looking up the expanded value.

}else // RDN_EXCHID is Alphanumeric in TIB infrastructure{

fld = new RTRRTAlphanumericField(*fidDef, farea, 0);fld->set("NYS", 3);

}_record.putField(*fld);

}

The following table summarizes how enumerations are received for various infrastructures. In each row, the RDN_EXCHID field is being published. The value sent by the publisher is what will be sent through the infrastructure. The client values show what will be available through SFC. The f and ef variables are RTRRTField and RTRRTEnumeratedField, respectively. The value returned by string() is the value actually stored by SFC.

Infrastructure / FID definition type

Value sent by publisher

SFC consumer configuration Client values

RTIC/ Alphanumeric

Enumerated (2) Any f.string() = "2"

(works, but is not the value typically expected from TIB)

RTIC/ Alphanumeric

Expanded (NYS) Any f.string() = "NYS"

Table 5.5: Enumeration Summary by Infrastructure

SFC Developer’s Guide 295

Page 310: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.2.2 HintSFC allows system to identify data display format by determining hint which can be grouped into 3 forms as described in table 5.6.

Triach & RMDS / Enumerated

Enumerated (2) Default ef.enumeratedValue() = 2ef.expandedValue() = "NYS"ef.string() = "2"

Triach & RMDS / Enumerated

Enumerated (2) *srcExpandsEnum-Fields: true

Invalid configuration

Triach & RMDS / Enumerated

Expanded (NYS) Default ef.enumeratedValue() = 0ef.expandedValue() = ""ef.string() = "2"

(only string() returns a valid value)

Triach & RMDS / Enumerated

Expanded ( NYS) *srcExpandsEnums-Fields: true

ef.enumeratedValue() = 2ef.expandedValue() = "NYS"ef.string() = "2"

NOTE: Hint is only applicable to SFC consumer. There is no control for SFC publisher over hints, so SFC will automatically generate appropriate hint for each field when it is published.

Infrastructure / FID definition type

Value sent by publisher

SFC consumer configuration Client values

Table 5.5: Enumeration Summary by Infrastructure (Continued)

SFC Developer’s Guide 296

Page 311: sfc

5 SFC IMPLEMENTATION DETAILS

Table 5.6: Data Displaying

The data buffer size can be set by configuring the configuration variable *decimalSize of which the default value is 17. However, this buffer size must be reserved at least two digits for a sign string and a string termination. This configuration variable is applicable only with TSS data dictionary. See section 5.5.2 for purposes of this configuration variable.

SFC will display data in several ways, depending on a hint that comes with the data. The hint will determine displaying data format under several scenarios as described below. The buffer size used in the examples are 17.

Type of Data Displaying Hint Examples Data Display

Display in fraction form, divider specified by hint.

TSS_HINT_DENOM_2TSS_HINT_DENOM_4TSS_HINT_DENOM_8TSS_HINT_DENOM_16TSS_HINT_DENOM_32TSS_HINT_DENOM_64TSS_HINT_DENOM_128TSS_HINT_DENOM_256

123.5 +123 1/2+123 2/4+123 4/8+123 8/16+123 16/32+123 32/64+123 64/128+123 128/256

Display in floating point form by specified decimal

part digits.

TSS_HINT_DECIMAL_1TSS_HINT_DECIMAL_2TSS_HINT_DECIMAL_3TSS_HINT_DECIMAL_4TSS_HINT_DECIMAL_5TSS_HINT_DECIMAL_6TSS_HINT_DECIMAL_7TSS_HINT_DECIMAL_8TSS_HINT_DECIMAL_9

12.3456789 +12.3+12.35+12.346+12.3457+12.34568+12.345679+12.3456789+12.34567890+12.345678900

Display in original form. TSS_HINT_DENOM_NONETSS_HINT_32_PLUSand other types.

123.45 +123.45

SFC Developer’s Guide 297

Page 312: sfc

5 SFC IMPLEMENTATION DETAILS

Scenario 1. SFC will strictly follow the hint if the data buffer size is sufficient.

Table 5.7: Example of SFC Displaying Data Using Hint

Scenario 2. SFC will display data as hint, but the decimal part may be rounded up or rounded down depending on the available buffer size.

Table 5.8: Example of SFC Displaying Data by Truncating Decimal

Data Hint Display

123 TSS_HINT_DENOM_NONE +123

123 TSS_HINT_DECIMAL_9 +123.000000000

123.456 TSS_HINT_DENOM_NONE +123.456

123.456 TSS_HINT_DECIMAL_9 +123.456000000

123.4567 TSS_HINT_DECIMAL_3 +123.457

Data Hint Display

123456789 TSS_HINT_DECIMAL_9 +123456789.00000

12345678.90123 TSS_HINT_DECIMAL_8 +12345678.901230

1234567 TSS_HINT_DECIMAL_9 +1234567.0000000

1234567890123 TSS_HINT_DECIMAL_9 +1234567890123.0

12345678901234 TSS_HINT_DECIMAL_9 +12345678901234

123456789012345.678 TSS_HINT_DENOM_NONE +123456789012346

SFC Developer’s Guide 298

Page 313: sfc

5 SFC IMPLEMENTATION DETAILS

Scenario 3. SFC will display data in exponential form without hint associated when the buffer size is not sufficient for a whole number. This causes the data to be rounded up or rounded down in some cases.

Table 5.9: Example of SFC Displaying Data in Exponential Form

A log message will be generated when:

1. Data could not be displayed as hint. Displaying data as hint requires a larger buffer size than an allocated buffer size does. Message will be printed as "could not be displayed as hint.".

2. Truncation validation. Truncation process can be ceiling and floor. The validation will be performed in the following cases:

• Hint is defined as TSS_HINT_DENOM_NONE or TSS_HINT_32_PLUS.

• Data could not be displayed as hint. Truncation validation will be validated in scenario 1 as well.

Upon truncation validation event, message will be printed only when the data is rounded up or rounded down. Message will be printed as "it is rounded up." or "it is rounded down.". The severity level of log message is "warning".

Data Hint Display

1000000000000000 TSS_HINT_DENOM_NONE +1e+015

1000000000000000 TSS_HINT_DECIMAL_9 +1e+015

1234567890123456789 TSS_HINT_DENOM_NONE +1.23456789e+018

1234567890123456789 TSS_HINT_DECIMAL_9 +1.23456789e+018

1234567890123456.789 TSS_HINT_DENOM_NONE +1.23456789e+015

1234567890123456.789 TSS_HINT_DECIMAL_9 +1.23456789e+015

123456789987654321012 TSS_HINT_DENOM_NONE +1.2345679e+020

SFC Developer’s Guide 299

Page 314: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.3 Record TemplatesRecord templates provide a list of all of the fields in a particular record. The record template number is sometimes referred to as the field list number. In TSS-based dictionary format the record templates are defined in tss_records.cf and its supporting fields. In IDN, record templates are specified in a file commonly known as "Appendix D." "Field templates" is another name for the data dictionary or FID database, described in section 5.5.4.

The record templates in TSS and Marketfeed data dictionary formats may be different. This is usually not a concern because the key fields of interest are available on both infrastructures. However, this can be an issue when writing gateway applications between Triarch and RTIC/TSS or RTIC/TSS and RMDS.

RTRString * RTRRTRecord::recordTemplateNumber() provides access to the field list number from the Marketfeed header or the REC_TYPE field from a Rendezvous message. If these values are not set, this method will return a null pointer.

RTRRTRecordImpl::setRecordTemplateNumber( RTRString * ) is used by publishing applications to set the string of the record template number for a single record. This method is part of the RTRRTRecordImpl abstract interface and is applicable in TIB and SSL implementations. In the SSL implementation of SFC, this method uses the value to set the field list number that is published in the Marketfeed message header. In the TIB implementation this method sets the value that will be put in the REC_TYPE field of the published message.

While the methods for getting and setting the record template number are generic for SSL and TIB implementations, there are several infrastructure issues to consider:

• If the record template number is not available, a NULL pointer will be returned by recordTemplateNumber().

• Record templates are a legacy concept on Triarch. Very few components actually use them.

• For TSS the record template number must match a template in tss_records.cf and its supporting files. Otherwise it might not be cached.

• When a record template number is published, the RTIC will cache exactly the fields defined for the record template number. If fields are missing from the image, the TIC will populate those fields with empty values. If the publisher sends extra fields not in the template, the RTIC will throw them out.

SFC Developer’s Guide 300

Page 315: sfc

5 SFC IMPLEMENTATION DETAILS

• When record templates are used, the RTIC will never add or remove fields, even if another image is published. When record templates are not used, the RTIC will replace the item in the cache when a TIB_MSG_VERIFY (i.e. record resync) is received.

• REC_TYPE is required when using the record publishing model to send contributions on a Rendezvous network.

• Record template numbers have different values on TSS and Marketfeed data dictionaries. Since most Marketfeed data dictionary do not use fixed record templates, the TSS data dictionary values can be used.

Due to these issues, SFC’s TIB implementation has an additional mechanism for controlling when record template numbers are published. First, the generic record publishing code can be written to always publish record template numbers. Then record template number publishing can be controlled for a service either programmatically or through configuration.

RTRRTFieldToTIBRecordService::setUseTemplates();RTRRTFieldToTIBRecordService::clrUseTemplates();

setUseTemplates() enables publishing of the REC_TYPE field, and clrUseTemplates() disables publishing of that field, regardless of whether the setRecordTemplateNumber() method was used. If the template behavior is not set programmatically, the *useTemplates configuration variable can be used. That configuration variable defaults to true. Setting *useTemplates to false is equivalent to calling clrUseTemplates().

5.5.4 Data DictionaryData dictionary is a term that is often used for field templates or FID database. SFC uses the abstract class RTRFidDb for data dictionaries. Two key implementations of this interface are RTRSSLFidDb and RTRTIBFidDb. See the SFC Reference Manual for information on these classes.

Triarch and RMDS use the Marketfeed data dictionary that is specified in the appendix_a and enumtype.def files. The RMDS infrastructure also supports downloading of data dictionary files from the P2PS or RTIC, with a few limitations. Moreover, RMDS(RTIC) also supports the TSS data

NOTE: If the record template number is only being used to distinguish between different types of records and is not being used to define an exact set of fields for a record template, then the RDNDISPLAY field can probably be used. This field is typically used to select a display template, and it is available from all infrastructures.

SFC Developer’s Guide 301

Page 316: sfc

5 SFC IMPLEMENTATION DETAILS

dictionary that is loaded from tss_fields.cf, tss_records.cf, and supporting files. Many data discrepancies between infrastructures can be linked to data dictionary differences.

5.5.4.1 Sharing a Data DictionaryIf the data dictionary is not explicitly created and passed to the service in the constructor, SFC will create the correct type of data dictionary. The service pool factory classes also create the correct type of data dictionary.

The application has the option of creating the data dictionary directly and passing it to the service in the constructor. This is typically done for one of the following reasons:

• to share a data dictionary between a publishing and subscribing service

• to share a data dictionary between two subscribing services that have two different connections. Note that a service pool factory can be used to share the FidDb between services on the same connection.

• to pass a data dictionary that was downloaded from one Rendezvous session to a publishing service on a different session. This is necessary when the TIC or RTIC’s configuration file has different values for RV3_PUBLISH_SERVICE, RV3_PUBLISH_NETWORK, and RV3_PUBLISH_DAEMON than it does for RV3_OUTPUT_SERVICE, RV3_OUTPUT_NETWORK, and RV3_OUTPUT_DAEMON.

The application also has three options to handle the data dictionary classes:

1. RTRSSLFidDb::load() can be used to load the data dictionary from file or download from the network (P2PS) for RMDS.

2. RTRFileFidDb::load() can be used to load the data dictionary from the local appendix_a and enumtype.def files for Triarch and RMDS.

3. RTRTIBFidDb::load(FidDbType = Marketfeed, FidDbLocation = Default) can be used to load the data dictionary from file or download from the network for RMDS.

The *fidDbType configuration variable can be used to override the type of data dictionary used for a service. If the variable is set to "Marketfeed", the dictionary will be based on an appendix_a and enumtype.def and the default location will be files. If the variable is set to "TSS", the dictionary will be based on a tss_fields.cf and the default location will be the network.

The FID database location can also be controlled through the *fidDbLocation configuration variable. If the variable is set to "file", the data dictionary will be loaded from files. If the variable is set to

SFC Developer’s Guide 302

Page 317: sfc

5 SFC IMPLEMENTATION DETAILS

"network", then the data dictionary will be downloaded from the P2PS or RTIC. See Appendix C.2.3 and Appendix E.4 for information on how to configure the infrastructure to support data dictionary download. If the *fidDbLocation variable is not set, the default location for that type of data dictionary will be used. For TSS, the default location is network. For Marketfeed, the default location is file.

When the *fidDbLocation is "file" for a TSS data dictionary, the fid_file_path configuration variable must be set to the fully qualified filename of tss_fields.cf . Also, the cfile_path environment variable must include the directory in which tss_fields.cf and its support files are found. The fid_file_path config variable and the cfile_path environment variable should be set using forward slashes (e.g. cfile_path = /var/tib; *fid_file_path: /var/tib/tss_fields.cf).

If the data dictionary is loaded from files, the *fid_file_path and *enum_file_path configuration variables can be used to set the location. The priority for determining the data dictionary location is as follows:

1. filenames passed in constructor or load() methods

2. filenames found in *fid_file_path and *enum_file_path

3. the current working directory

4. \\HKEY_LOCAL_MACHINE\SOFTWARE\Reuters\Triarch\MASTER_FID_FILE and \\HKEY_LOCAL_MACHINE\SOFTWARE\REuters\Triarch\ENUM_FILE registry entries (Win32 only)

5. MASTER_FID_FILE and ENUM_FILE environment variables

In order to load both tss_fields.cf and appendix_a from files specified in configuration, configuration class IDs should be used. For example:

*fidDbLocation: fileFileFidDB.fid_file_path: /var/triarch/appendix_aFileFidDB.enum_file_path: /var/triarch/enumtype.defTIBFidDB.fid_file_path: /var/tib/tss_fields.cf

5.5.4.2 Infrastructure IssuesRTRSSLFidDb and RTRFileFidDb should always be used with the SFC’s SSL implementation. A RTRTIBFidDb should always be used with SFC’s TIB implementation. Using a RTRFileFidDb with the RMDS infrastructure may prevent data from being parsed correctly.

While the SFC model supports a separate RTRFidDb for each service, the TIBMsg parser used for RMDS and TIB market data uses two global data dictionaries. One of these data dictionaries is TSS-

SFC Developer’s Guide 303

Page 318: sfc

5 SFC IMPLEMENTATION DETAILS

based and the other is Marketfeed-based. When a RTRTIBFidDb is loaded, one of the two global data dictionaries is loaded. If another RTRTIBFidDb of the same type is loaded, the data dictionary in the parser is replaced, and services based on the first data dictionary will begin to use the second for parsing.

5.5.4.3 ExamplesThe examples in this section show how to use the RTRTIBFidDb::load() methods and service constructors to share data dictionaries. The examples may use some of the following includes and declarations:

#include "rtr/objid.h" // RTRObjectId #include "rtr/tibrtsvc.h" // RTRTIBRTRecordService #include "rtr/tfdb.h" // RTRTIBFidDb#include "rtr/tconnect.h" // RTRTIBConnection #include "rtr/fldtossl.h" // RTRRTFieldToSSLRecordService#include "rtr/fldtotib.h" // RTRRTFieldToTIBRecordServiceRTRObjectId appId("appId");RTRRTRecordService * subservice;

Triarch RMDS/RTIC/TSS based RMDS/P2PS

RMDS/RTIC/Marketfeed

based

Class Name RTRSSLFidDb, RTRFileFidDb

RTRTIBFidDb RTRSSLFidDb, RTRFileFidDb

RTRTIBFidDb

Type Marketfeed TSS Marketfeed Marketfeed

Possible Loca-tions

file network, file network, file network, file

Default Location file network file file

Default File-name(s)

appendix_a, enumtype.def

tss_fields.cf appendix_a, enumtype.def

appendix_a, enumtype.def

Enumerations yes no yes yes

Table 5.10: Data Dictionary Summary by Infrastructure

SFC Developer’s Guide 304

Page 319: sfc

5 SFC IMPLEMENTATION DETAILS

RTRRTRecordServiceImpl * pubservice;RTRTIBConnection * c;RTRTIBFidDb * fidDb;

1. RMDS local publishing and subscribing services, Marketfeed-based data dictionary from file

c = new RTRTIBConnection(appId, "connection");c->connect();fidDb = new RTRTIBFidDb(appId, c);fidDb->load(); // Marketfeed, File is defaultsubservice = new RTRTIBRTRecordService(appId, "IDN", *fidDb, *c);pubservice =new RTRRTFieldToTIBRecordService(appId, "PUB", *fidDb, *c);

2. RMDS local publishing and subscribing services, Marketfeed-based data dictionary from network

connection = new RTRTIBConnection(appId, "connection");c->connect();fidDb = new RTRTIBFidDb(appId, c);fidDb->load(RTRTIBFidDb::Marketfeed, RTRTIBFidDb::Network);subservice = new RTRTIBRTRecordService(appId, "IDN", *fidDb, *c);pubservice =new RTRRTFieldToTIBRecordService(appId, "PUB", *fidDb, *c);

3. RMDS local publishing and subscribing services, TSS-based data dictionary from file

c = new RTRTIBConnection(appId, "connection");c->protocol(RTRTIBConnection::SASS2); //SASS3 is also valid if

//using a RTIC(SASS3)fidDb = new RTRTIBFidDb(appId, c);fidDb->load(RTRTIBFidDb::TSS, RTRTIBFidDb::File);subservice = new RTRTIBRTRecordService(appId, "RSF", *fidDb, *c);pubservice = new RTRRTFieldToTIBRecordService(appId, "PUB", *fidDb, *c);

4. RMDS local publishing and subscribing services, TSS-based data dictionary from network

c = new RTRTIBConnection(appId, "connection");c->protocol(RTRTIBConnection::SASS2); //SASS3 is also valid if

//using a RTIC(SASS3)fidDb = new RTRTIBFidDb(appId, c);fidDb->load(RTRTIBFidDb::TSS); // Network is default for TSSsubservice = new RTRTIBRTRecordService(appId, "RSF", *fidDb, *c);pubservice = new RTRRTFieldToTIBRecordService(appId, "PUB", *fidDb, *c);

5. Sharing data dictionary between a RMDS service and Triarch service.

SFC Developer’s Guide 305

Page 320: sfc

5 SFC IMPLEMENTATION DETAILS

Note that the FidDb is loaded from a file. Also note that a RTRTIBFidDb is used, not a RTRFileFidDb. This necessary because RTRTIBFidDb has the side-effect of correctly initializing the RMDS parser.

c = new RTRTIBConnection(appId, "connection");c->connect();fidDb = new RTRTIBFidDb(appId, c);fidDb->load(); // Marketfeed, File is defaultsubservice = new RTRTIBRTRecordService(appId, "IDN", *fidDb, *c);pubservice =new RTRRTFieldToSSLRecordService(appId, "PUB", *fidDb, *c);

6. Downloading a data dictionary when the RTIC’s RV3_OUTPUT_* and RV3_PUBLISH_* parameters or the RTIC’s RV2_OUTPUT_* and RV2_PUBLISH_* parameters are set.

const char * outservice = "7501";const char * pubservice = "7502";c = new RTRTIBConnection(appId, "connection", outservice,"","");c->connect();fidDb = new RTRTIBFidDb(appId, c);fidDb->load(RTRTIBFidDb::TSS); // Network is default for TSSpubservice =

new RTRRTFieldToTIBRecordService(appId, "PUB", *fidDb, pubservice,"","");

Note that for this setup, the SFC configuration file must have the following entry:

TIBDistribution*pingInterval : 0

or

TIBDistribution*enablePingSubscription : false

5.5.4.4 Configuration*fid_file_path - Default location of appendix_a. This configuration variable is also used for loading tss_fields.cf from a local file. To set both appendix_a and tss_fields.cf filenames through configuration, FileFidDB and TIBFidDb Class IDs must be used. When loading tss_fields.cf, the cfile_path environment variable must also be set to include the directory with the supporting .cf files. See section 5.5.4.1 for details.

*enum_file_path - Default location of enumtype.def.

*fidDbInterval - If downloaded RTRSSLFidDb or RTRTIBFidDb did not load within this time period (in seconds), it will be retried. The default value is 20.

SFC Developer’s Guide 306

Page 321: sfc

5 SFC IMPLEMENTATION DETAILS

*fidDbLocation - Has no default. Can be set to "network" or "file" for RTRSSLFidDb or RTRTIBFidDb. If it is not set, the default value for that infrastructure will be used.

*fidDbType - Has no default. Can be set to "Marketfeed" or "TSS" for RTRTIBFidDb. If it is not set, the default value for that infrastructure will be used.

5.5.5 Data and Connection StatusAll SFC applications can monitor the status of items and services by implementing the appropriate record client, page client, service client, and connection client interfaces. Stale notifications are usually received through a processStale event. Recovery conditions are received through itemResync, itemNotStale, serviceSync, or connectionConnected events. When SFC logging is enabled, the log file may also show some status events.

In the RMDS infrastructure, status information is primarily at the item level. Services are considered up as long as the connection is up and the data dictionary is complete.

5.5.5.1 Data Status with RTICIn SASS3 infrastructures, the RTIC has a mechanism for detecting when broadcast publishers die. They expect a message from the publisher every so often. If no message is received within the timeout interval, all items from that publisher are marked stale and stale events are broadcast for all subscribers. For this mechanism to work:

• the RTIC must be version 10.1 or later.

• the RTIC must be configured. See Appendix D.4 and Appendix E.4 for details on configuring the RTIC.

• the SFC local publisher must be configured with a unique numerical ID using the *groupId configuration variable. The groupId can be configured on a per service basis. It is recommended to configure the groupId to be > 1000 to avoid conflict with MDH services.

• the SFC local publisher’s *pingInterval must be less than FEED_FAIL_TIMEOUT configured in the RTIC.

When RMDS consumers request non-cached items from a broadcast service and the infrastructure component has BCAST_NAK set to true, the item will be marked as stale. Applications will receive stale or info events, and the request will be periodically retried by SFC. In previous versions of SFC, the item would be marked as inactive. To maintain this previous behavior, set the *notFoundAsRecoverable configuration variable to false.

SFC Developer’s Guide 307

Page 322: sfc

5 SFC IMPLEMENTATION DETAILS

When sourcing data from an RMDS service (SASS2/SASS3), an item that is in a stale state will transition to a not stale state when an update which record status equals to OK is received and the configuration variable *allowUpdatesToChangeStaleToOk is set to true. On the other hand, an item that is in a not stale state will transition to a stale state when an update which record status equals to STALE_VALUE is received.

5.5.5.2 Rendezvous Advisory MessagesThe RMDS infrastructure can also receive status information through Rendezvous advisory messages. Rendezvous advisory messages include RVD connection information such as disconnections, license expiration warnings, and RVD overflows. The overflows could occur because the subscriber client is too slow or a publisher on the network is too fast. This information is sent to SFC applications through events on the RTRMDConnectionClient interface.

The _RV.WARN.SYSTEM.EVENTLOOP.STARVATION advisory indicates that the application is not releasing the thread of control fast enough in callback functions. This event can occur if an application is temporarily suspended or is too slow.

The _RV.ERROR.SYSTEM.CLIENT.SLOWCONSUMER advisory indicates that the application is too slow. When this is received, the connection will be closed, making all market data services and items stale. The connection will be re-established after waiting for 20 seconds. The reconnect delay can be changed using the *slowconsumer_interval configuration variable. If the reconnect interval is less than or equal to zero, the connection will not be terminated. After the connection recovers, the Items will automatically be re-requested. See section 5.4.4 for information on when items will be re-requested. If this advisory is frequently logged, the application should request less data or should be run on a faster machine.

The _RV.ERROR.SYSTEM.CLIENT.FASTPRODUCER advisory indicates that the application is publishing too fast. This is a warning message only, although a fast producer may lead to a _RV.ERROR.RV.DATALOSS.OUTBOUND.

The _RV.ERROR.SYSTEM.CLIENT.NOMEMORY indicates that the application ran out of memory. This could result in serious errors and could potentially crash the application. SFC will close the connection, but will not try to reconnect because the state of the application could be corrupt. If this event is received, the application should request less data or should be run on a machine with more memory.

The _RV.ERROR.SYSTEM.LICENSE.EXPIRE indicates the RVD’s license has expired. SFC will close the connection, but will not try to reconnect. The application should be restarted when the RVD has been restarted with a new license.

SFC Developer’s Guide 308

Page 323: sfc

5 SFC IMPLEMENTATION DETAILS

_RV.ERROR.RV.DATALOSS.INBOUND advisories indicate packets have been lost and cannot be recovered. In this case, it is not possible to determine the effect of the loss, so SFC logs this information and initiates a disconnect event and reconnect after a specified time interval. The time interval is specified through configuration of *dataLossInboundInterval. The default for this interval is 0. A time interval of less than or equal to 0 disables the disconnect and reconnect functionality.

_RV.ERROR.RV.DATALOSS.OUTBOUND advisories indicate packets have been lost and cannot be recovered. In this case, it is not possible to determine the effect of the loss, so SFC logs this information and initiates a disconnect event and reconnect after a specified time interval. The time interval is specified through configuration of *dataLossOutboundInterval. The default for this interval is 0. A time interval of less than or equal to 0 disables the disconnect and reconnect functionality.

5.5.5.3 SSL Warning MessagesIn the SSL log file (see section 5.4.7), warning messages may occur if the publisher is sending data too quickly.

A message similar to:

file = src/ssl/edapi.c, line = 7802, Channel = 1send_it: No Resources: Event Posting failed for Event 45.

or

ssl_errno = 10 on channel = 1<src/ipc/sipcsrvr.c:3206> sipc46DataBuffer() failed, the output buffer may need to be flushed

sipc_errno = 4 sys_errno = 0file = src/ssl/edutils.c, line = 4082, Channel = 1ssl_GetMsgBuffer: No Resources: Failed Getting Buffer for Channel 1.

indicates that sending the data failed and that data may have been lost. The application can increase the number of output buffers used by changing the sslapi.cnf configuration variable *numOutputBuffers. Increasing the value from the default uses more memory. See Appendix B.6.3.16 for details on the configuration variable. For best performance results thorough load testing is encouraged.

5.5.5.4 Status Event NormalizationIn the TIB implementation, SASS3, and SASS2 status messages are normalized to the SFC market data event model (Sync, Resync, Stale, Inactive, etc.). A variety of SASS messages are mapped to

SFC Developer’s Guide 309

Page 324: sfc

5 SFC IMPLEMENTATION DETAILS

stale events. These events fall into two categories: those that SFC will try to recovery (for example CACHE_FULL) and those that SFC will let the infrastructure recover (for example TMF_DOWN).

In most circumstances, SFC’s default mapping behavior is acceptable. In some environments, the event mapping needs to be changed. The following configuration can be used to make some large grain changes to how status codes fall into those categories:

*forceSFCDrivenRecovery : False*forceInfrastructureDrivenRecovery : False

When *forceSFCDrivenRecovery is set to True, SFC will close all stale items and will re-request the items. While this could speed up recovery in some circumstances, it could also lead to network request "storms" if hundreds of applications are configured this way. In case RTIC is down, SFC will wait until RTIC is up and then re-request the items.

When *forceInfrastructureDrivenRecovery is set to True, SFC will not re-request any stale items. This can alleviate the network request load in complete system recovery situations. However, in some circumstances, the items may never recover. This is especially true in the case of the SASS2 protocol.

If these configuration variables need to be set, then typically only one of them is set. These configuration variables do not affect connection recovery or request queue timeouts.

5.5.6 Discovery

5.5.6.1 Service Pool FactoryOn Triarch, services can be dynamically discovered, so the RTRSSLServicePoolFactory automatically populates pools with services that are requested from it. The RTIC(SASS2) infrastructure does not have a mechanism for broadcasting the names and types of all available services, so services must be added to the RTRTIBServicePoolFactory manually or through configuration. With the SASS3 protocol (RMDS infrastructure) services are dynamically discovered and automatically populate RTRTIBServicePoolFactory.The dynamic behavior of the SSL and RMDS implementations can be stopped (so it more closely mimics the RTIC(SASS2) implementation) by setting the following configuration variables:

*enableDynamicRTRecordServices: false*enableDynamicPageServices: false*enableDynamicRTPageServices: false*enableDynamicTimeSeriesServices: false*enableDynamicInsertServices: false

SFC Developer’s Guide 310

Page 325: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.6.2 Service Provider DiscoveryA special subject (<SERVICENAME>.QUERY.SERVICE.STATUS) is used by the SASS3 protocol implementation to dynamically determine whether a service to publish to or consume from is an RTIC(SASS3). It is also used to distinguish page and record services and to determine the default sector used by the RTIC. In some environments, this mechanism will fail. In particular, the mechanism will not work with:

• DTIC for RMDS (RDTIC)

• SSL Adapter-based programs using RTIC local publishing (sslrv.cnf configuration setting *rticInsertMode: Publish)

• some RTIC configurations that filter out the QUERY "sector" or the STATUS "exchange."

In these circumstances, the mechanism must be disabled with the following configuration:

*<SERVICENAME>*serviceProvider : RTIC ! could also be TIC

"RTIC" would be used for an RTIC(SASS3) and an RDTIC. "TIC" should be used for an RTIC(SASS2).

When the provider discovery mechanism has been disabled, all services dynamically discovered through the SASS3 protocol will be assumed to be record services. Also, setting *serviceProvider to RTIC will make the default sector for subjects be "ANY" and setting *serviceProvider to TIC will make the default sector for subjects be "REC". To override the default values for "Record" and "ANY" or "REC, the following configuration can optionally be used:

*<SERVICENAME>*dataType : Record ! set to "Page" for page services*<SERVICENAME>*defaultSector : ANY !! set to *sectorName from rtic.cf

! or set to the SECTOR from the tic.cf

If dataType is not set for page services, they will be assumed to be record services.

When the service provider discovery is used (*serviceProvider is not set), SFC will periodically retry the QUERY subject until a response is received. The following configuration can be used to configure how long SFC will wait before retrying:

*serviceStatusInterval : 15

SFC Developer’s Guide 311

Page 326: sfc

5 SFC IMPLEMENTATION DETAILS

The *serviceProvider configuration variable controls the defaults of several other configuration variables. The following table shows the relationship between various configuration variables.

5.5.7 Market Data Item Names and TIB Subject NamesReuters Instrument Codes (RICs) are used for "symbol()" of SFC market data item names. For more information on RICs, see the Selectfeed Plus User Guide.

The TIB implementation of SFC automatically maps RICs into four-part Rendezvous subject names. The same mapping algorithm is used in the SSL Adapter. Most SFC applications do not need to be concerned with the four-part names. However if SFC applications will interact with non-SFC applications over the Rendezvous network, it is helpful to know how SFC uses the four-part naming scheme. These names take the format:

<serviceName>.<sector>.<itemSymbol>.<exchange>

*serviceProvider or dynamic discovery

valueEquivalent configuration Other values controlled

RTIC *defaultSector: ANY*sectorList: ANY*fidDbLocation: file*fidDbType: Marketfeed*newsEnabled: false

Page previous char: -Page next char: +DACS Locks generated: noRenamable pages as snapshots: noPage parser: ANSI

TIC *defaultSector: DFLT*sectorList: REC, PAGE, LINK*fidDbLocation: network*fidDbType: TSS*newsEnabled: true

Page previous char: pPage next char: nDACS locks genereated: yesRenamable pages as snapshots: yesPage parser: TIBMsg

Table 5.11: Configuration relationships

<serviceName> the name of the service (in SFC)

<sector> REC, LINK, PAGE, BRCAST, INTERACTIVE, or ANY

SFC Developer’s Guide 312

Page 327: sfc

5 SFC IMPLEMENTATION DETAILS

The first, third and fourth parts of the name can be determined from the SFC service name and the market data item name. The sector, however, must be guessed. On the client side, SFC takes its best guess (based on the service type and the RIC). If that guess does not work, it cycles through the other sectors. Table 5.12 shows some examples of the four-part names that SFC creates from the service names and RICs.

Sector selection is slightly different with an RMDS infrastructure. When a consuming SFC application accesses data provided by the Market Data Hub through an RTIC, it will always use the sector from service provider discovery (see section 5.5.6.2), which is typically "ANY". SFC local publishers, publishing on the Rendezvous portion of an RTIC SASS3 infrastructure, will always use the "ANY" sector by default. In RTIC/SASS2 infrastructure, it will always guess which sector should be used for the publishing symbol. The sector can possibly be "REC", "LINK", "PAGE" and "BRCAST" which depends on the publishing symbol.

<itemSymbol> base part of the symbol name

<exchange> suffix of the symbol name

Service name RIC Rendezvous name

RSF IBM.N RSF.REC.IBM.N

RSF IBM RSF.REC.IBM.NaE

RSF 0#.DJI RSF.LINK.0#^DJI.NaE

RDF .DJI RDF.REC.^DJI.NaE

RSF .AV.O RSF.LINK.^AV.O

RDF 1#.AV.O RDF.LINK.1#^AV.O

TELERATE 12 TELERATE.PAGE.12.NaE

RSF WRLD RSF.PAGE.WRLD.NaE

RSF NEWS2K_HL RSF.BRCAST.NEWS2K_HL.NaE

Table 5.12: Mapping SSL RICs to Rendezvous 4-part Subject Names

SFC Developer’s Guide 313

Page 328: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.7.1 RIC to Subject MappingThe SFC interface is standardized on the Reuters Instrument Code (RIC) naming scheme which combines the <instrument> name and <exchange> into a single "symbol” and uses other special character combinations to define special instruments like chains. For example, instrument "IBM” from the NYSE exchange is published with a symbol name of "IBM.N”. The base record for the chain of records that provide the volume leaders on the NASDAQ exchange is ".AV.O”. The instrument "IBM" which is not from any exchange (i.e. <exchange> is "NaE") is published simply as "IBM."

Furthermore, the <serviceName> is determined by the service to which a record "belongs".

In order to properly map the SFC symbol name and serviceName into a valid 4-part subject name, the TIB publishing service implementation will parse out the <exchange> from the record’s symbol name and will apply a mapping algorithm to determine the <sector> for the given <instrumentName> and <exchange>. This algorithm is encapsulated in the default implementation of the RTRTIBCustomizer class.

SFC Developer’s Guide 314

Page 329: sfc

5 SFC IMPLEMENTATION DETAILS

Figure 5.1: Sector Guessing

Determine theSector

Is this the firsttry?

1st char is'n' or 't'?

'.' appears initem twice?

itemcontains '#'?

1st char is 'd'?

contains '/', butnot 1st char?

item length > 4and alphanumeric?

item ends with "X="?

sector = REC

sector = LINK

sector = PAGE

sector =BRCAST

Done

item starts with"NEWS2K_"?

1st char '.' or all charsbefore '.' are numeric?

YesNo

Yes

Yes

No

Yes

YesYes

NoUse the nextsector in list

sector = REC

sector = PAGE

sector = PAGE

sector = LINK

sector = LINKYes

Yes

Yes

No

No

No

No

No

No

No

SFC Developer’s Guide 315

Page 330: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.7.2 Default Customizers

Default Record Subscription Customizer for RTIC/SASS2The default record subscription customizer for RTIC/SASS2 uses an algorithm to guess the initial sector. If this subject fails it will iterate through a list of additional guesses.

To change the list of guesses for sectors, *sectorList must be defined in the configuration file. This configuration variable allows the client to set up a sequence of sectors (e.g. *sectorList: LINK, PAGE, REC). SFC will use the sector names in the order specified in the sector list. News subject handling is described in section 5.5.7.6.

This customizer can use subject map files for recording. The subject map files contain mappings from RIC names to subject names. If local or global subject map files are specified and exist, they are read at startup and are used to pre-load RIC to subject mappings. The global subject map file is a read-only file. The local subject map file is a writable file. If SFC guesses the wrong subject for a RIC, the RIC and its correct subject are written to the local subject map file. This will prevent SFC from guessing incorrectly in the future. There are default subject map files, so that feature is disabled by default. The *globalSubjectMapFile and *localSubjectMapFile configuration variables can be used to specify the map files.

SFC's subject map file has the same format as the one used by SSL Adapter. The following is an example of contents from a subject map file:

1.AV.PA LINK.1^AV.PA0001.HK REC.0001.HK

The default record customizer has the following configuration.

• *sectorList - A list of sectors for the default record customizer to try after the initial guess (in the order of the list).

• *localSubjectMapFile - A local file that the default record customizer uses to record RIC to subject mappings that were not guessed correctly on the first try. The customizer can also read from this file for all the correct subject mappings for its use. This file is disabled by default.

• *globalSubjectMapFile - A read-only file that the default record customizer reads for correct RIC to subject mappings. This file is not changed by the customizer.

• *subjectMapSize - Specify the size of the hash table for the subject map.

• *number_of_items - Specify the size of the hash table for RTRServiceCustomizer

SFC Developer’s Guide 316

Page 331: sfc

5 SFC IMPLEMENTATION DETAILS

Other Default CustomizersThe default record publishing customizer for RTIC employs the same algorithm that is used by the SFC record subscriber for its initial guess. This customizer also supports reading subjects from the local and global subject map files, but it does not record subjects to the local subject map file. A publishing customizer does not retry because its first subject is always assumed to be correct. If the publishing customizer is changed, all subscription applications should be changed to use the same customizer to ensure they can produce the same RIC to subject mapping.

The default page customizer for RTIC(SASS2) does not retry or record. It always uses the PAGE sector, unless the default sector is overridden in configuration or programmatically.

The default customizer for RMDS subscribers and publishers does not retry or record. It always uses the sector downloaded from the RTIC, unless the setDefaultSector() method or the *serviceProvider or *defaultSector configuration variables are used. If the *serviceProdiver configuration variable is set to RTIC, the sector will default to "ANY".

The default customizer for RMDS insert services does not retry or record. It always uses the "ANY" sector, unless the setDefaultSector() method or the *dataProvider or *defaultSector configuration variables are used.

5.5.7.3 Setting defaultSector to "."When the default customizers do not satisfy the needs of an application, SFC has a simple way for applications to request subject names. If the default sector is set to "." (either through setDefaultSector() or *defaultSector) then the SFC will use a simplified subject mapping scheme. SFC will still use the service name as the first part of the subject name. The item name will be used as-is for the rest of the the subject name. For example, with service RDF and record item name REC.IBM.N, the subject will be RDF.REC.IBM.N. For record item name ANY.IBM.N, the subject will be RDF.ANY.IBM.N.

Setting the defaultSector to "." eliminates the need to write a RTRTIBCustomizer (described in section 5.5.7.4) for most applications. However, it has a couple of disadvantages related to infrastructure portability and migration:

1. Applications written to request records using the last three parts of the subject name will only work with the TIB implementation. The records will not exist on Triarch.

2. Sector names differ between RTIC/SASS2 and SASS3 infrastructures, so applications written to request REC.IBM.N for an RTIC(SASS2) infrastructure will not work with RTIC(SASS3), which would require ANY.IBM.N.

SFC Developer’s Guide 317

Page 332: sfc

5 SFC IMPLEMENTATION DETAILS

Since page services have simpler sector schemes (i.e. its either PAGE or ANY), the default sector of "." is only supported for record subscription and publishing services. The *defaultSector configuration variable can still be used with page services to set the actual sector.

5.5.7.4 Overriding the TIB CustomizerIn cases where the default mapping algorithm does not produce the appropriate 4-part subject name, the application programmer may create a subclass of RTRTIBCustomizer to override methods in the RTRTIBCustomizer class to provide the name mapping required by the application. To do this, the programmer writes a new class that inherits from RTRTIBCustomizer and re-implements one of the public methods. The RTRTIBCustomizer base class provides default implementations for all methods, so only some of the methods must be overridden in the customizer subclass. This new customizer can then be given to the service using the setTIBCustomizer() method on RTRTIBRTRecordService, RTRTIBPageService, or RTRRTFieldToTIBRecordService. Since the customizer is set right after the service is constructed, the TIB implementation specific code can be in one place, and the rest of the application can use the generic RTRRTRecordService.

The RTRTIBCustomizer::makeSubject() method is called by the SFC publishing service to map a given service name and record symbol into a valid 4-part subject. To do this, it first calls the RTRTIBCustomizer::getSectorForSymbol() which parses the SFC symbol to find the proper sector value. Then the RTRTIBCustomizer::getExchangeForSymbol() method is called to determine the exchange value. See the SFC Reference Manual for more information about RTRTIBCustomizer methods. Figure 5.2 shows how and when the methods are called in a RTRTIBCustomizer.

A user-defined customizer may override one or all of these methods to modify the mapping algorithm and ensure the expected TIB subject is published.

For simple subject customization, a RTRTIBCustomizer is not needed. RTRTIBRTRecordService, RTRTIBPageService, and RTRRTFieldToTIBRecordService have setDefaultSector() and setDefaultExchange() methods along with defaultSector and defaultExchange configuration variables to which the sector and exchange portions of the subject can be fixed.

SFC Developer’s Guide 318

Page 333: sfc

5 SFC IMPLEMENTATION DETAILS

Figure 5.2: RTRTIBCustomizer Usage

SFC Developer’s Guide 319

Page 334: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.7.5 Next and Previous Page NamesIn Triarch and RMDS, page services typically append a ’+’ to indicate the next page and a ’-’ to indicate the previous page. In RTIC(SASS2), page services use ’n’ for next and ’p’ for previous. The SSL implementation requires + and -, but the TIB implementation will automatically map n, p, +, and - to the correct character for the RMDS infrastructure.

While SFC maps n, p, +, and -, it also provides configuration for overriding this behavior. The follow configuration entries show how to additionally map x to next and y to previous.

*nextChars : n+x*prevChars : p-y

5.5.7.6 News Headlines

N2_UBMS is a special RIC in the RMDS and Triarch infrastructures to deliver news headlines, alerts, and corrections. In the TIB infrastructure this data is typically delivered in seven separate subjects. For a service RSF, these subjects would be:

RSF.BRCAST.NEWS2K_ALERT.NaERSF.BRCAST.NEWS2K_HL.NaERSF.BRCAST.NEWS2K_SUB_HL.NaERSF.BRCAST.NEWS2K_CORRECT.NaERSF.BRCAST.NEWS2K_CORECTD.NaERSF.BRCAST.NEWS2K_DELETE.NaERSF.BRCAST.NEWS2K_EXPIRE.NaE

For the TIB infrastructure, C++ Edition supports mapping the single N2_UBMS subject to the seven TIB subjects. This allows SFC applications to request N2_UBMS from any infrastructure. When the application subscribes to N2_UBMS, SFC will subscribe to each of seven news subjects. Subject-based entitlement checks will be performed on each of the TIB news subjects. Data from any of those subjects will be forward to clients of the N2_UBMS record.

N2_UBMS mapping is enabled by default, but it can be disabled by setting the *newsEnabled configuration variable to false. The *newsSymbol configuration variable can be used to change the application requested RIC from N2_UBMS.

When forwarding news subjects to the N2_UBMS record, SFC maps the subject to a numeric value stored in the DSPLY_NAME field. The mapping can be configured using the *newsInstrumentList.

NOTE: This feature is deprecated since SFC 4.5.1.L3 which dropped support for TIB infrastructure.

SFC Developer’s Guide 320

Page 335: sfc

5 SFC IMPLEMENTATION DETAILS

Applications using the TIB infrastructure still have the option of subscribing directly to the seven news RICs: NEWS2K_ALERT, NEWS2K_HL, NEWS2K_SUB_HL, NEWS2K_CORRECT, NEWS2K_CORECTD, NEWS2K_DELETE, and NEWS2K_EXPIRE.

The *newsSectorList configuration variable provides a list of sectors that the default record customizer for TIB uses with news subjects. The *newsPrefix configuration variable is used to determine which subjects use *newsSectorList and which use the *sectorList.

News configuration has the following defaults:

*newsInstrumentList: NEWS2K_ALERT.NaE 1, NEWS2K_HL.NaE 2, NEWS2K_SUB_HL.NaE 3, NEWS2K_CORRECT.NaE 4, NEWS2K_CORECTD.NaE 5, NEWS2K_DELETE.NaE 7,NEWS2K_EXPIRE.NaE 8

*newsSectorList: BRCAST, INTERACTIVE*newsPrefix: NEWS2K_*newsSymbol: N2_UBMS*newsEnabled: true

5.5.7.7 ConfigurationThe complete list of customizer configurations is shown below with the default values. All values can be configured on a per service basis.

The default record subscription customizer for TIB has the following configuration:

*sectorList: REC, PAGE,LINK*newsSectorList: BRCAST,INTERACTIVE*newsPrefix: NEWS2K_

The default record subscription and publishing customizers for TIB have the following configuration.

*localSubjectMapFile:! disabled*globalSubjectMapFile:! disabled*subjectMapSize: 1000! size of subjectMap hash table*number_of_items: 503! size of RTRServiceCustomizer hash table

TIB page services have the following default configuration:

*defaultSector: PAGE*defaultExchange: NaE

NOTE: Applications on Triarch and RMDS infrastructures must use N2_UBMS.

SFC Developer’s Guide 321

Page 336: sfc

5 SFC IMPLEMENTATION DETAILS

TIB record services have the following default configuration:

*defaultSector: ! the guess algorithm will be used*defaultExchange: NaE

5.5.8 Page Services

5.5.8.1 Page RecordsMost of the time, the LINK and REC sectors are used by record services to receive data from market datafeeds. TIB effects pages use the PAGE sector. Effects pages originate from a ANSI stream page feed (e.g. Telerate) before being logicized by TIB feed handlers. They are different than IDN page records because they contain attribute information. Despite using the same PAGE sector, effects pages should be processed by the SFC page model.

Some items within the PAGE sector are also available from Marketfeed record services. These market data items are called page records. Page records are pages whose data has already been separated into rows and whose rows have been put into fields before being processed by the datafeed. They do not contain attribute information and should be processed through the SFC record model. SFC’s page model is intended for page services that have attribute information (e.g. bold, inverse), such as TELERATE and TULLETT.

On Triarch and RMDS the SFC page model must be used for ANSI data. SFC’s page model will decode the ANSI data and provide a simple interface for querying attributes and data. The SFC page model cannot be used for IDN data, even if the conceptual data type of the Marketfeed is a "page." IDN data in a page format is sometimes called a "page record", because the record contains fields named as rows (ROW64_1, ROW80_2, etc.)

On TIB Classic, it is a little different because all data is logicized to look like a record. The SFC page model should be used for "effects" pages (the TIB terminology for pages with attributes). The SFC page model will decode the attributes and present the same interface as if the data had come fromTriarch or RMDS. The SFC record model could also be used for effects pages. However this is not recommended because the attribute information will left encoded in a binary format. Also, the application would only work on TIB and would not work on RMDS or Triarch. The SFC page model could be used for IDN page records. This works because the TIB feed handler has normalized the data. The RTRPages will not have attribute information because IDN pages do not have attributes. Using the SFC page model for IDN page records on TIB is not recommended because the application would only work on TIB and would not work on RMDS or Triarch.

SFC Developer’s Guide 322

Page 337: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.8.2 Effects Page Attribute EncodingSome page datafeeds on a TIB market data system do not use the TIB standard method for encoding attributes. Instead of sending color information in the color bytes, they encode colors in the bytes reserved for format attributes (bold, italics, etc.). SFC provides a mechanism for automatically mapping data attributes to the correct semantic color attributes. An example attribute map for the GARBAN service is defined in /var/triarch/charMapFile.cnf. Separate attribute maps can be specified in this file for each service. Attribute mapping can also be turned off through SFC configuration. Attribute mapping is enabled by default, so it should be disabled, or an attribute map for the service should be added to the file.

Like attribute mapping, character set mapping is used to automatically change the underlying page region data. Most applications do not have to worry about character set mapping. However, if a page uses extended ASCII characters (above 127), the application may need to change the character to something that can be more accurately displayed using the character sets available to the application. Several example character set maps are defined in /var/triarch/charMapFile.cnf. Character set mapping is enabled by default, but it can also be disabled through configuration.

The following standard SFC configuration variables can also be used to configure the attributes for TIB page services:

• *mapAttributes - should attribute mapping be enabled? (default is true)

• *mapCharacters - should character set mapping be enabled? (default is true)

• *attrMapFile - the filename of the character set and attribute map configuration file (default is /var/triarch/charMapFile.cnf)

• *sslPageCompatible - should a mock feed status line (sent with pages on Triarch) be added to the bottom of the page? (default is false)

• *vendorName - the name to be used in the sslPageCompatible feed status line

• *defaultCharSet - the default character set (default is ’B’ for US_ASCII)

5.5.8.3 ANSI Page SizesANSI stream based pages from RMDS or Triarch have a default size of 80 columns by 25 rows. To support larger pages, SFC must be configured with the page size. SFC uses the following configuration variables:

*rowsInPage : 25

SFC Developer’s Guide 323

Page 338: sfc

5 SFC IMPLEMENTATION DETAILS

*columnsInPage : 80

The Source Distributor must also be configured with those settings.

5.5.9 Inserts and ContributionsThe terms ’contribution’ and ’insert’ are generally synomous. There are differences as to how to implement inserts with respect to the various infrastructures (Triarch, RMDS, and Classic TIB) and how different infrastructures handle inserts and contibutions. The SFC insert model is supported on the RMDS and Triarch infrastructures. Local publishing (sending data through an RVD to a TIC or RTIC using a service specified in the TIC’s configuration file as a broadcast service) is used to contribute data using the Classic TIB infrastructure.

5.5.9.1 Inserts and TriarchThe contribution is sent through a Sink Distributor and a Source Distributor. The data in the contribution is formatted as Marketfeed. SFC’s insert model is used to impliment contributions on Triarch.

5.5.9.2 Inserts and RMDS (SASS3)Contributions are sent through the RVD, RTIC, and Source Distributor. The contribution service is specified as an interactive service in the RTIC’s configuration file. The data in the contribution is typically formatted as Marketfeed. The behavior is very similar to that for Triarch. SFC’s insert model must be used to send contributions.The primary difference between contributions on RMDS and Triarch is the RVD vs. Sink Distributor connection.

5.5.9.3 Inserts and Classic TIB (SASS2 and SASS3)

Contributions are sent the same way that local published data is sent. Like local publish services, the contribution service is specified as a broadcast service in the TIC’s configuration file. The difference is a TIB contribution server (e.g. MarketLink) happens to be consuming the locally published data. It validates the data and forwards it through the contribution infrastructure. SFC’s insert model cannot be used; the record publishing model must be used to send contributions. The application will never receive an ACK or NAK because TIB contribution servers do not send them. SFC publishes the data in

NOTE: This feature is deprecated since SFC 4.5.1.L3 which dropped support for TIB infrastructure.

SFC Developer’s Guide 324

Page 339: sfc

5 SFC IMPLEMENTATION DETAILS

TIBMsg self-describing format and the TIC converts the data to a QForm based on the record template number provided to SFC.

5.5.10 Connection and Session ParametersSee section 4.8.1 for information on the Connection model and for examples of how to set connection parameters programmatically.

5.5.10.1 RTICThe standard Rendezvous connection parameters can be set using the constructor or through the RTRConfigDb:

• *service - which service group should be used. Default value is NULL which means the default Rendezvous service will be used.

• *network - which network interface should be used. Default value is NULL which means the primary network interface for the host computer will be used.

• *daemon - location of the Rendezvous daemon used to establish communication. Default value is NULL which means the local daemon on TCP socket 7500 will be used.

• *updateService - which TMF service group should be used. Default value is NULL which means the TMF default Rendezvous service will be used.

• *updateNetwork - which TMF network interface should be used. Default value is NULL which means the TMF primary network interface for the host computer will be used.

• *updateDaemon - location of the TMF Rendezvous daemon used to establish communication. Default value is NULL which means the TMF local daemon on TCP socket 7500 will be used.

Several SFC-specific parameters can also be set

• *enableEntitlements - See section 5.3.2. This parameter is used to enable or disable entitlements.

NOTE: If updateService, updateNetwork, and updateDaemon are all NULL, then TMF is disabled by default.

SFC Developer’s Guide 325

Page 340: sfc

5 SFC IMPLEMENTATION DETAILS

Entitlements are checked on both subscriber and publisher. The entitlements profile is loaded after the data dictionary is complete. While the data dictionary and entitlements profile are downloading, the subscription is not allowed and the service is not available.

• *reconnect_interval - If the Rendezvous connection fails due to a recoverable condition, this value is used to schedule a reconnection attempt. The default value is 5 (seconds).

• *slowconsumer_interval - If the Rendezvous connection fails due to a slow consumer advisory message, this value is used to schedule a reconnection attempt. The default value is 20 (seconds). This is slower than reconnect_interval to allow the consumer’s machine more opportunity to catch up. If the value is less than or equal to zero, the RVD connection will not be terminated when a slow consumer advisory message is received.

• *username - the DACS username used for entitlement checking. This option only applies when entitlements are enabled and the connection is a SASS3 connection. See section 5.3.3 in this manual or see RTRTIBConnection in the SFC Reference Manual for details.

• *enablePingSubscription - Two purposes of this configuration are: (1) for SASS2 and SASS3, to enable RTRRTFieldToTIBRecordService to send heartbeats to the RTIC. These heartbeats provide the RTIC to determine if the SFC publisher goes down. This mechanism will incorporate with RTIC’s BC_DQA_MODE and SFC’s *groupId configuration. (2) for SASS2 only, these heartbeats also provide the SFC publisher with a mechanism to determine if the RTIC goes down. It does this by subscribing to its own ping over the same Rendezvous session on which it is publishing. This configuration variable must be set to false when the RTIC is using different values for the RVx_OUTPUT_* and RVx_PUBLISH_* RTIC configuration parameters. Specifically, *enablePingSubscription must be set to false when:

O the RV2_OUTPUT_* and RV2_PUBLISH_* parameters are set in the RTIC’s configuration file

O the RV3_OUTPUT_* and RV3_PUBLISH_* parameters are set in the RTIC’s configuration file

O sending contributions

O the RTIC has a partitions.cf that filters out the PING sector

• *pingInterval - the frequency, in seconds, that a heartbeat will be sent to the RTIC. The default value is 10 seconds and it can be set on a per service basis. If RTIC’s BC_DQA_MODE is set to TRUE and SFC’s *groupId is set, *pingInterval must be less than the RTIC’s FEED_FAIL_TIMEOUT. Otherwise the RTIC will think that the publisher has died and will mark all

SFC Developer’s Guide 326

Page 341: sfc

5 SFC IMPLEMENTATION DETAILS

items stale. In addition, setting *pingInterval to 0 is equivalent to setting *enablePingSubscription to FALSE.

See RTRTIBConnection or RTRTIBServicePoolFactory in the SFC Reference Manual for further details on all of these parameters.

5.5.10.2 SSLMost SSL client connection parameters are configured in the sslapi.cnf. The following values can be set using the SFC configuration file for a SSL Connection:

• *username - the DACS username used when making a sink connection. See section 5.3.3 in this manual or see RTRSSLConnection in the SFC Reference Manual for details.

• *mountRetryInterval - the number of seconds to wait before retrying an initial connection to a Sink Distributor. The default value is 5 (seconds).

The following values can be set using the SFC configuration file for a SSL Connection Server:

• *username - the DACS username used when making a sink connection. See section 5.3.3 in this manual or see RTRSSLConnectionServer in the SFC Reference Manual for details.

• *ipcServerName - the name of the well-known port to open for accepting connections

• *maxSessions - maximum number of connections accepted from other applications

• *reconnect_interval - The default value is 10 (seconds).

• *enableEntitlements - See section 5.3.2. This parameter is used to enable or disable entitlements.

• *tcpNoDelay - The *tcpNoDelay parameter controls the use of TCP_NODELAY socket option (which the Nagle algorithm disabled). SFC normally does not use TCP_NODELAY socket by default; this improves overall performance but it might briefly delay transmission of smaller packets. If the delay is undesirable or unacceptable, setting *tcpNoDelay to true may reduce end-to-end latency but it will consume more CPU usage.

The following values can be set using the SFC configuration file for a SSL publisher session:

• *dispatchInterval - The parameter is interval time publisher session for dispatching event for event queue. Setting the configuration lower may improve latency under high update rates but would result in more CPU usage. The default value is 25 (milliseconds); the lowest value can be 10.

SFC Developer’s Guide 327

Page 342: sfc

5 SFC IMPLEMENTATION DETAILS

5.5.11 Using Rendezvous 6 Library with the SFCThe Rendezvous 6 library and functions can be used in an application that also uses SFC, with the following constraints:

• Application code using Rendezvous 6 must run in a separate thread than Rendezvous 5 or SFC code.

All code that calls Rendezvous 6 functions or receives callbacks from Rendezvous 6 library must run in a different thread from the SFC or code using Rendezvous 5.

• Your build environment must reference an Rendezvous 6 library and include associated header files.

These are not included in the C++ Edition.

This release includes a simple example program that uses both Rendezvous 6 and SFC in the same application. The example can be found in the <INSTALL_DIR>/sfc/examples/rvinterop directory of the installation.

5.5.12 Using Rendezvous 5 Library with the SFCRendezvous 5 functions may be called directly in an application that also uses SFC classes, with the following restrictions:

• SFC and Rendezvous 5 code must run in the same thread.

All SFC objects, Rendezvous functions and any application code receiving callbacks from either SFC or Rendezvous or calling SFC or Rendezvous methods MUST be run in the same thread.

Since the SFC implements the Rendezvous event manager and that code is not thread-safe, all code using the Rendezvous event manager must be run in the same thread.

However, all code that calls Rendezvous 6 functions or receives callbacks from Rendezvous 6 library must run in a different thread from the SFC or code using Rendezvous 5.

• Applications using SFC must not link in the Rendezvous 5 ’C’ library.

The SFC library contains the Rendezvous 5 library objects found in the librvcst.a and libtibrv.a libraries. Also, the SFC implements the Rendezvous event manager functions, so your application does not need to include an event manager implementation.

SFC Developer’s Guide 328

Page 343: sfc

5 SFC IMPLEMENTATION DETAILS

If your application needs to implement the main-loop, it needs to implement the SFC event notifier rather than the Rendezvous event manager. (See the RTRSelectNotifier and RTRWindowsNotifier class references for examples of how SFC notifiers can be implemented. Also note that the source code for all notifier implementations is provided in this product package.)

• Your build environment must include the Rendezvous 5 header files from Rendezvous version 5.3.

These header files are not included in the C++ Edition.

SFC Developer’s Guide 329

Page 344: sfc

5 SFC IMPLEMENTATION DETAILS

5.6 Configuration

5.6.1 SSL Library ConfigurationConfiguration of the SSL implementation of SFC falls into two realms:

1. SSL Library Configuration - low-level configuration of SSL library parameters

2. SFC Configuration - all other configuration

The SSL library configuration file consists of a number of configuration variable settings which may be specified on a per installation, per hosts, or per application name basis. Configuration variables cover connection parameters, low-level performance tuning, and tracing.

SSL library configuration can be done through sslapi.cnf. The sslapi.cnf file is preferred over the ipcroute file. The ipcroute file is still supported for backwards compatibility, but all of its functionality is also included in sslapi.cnf. The sslapi.cnf file takes priority over ipcroute, so ipcroute should not be used to avoid confusion. The ipcroute file is not installed in this version of SFC.

The SSL library will look for a configuration file in the following locations:

1. in the local directory (./sslapi.cnf) NOTE: A local file will take precendence over one specifid by a registry entry or environment variable.

2. if a file is not found in the local directory, \HKEY_LOCAL_MACHINE\Software\Reuters\SSL\SSLAPI_CONFIG registry entry (Windows only)

3. SSLAPI_CONFIG environment variable

If the sslapi.cnf file does not exist, the ipcroute file will be located per SSL 4.0 guidelines.

Note that the registry entry and the environment variable can be used to set the file location and name to the same one used by SFC’s RTRXFileDb. That way, only one configuration file is needed.

See Appendix B.6 for a detailed description of the sslapi.cnf file.

5.6.2 SFC Configuration SummaryThe following tables summarize SFC configuration variables and provide a reference for more information about them. Additional low-level SSL configuration variables are detailed in Appendix B.6.

SFC Developer’s Guide 330

Page 345: sfc

5 SFC IMPLEMENTATION DETAILS

Variable ClassIds Default Reference

display_configuration Logger false Reference Manual:RTRDefaultLogger

recordServices SSLServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

rtPageServices SSLServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

timeSeriesServices SSLServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

pageServices TIBServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

recordServices TIBServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

timeSeriesServices TIBServicePoolFactory None Reference Manual:RTRMDServicePoolFactory

pageServices SSLServicePoolFactory None Reference Manual:RTRMDSServicePoolFactory

ipcServerName SSLConnectionServer None Reference Manual:RTRSSLConnectionServer

maxSessions SSLConnectionServer None Reference Manual:RTRSSLConnectionServer

insert_timeout InsertService.SSLInsertService constructor or 30, config overrides constructor

Reference Manual: SSLInsertService

insert_timeout InsertService.TSAInsertService constructor or 30, config overrides constructor

Reference Manual: SSLInsertService

closeInactiveItemAsRecoverable SSLPublisherRecordService false ReferenceManual:RTRFieldToSSLRecordService

criteriaName RTRSSLSessionPublisherRecordSer-vice

triarch section 4.2.4.1

pubSubjectPrefix RTRMDAPIInterface _TIC section 4.2.4.2

defaultBgColor ProxySSLPageService 0 section 4.3.4.3

defaultFgColor ProxySSLPageService 7 section 4.3.4.3

Table 5.13: Configuration Variables

SFC Developer’s Guide 331

Page 346: sfc

5 SFC IMPLEMENTATION DETAILS

enableColors ProxySSLPageService true section 4.3.4.3

defaultBgColor RTRProxyTIBPageService 0 section 4.3.4.3

defaultFgColor RTRProxyTIBPageService 7 section 4.3.4.3

enableColors RTRProxyTIBPageService true section 4.3.4.3

requestTS1RealTime RTRTS1Record false section 4.5.2

protocol TIBConnection SASS3 section 4.8.1.2

defaultFileAction.file Logger log.out section 4.8.6.4

defaultFileAction.flush Logger true section 4.8.6.4

defaultFileAction.max_bytes Logger 10000 section 4.8.6.4

defaultFileAction.selector Logger *.info section 4.8.6.4

defaultFileAction.truncate Logger false section 4.8.6.4

enable Logger true section 4.8.6.4

install_file_action Logger true section 4.8.6.4

install_stderr_action Logger false section 4.8.6.4

install_system_action Logger false section 4.8.6.4

priority Logger 100 section 4.8.6.4

selector Logger *.info section 4.8.6.4

enableEntitlements SSLConnectionServer false section 5.3.2

username SSLConnectionServer None section 5.3.3

username TIBConnection None section 5.3.3

DACS_log_file_path DACSConnection ./ section 5.3.6

DACS_log_file_size DACSConnection 255 section 5.3.6

DACS_log_flush_interval DACSConnection 60 section 5.3.6

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 332

Page 347: sfc

5 SFC IMPLEMENTATION DETAILS

DACS_retry_connection_interval DACSConnection 60 section 5.3.6

DACS_user_login_retry_interval DACSConnection 1 section 5.3.6

DACS_user_login_wait_period DACSConnection 60 section 5.3.6

dacsHashTableSize DACSEntitlementSystem None section 5.3.6

permField RTRSASS3Interface PROD_CATG section 5.3.6

serviceId SSLPublisherRecordService None section 5.3.6

enableEntitlements SSLConnectionServer section 5.3.2

number_of_items PageService 101 section 5.4.2.1

number_of_items SSLMDService.SSLRTPageService 503 section 5.4.2.1

number_of_items SSLMDService.SSLRTRecordService 503 section 5.4.2.1

number_of_items SSLPublisherRecordService 101 section 5.4.2.1

number_of_items TIBPublisherRecordService 101 section 5.4.2.1

number_of_items TIBRTRecordService 503 section 5.4.2.1

number_of_items DACSEntitlementSystem 101 section 5.4.2.1,section 5.3.6

fids_per_record SSLPublisherRecordService 150 section 5.4.3

fids_per_record TIBPublisherRecordService 150 section 5.4.3

fids_per_record TIBRTRecordService 150 section 5.4.3

request_queue*initial_pending_limit VJRequestQueue 10 section 5.4.4.1

request_queue*limit_multiplier VJRequestQueue 2 section 5.4.4.1

request_queue*max_pending_limit VJRequestQueue 100 section 5.4.4.1

request_item_config* retry_cap_seconds

RTRProxyTIBRTRecordService 300 section 5.4.4.2

request_item_config* retry_multiplier

RTRProxyTIBRTRecordService 2 section 5.4.4.2

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 333

Page 348: sfc

5 SFC IMPLEMENTATION DETAILS

request_item_config* retry_seconds

RTRProxyTIBRTRecordService 5 section 5.4.4.2

request_item_config* timeout_seconds

RTRProxyTIBRTRecordService 20 section 5.4.4.2

imageRequestOpenLimit SSLPublisherRecordService infrastucture default section 5.4.5

imageInterval SSLSession 100 section 5.4.5.2

imagesPerInterval SSLSession 30 section 5.4.5.2

traceLevel RTRProxyTIBPageService 0 section 5.4.6

traceLevel RTRProxyTIBRTRecordService 0 section 5.4.6

traceLevel RTRTIBPublisherRecordService 0 section 5.4.6

item_debug SSLMDService false section 5.4.6

traceLevel SSLPublisherRecordService 0 section 5.4.6

tiblogfile RTRSASS3Interface "SASS3.log" section 5.4.7

mountTrace SSLDispatcher false section 5.4.7

sslLogFile SSLInterface SSL.log section 5.4.7

sslLogFileSize SSLInterface 10000 section 5.4.7

reconnect_interval SSLConnectionServer 10 section 5.5.10

mountRetryInterval SSLDispatcher 5 section 5.5.10

daemon TIBConnection "" section 5.5.10

network TIBConnection "" section 5.5.10

reconnect_interval TIBConnection 5 section 5.5.10

service TIBConnection "" section 5.5.10

slowconsumer_interval TIBConnection 20 section 5.5.10

updateDaemon TIBConnection "" section 5.5.10

updateNetwork TIBConnection "" section 5.5.10

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 334

Page 349: sfc

5 SFC IMPLEMENTATION DETAILS

updateService TIBConnection "" section 5.5.10

enablePingSubscription TIBDistribution true section 5.5.10.1

pingInterval TIBDistribution 5 section 5.5.10.1

tcpNoDelay SSLConnectionServer false section 5.5.10.2

dispatchInterval RTRSSLPublisherSession 25 section 5.5.10.2

dropSeqNo ProxyTIBRTRecordService false section 5.5.2

decimalSize RTRBaseTIBFidDB 17 section 5.5.2, section 5.5.2.2

sendSymbolFields RTRTIBMsgEncoder true section 5.5.2

enableNextChainHeaderAsString RTRTIBMsgEncoder true section 5.5.2

mfencoder RTRTIBPublisherRecordService false section 5.5.2

srcExpandsEnumFields RTRProxyTIBRecordService false section 5.5.2.1

srcExpandsEnumFields SSLMDService.SSLRTRecordService false section 5.5.2.1

useTemplates RTRTIBPublisherRecordService true section 5.5.3

enum_file_path FileFidDb None, section 5.5.4.1

fid_file_path FileFidDb None section 5.5.4.1

fidDbInterval SSLFidDb 20 section 5.5.4.1

fidDbLocation SSLFidDb None section 5.5.4.1

enum_file_path TIBFidDb None, section 5.5.4.1

fid_file_path TIBFidDb None section 5.5.4.1

fidDbInterval TIBFidDb 20 section 5.5.4.4

fidDbLocation TIBFidDb None section 5.5.4.4

fidDbType TIBFidDb None section 5.5.4.4

allowUpdatesToChangeStaleToOk ProxyTIBRTRecordService false section 5.5.5.1

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 335

Page 350: sfc

5 SFC IMPLEMENTATION DETAILS

groupId TIBDistribution 0 section 5.5.5.1

notFoundAsRecoverable TIBItemService true section 5.5.5.1

dataLossInboundInterval TIBConnection 0 section 5.5.5.2

dataLossOutboundInterval TIBConnection 0 section 5.5.5.2

forceInfrastructureRecovery TIBItemService false section 5.5.5.4

forceSFCDrivenRecovery TIBItemService false section 5.5.5.4

enableDynamicTimeSeriesServices SSLServicePoolFactory true section 5.5.6.1

enableDynamicPageServices SSLServicePoolFactory true section 5.5.6.1

enableDynamicRTPageServices SSLServicePoolFactory true section 5.5.6.1

enableDynamicRTRecordServices SSLServicePoolFactory true section 5.5.6.1

enableDynamicInsertServices SSLServicePoolFactory true section 5.5.6.1

enableDynamicTimeSeriesServices TIBServicePoolFactory true section 5.5.6.1

enableDynamicPageServices TIBServicePoolFactory true section 5.5.6.1

enableDynamicRTRecordServices TIBServicePoolFactory true section 5.5.6.1

enableDynamicInsertServices TIBServicePoolFactory true1 section 5.5.6.1

dataType ServiceStatus None section 5.5.6.2

serviceProvider ServiceStatus None section 5.5.6.2

serviceStatusInterval ServiceStatus 15 section 5.5.6.2

traceServiceStatusInfo ServiceStatus False section 5.5.7.2

number_of_items DefaultRecordCustomizer 503 section 5.5.7.2

sectorList DefaultRecordCustomizer REC, PAGE, LINK section 5.5.7.2

defaultSector InsertService.TSAInsertService ANY section 5.5.7.2

defaultExchange RTRProxyTIBPageService NaE section 5.5.7.2

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 336

Page 351: sfc

5 SFC IMPLEMENTATION DETAILS

defaultSector RTRProxyTIBPageService PAGE section 5.5.7.2

defaultExchange RTRProxyTIBRecordService NaE section 5.5.7.2

globalSubjectMapFile ServiceCustomizer None section 5.5.7.2

localSubjectMapFile ServiceCustomizer None section 5.5.7.2

subjectMapSize ServiceCustomizer 1000 section 5.5.7.2

defaultSector RTRProxyTIBRecordService "" section 5.5.7.2, section 5.5.7.3

defaultSector RTRTIBPublisherRecordService "" section 5.5.7.2, section 5.5.7.3

nextChars RTRProxyTIBPageService +n section 5.5.7.5

prevChars RTRProxyTIBPageService -p section 5.5.7.5

newsSectorList DefaultRecordCustomizer BRCAST, INTERACTIVE section 5.5.7.6

newsEnabled RTRProxyTIBRecordService true section 5.5.7.6

newsSymbol RTRProxyTIBRecordService N2_UBMS section 5.5.7.6

newsPrefix ServiceCustomizer NEWS2K_ section 5.5.7.6

newsInstrumentList TIBNews NEWS2K_ALERT.NaE 1, NEWS2K_HL.NaE 2, NEWS2K_SUB_HL.NaE 3, NEWS2K_CORRECT.NaE 4, NEWS2K_CORECTD.NaE 5, NEWS2K_DELETE.NaE 7, NEWS2K_EXPIRE.NaE 8

section 5.5.7.6

attrMapFile RTRProxyTIBPageService /var/triarch/charMapFile.cnf section 5.5.8.2

charMapFile RTRProxyTIBPageService /var/triarch/charMapFile.cnf section 5.5.8.2

defaultCharSet RTRProxyTIBPageService B section 5.5.8.2

mapAttributes RTRProxyTIBPageService true section 5.5.8.2

mapCharacters RTRProxyTIBPageService true section 5.5.8.2

sslPageCompatible RTRProxyTIBPageService false section 5.5.8.2

vendorName RTRProxyTIBPageService "" section 5.5.8.2

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 337

Page 352: sfc

5 SFC IMPLEMENTATION DETAILS

columnsInPage PageService 80 section 5.5.8.3

rowsInPage PageService 25 section 5.5.8.3

1. For TIC/SASS2 infrastructure, service must be added to the RTRTIBServicePoolFactory manually or through con-figuration.

Variable ClassIds Default Reference

Table 5.13: Configuration Variables (Continued)

SFC Developer’s Guide 338

Page 353: sfc

APPENDIX A: GLOSSARY

Active A market data item is initially in this state when it is created. It remains active until it is closed or destroyed.

ANSI The American National Standards Institute (ANSI) develops standards widely used as guidelines by US firms. Data processing standards devel-oped from ANSI range from the definition of ASCII to the determination of overall datacom system performance.

ANSI Sequence A string of characters that invokes a mode or status change in the display system. ANSI sequences start with an ESC character (1B hex) and then follow one of several patterns. The receiving device must recognize these patterns and act upon the supported sequences while ignoring unsup-ported sequences. ANSI sequences can refer to position or attribute infor-mation.

ANSI Page The Triarch name for Effects Page. Pages on Triarch are delivered as a stream of ANSI encoded data. See also Page.

Attributes See Page Attributes.

CBE Content Based Entitlements

Client A component that receives events from SFC.

Client Application An application that receives data and events from a market data infrastruc-ture.

CMON A TIB infrastructure component that monitors the status of other infrastruc-ture components.

Consumer See Subscriber, Client Application, Sink Client.

Contribution See Insert.

SFC Developer’s Guide 339

Page 354: sfc

APPENDIX A: GLOSSARY

DACS The Data Access Control System is a entitlement tool that allows custom-ers to automatically control who is permitted to use which sets of data in the customer’s financial information management system. In this way, the customer can demonstrate to information providers and vendors how many people are using which sets of data.

Data Dictionary See FID Database.

Distribution Layer The TIBCO Rendezvous network that consists of the RVDs of the RTIC and end-user programs.

DQA Data Quality Assurance. The TIB infrastructure uses the CMON process to send heartbeats to other market data components. If one of them does not respond, a DQA message is broadcast to indicate that the data might be stale.

Effects Pages An ANSI Page, after it has been converted into a Logical Page to be broadcast on a TIB market data system.

Entitlement Code If a vendor requires subservice permissioning, a code must be provided with each data item from that vendor. This entitlement code is used by the permissioning system (DACS) to control access to data.

Enumerated Type An enumerated type is one of the field types defined for Marketfeed. It con-sists of a set of mnemonics, each having its own specific meaning. A dis-playable string is associated with each of these mnemonics.

Enumerated Value The integer value equivalent of data that has an enumerated type.

ETIC Entitlements TIC. Entitlements TIC provides the entitlement profile needed for a TIB publisher and subscriber.

Expanded Value The full mnemonic string for data that has an enumerated type.

Fading An ANSI extension that many users and sources require, where an area of updated text must be highlighted for a short time to draw attention to it. After the end of the fade period, the text returns to its original color. Appli-cations implement fading as follows: when a character is changed, it is displayed initially with the “Fading” set of attributes; after a fixed period of time, it is re-displayed with the default attributes.

SFC Developer’s Guide 340

Page 355: sfc

APPENDIX A: GLOSSARY

FID Applies to record data as defined by Marketfeed. A Field Identifier (FID) is an integer that identifies a [Service, Field Name] pair. This integer is unique within a given RMDS or Triarch system.

FID Database The repository of all valid market data FIDs. On Triarch or RMDS, this is generated from the appendix_a file. On Rendezvous, this can be read from a series of configuration files or can be downloaded from the TIC. Also referred to as the data dictionary.

Field As applied to records, a field is a constituent component of record data as defined by Marketfeed.

Field List Number See Record Template Number.

Field Name Applies to record data as defined by Marketfeed. This is the name given to a component field of record data (e.g., BID, ASK). Such names are unique across a service.

Field Type Applies to record data as defined by Marketfeed. The name given to the type of data carried in a given field of record data (e.g., INTEGER, PRICE).

Full-Cache Service A publishing service that pre-loads all available records into its cache. See also Non-Interactive Service, Source-Driven.

IDN The Reuters Integrated Data Network (IDN) combines multiple sources of information into a single format. IDN is characterized by record data and high transmission speed.

Image The complete representation of a market data item. All of the fields that will ever be in the record have been created.

Inserts Allows a peer-to-peer dialogue between a sink client and a source service. The dialogue is initiated by the sink client. Insert usage is determined by the application, although this capability is typically used to add information to a data stream. Also known as a Contribution.

Interactive Publisher A publisher that can accept dynamic item requests. See also Sink-Driven.

SFC Developer’s Guide 341

Page 356: sfc

APPENDIX A: GLOSSARY

Inactive A market data item is in this state when it is closed or destroyed. Some-times, the market data infrastructure will force an item to be closed, and thus become inactive. Inactive is a terminal state. Once an item is inactive, it cannot become active again.

Item See Market Data Item.

Local Publisher A non-interactive publisher on the Rendezvous distribution network of RMDS or a TIB market data system.

Logical Data Real-time data distributed across a market data system in a display-inde-pendent format. By implication, applications can access both the syntax and semantics of all constituent elements of the data. Implemented as records on Triarch.

Logical Page A page that has been broken down into regions. Page data and attributes are available by accessing a row and column.

Marketfeed Originally the Reuters presentation protocol providing public access to data supplied by Reuters. Its purpose is to support the transfer of data between Reuters and user computer systems in a consistent and logical format for Triarch or RMDS.

Market Data Hub The set of components that provide resilient and scalable integration of the RMDS with external sources of real-time market data and news. The hub is comprised of the information source, source distributors, and compatible feed handlers.

Market Data Item Information from a specified source (e.g., IDN_SELECTFEED or YOUR_SOURCE) for a specified item (e.g., DEM=). Market data items are identified by the name of the source service which supplies them and the name of the individual item within that source service.

MDDS Market Data Distribution System

Node A device connected to a network cable. This usually refers to a server or a workstation.

SFC Developer’s Guide 342

Page 357: sfc

APPENDIX A: GLOSSARY

Non-Interactive Pub-lisher

A publisher that cannot except dynamic requests for market data items that it does not know about. See also Full-Cache Service, Source-Driven.

Page A page is a type of data item formatted for distribution to display systems. The data includes attribute information.

Page Attributes Information that describes how a page’s text should be displayed; e.g. properties such as highlighting, blinking, color, etc.

Page Record A logical record that contain rows of text. Page records are different than pages because page records do not contain attribute information. They are also delivered from record sources. An example is an IDN Page Record.

Page Source A source that supplies data items in the form of pages. Pages are of vari-able dimensions, but typically displayed in 80 columns and 24 or 25 rows.

Permissionable Entity (PE)

A numeric code included in each Reuters IDN record. The PE is used to determine to which subservice(s) the record belongs. For example the PE value 62 indicates that the item is from the New York Stock Exchange.

Publisher An application that creates market data items and distributes them to a market data infrastructure. Publishers can manage the state and update the values of the market data items. In contrast, contributions do not have a state model.

Record A record is a type of data item encoded in a form that is convenient for use by computer applications.

Record Source A source that supplies data items in the form of records.

Record Template A specification of all of the fields that are in a record.

Record Template Num-ber

The number that specifies which record template was used to create the record of a given type. Also called Field List Number.

Rendezvous See TIBCO Rendezvous.

RIC Reuters Instrument Code. A RIC is a unique identifier for a record.

SFC Developer’s Guide 343

Page 358: sfc

APPENDIX A: GLOSSARY

RMDS Reuters Market Data System. The market data system that fully leverages the TSA Framework and consists of a best-of-breed combination of Triarch and the TIB MDDS.

RRCP Reuters Reliable Communication Protocol. The UDP broadcast-based communications layer of RRDP.

RRDP Reuters Reliable Datagram Protocol. A stack of protocols used to commu-nicate between the key processes which make up the Triarch backbone or the Reuters Market Data Hub. RRDP consists of RRMP and RRCP.

RRMP Reuters Reliable Messaging Protocol. The session management layer of RRDP.

RTIC TIC—RMDS Edition. The RMDS caching server that connects a Reuters Market Data Hub with a Rendezvous Distribution Layer.

RV See TIBCO Rendezvous.

RVD Rendezvous Daemon. RVD is a process that listens to multicast traffic on a Rendezvous network. SFC gets data directly from the RVD.

SASS Subject Addressed Subscription Service. The SASS protocol is used by the TIC and RTIC to deliver market data over Rendezvous network.

SBE Subject Based Entitlements

Server A server is a process or several coordinating processes whose function it is to satisfy client requests.

Service A logical entity, made up of one or more source applications that have been configured to provide a single, coherent view of a set of data. Sink applications request data from services.

Service Distributor (a.k.a. Service Manager) An optional process that implements many of the advanced information resource management features of an RRDP-based Market Data Hub. The Service Distributor ensures that requests made by a Sink Distributor (on Triarch) or an RTIC (on RMDS) are directed to the most appropriate Source Distributor at the optimum rate.

Sink A consumer of data from the RMDS or Triarch network.

SFC Developer’s Guide 344

Page 359: sfc

APPENDIX A: GLOSSARY

Sink Application An SSL application that functions as a sink client.

Sink Client A consumer of data from the Triarch network which interfaces with a Sink Distributor via the SSL Library.

Sink Components The underlying SSL components that are specific to a sink client. The sink components consist of the Sink Distributor and SSL Library.

Sink Distributor The Sink Distributor is a daemon process that accepts user requests and delivers data items to the sink clients which it serves.

Source A contributor of data items to the RMDS or Triarch network.

Sink-Driven Source A source whose cache is determined, within the limitations of the applica-tion, by demand from consuming applications. At any given point in time, the cache of the source client contains a subset of all possible items avail-able from that source client. Also known as a selective source or interac-tive source.

Source-Driven Source A source client whose cache is determined by the source client itself. Demand from the network will not change the contents of a source-driven source client’s cache. At any given point in time, the cache of the source client contains all possible items available from that source client. Also known as a full cache source or non-interactive source.

Source Application An SSL application that functions as a source client.

Source Components The underlying SSL components that are specific to a source client. These components are the Source Distributor and SSL Library.

Source Distributor The Source Distributor is a daemon process which is used to distribute data items to the RMDS or Triarch network.

Source Server A logical entity that consists of a source client and source distributor. Source service most commonly integrate datafeeds from vendors, exchanges, etc. with an RMDS or Triarch network. The source server sup-plies items upon request and forwards updates to these items as they are received.

SFC Developer’s Guide 345

Page 360: sfc

APPENDIX A: GLOSSARY

Source Service The name by which a particular vendor or data contributor is identified on the Triarch network. A source service is comprised of one or more source servers on the Triarch network.

SSL Source-Sink Library. A Reuters software product that provides an applica-tion programming interface to the Triarch network. “SSL” is also used when referring to the Triarch implementation of SFC.

System Foundation Classes (SFC)

A set of object oriented class libraries written in C++. The SFC includes a series of abstract interfaces and implementations to enable easy and con-sistent access to both real-time and historical data.

Stale A state indicating that a service is unavailable or a market data item may not have the current value. This state could result from mis-configuration, network problems, or failures of upstream market data components.

State For a given application, each channel and data stream may be in one of several possible defined states (e.g., open data stale). Certain events cause a transition from one state to another.

Status A status indicates the state of a data item. For example, a status may indi-cate that the item is unavailable, that the data provided may not be com-plete, or that the item is now up to date.

Subscriber An application that listens for market data events. See also Consumer, Client Application, Sink Client.

Triarch A network infrastructure aimed at the financial market place. It is designed to distribute market data in an efficient manner. Core distribution compo-nents of Triarch are the Source, Service, and Sink Distributors.

TIB The Information Bus. “TIB” is used when referring to the Rendezvous implementation of SFC. It is also sometimes used to refer to the TIC-based TIB infrastructure.

TIBCO The Information Bus Company

TIBCO Rendezvous A broadcast-based message delivery system that can be used to deliver market data. The TIB implementation of SFC uses the Rendezvous infra-structure.

SFC Developer’s Guide 346

Page 361: sfc

APPENDIX A: GLOSSARY

TIC TIBCO Information Cache. The caching server that connects a TIB ciSer-ver feed network with a ciServer or Rendezvous-based client-delivery net-work. It caches market data broadcast traffic so it can provide initial images to client applications. The TIC is the caching component of the TIB infrastructure.

Update An update is a modification to the contents of a data item. A source sends updates asynchronously as the contents of the item change.

SFC Developer’s Guide 347

Page 362: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.1 Overview

Reuters has created the SSL architecture in order to connect suppliers and consumers of financial information. From an application programmer’s perspective, the SSL may be thought of as an architecture for building location-independent applications. In such an environment, applications can distribute both data and functionality across one or more cooperating machines at one or more geographic locations. Such an environment allows users to transparently make use of the combined computing resources that are provided by a distributed system—such as redundancy and fault-tolerance, load balancing, normalization, and integration of internal and external data or services—while adhering to a consistent real-time client/server model.

B.2 The SSL Interface

User applications interface with the SSL infrastructure using a variety of logical constructs. This section describes the entities used by an application to communicate with the SSL in order to request network data and to receive information about the state of the network or data.

In order for these communication processes to occur, the sink, source, or message application must first mount a channel.

For sink application programming, it also important to understand the concept of a data stream.

(SSL) Channel A channel connects the sink application to the sink distributor . Multiple channels may be mounted, and each channel is independent of any other channel.

Most of the function calls, and all of the events that are available via the SSL API, require that the application specify or provide a channel number to the application letting it know to which connection an event applies.

Data Stream A data stream is opened for a data item, allowing information about that item to flow across a channel. The data stream logically relates a channel, service name, and item name. An open data stream contains an image message followed by any number of updates and state information. Infor-mation concerning the state of the data is guaranteed to be sent, whether the state is OK, STALE, or CLOSED.

SFC Developer’s Guide 348

Page 363: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

In order to receive a data item, a sink application must open a data stream for that item. Likewise, a source application sends an item to the network through an open data stream. Multiple data streams may be opened on a channel, but only one data stream can be opened for a particular item on one channel. If multiple channels are mounted, one data stream may be opened for the same data item on each of the channels.

Once a channel has been mounted by a sink application, the sink application can request data items.

It is important to understand that the response to a sink application's request for a data item is not a single, discrete event, but instead is a continual stream of data events (see Figures B.1 and B.2). As the market changes throughout the day, the original data will be updated (as long as the source remains active and the application is connected). Status messages and (in some cases) new images will be sent if the data becomes stale. Data and status information will continue to flow through the stream, as it is available, until the data stream is closed.

Figure B.1: Source Data Stream

Figure B.2: Sink Data Stream

Update UpdateStatus

Data Stream for Channel 1, IDN_SELECTFEED, DEM=

Image

SourceApplication

SourceDistributor

Update UpdateStatus

Data Stream for Channel 1, IDN_SELECTFEED, DEM=

Image

SinkDistributor

SinkApplication

SFC Developer’s Guide 349

Page 364: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.3 SSL Sink Components

B.3.1 The Sink ApplicationSink applications request information from (see Figure B.3). If the information is already being held by the , it is provided to the application. If the information is not currently available in the infrastructure, it is requested from the .

Figure B.3: Typical Components of a Simple Network

Unless a “snapshot” request is made by the sink application requesting the data, the request is for a data stream to be opened to the service. Assuming that the request is for an actual data item and any permission checks have been satisfied, the service will provide an image of the current contents of the data item. As the data in the item changes, updates will be provided to the sink application until it indicates that it is no longer interested in the data item, by closing the data stream.

ReutersServer B

Network Backbone

SourceDistributor

ReutersServer ASource

Distributor

SinkDistributor

PTW

Source

Application

SSL

ATW

Distributor

SourceService

SFC Developer’s Guide 350

Page 365: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.3.2 Sink DistributorThe SSL Sink Distributor is responsible for responding to sink requests, maintaining communications with the required source services, and distributing SSL messages received from a source service to the proper sink clients. A sink application connects to a Sink Distributor through the use of the common software routines in the SSL Library. Architecturally, the Sink Distributor may reside on the same node as the sink client or on a separate node, in which case they communicate over the network.

The relationship between a Sink Distributor and an application is shown in Figure B.4.

Figure B.4: SSL Sink Components

A sink application accesses through its connection to the Sink Distributor. It is the role of the Sink Distributor to retrieve data items and forward updates on behalf of the sink application. The Sink Distributor communicates by passing messages using a socket Interprocess Communication (IPC) mechanism. This allows great configuration flexibility, since these components may reside on any node on the network.

Sink

SSL Library

Requestssent fordata items

SinkApplication

Responses returnedvia SSL events

Distributor

IPC

Network Backbone

SFC Developer’s Guide 351

Page 366: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.4 Design Goals and System Features

B.4.1 Triarch System Design GoalsThe Triarch Infrastructure has been designed to distribute information, with the following key goals in mind:

• Reliable Data Communications

• Flexibility and Scalability

• Platform Independence

• Optimal Resource Usage

• Fault-Tolerance and Resiliency

• Single Item Open Request

• Monitoring of Status and Component Health

• Data Access Control

The requirements driven by these goals are described in the following paragraphs in order to enhance the user’s understanding of the intended role of Triarch.

B.4.2 Reliable Data CommunicationsIn a financial environment, the timeliness and accuracy of information delivery is key. Data must be delivered quickly, and often this data must be sent to multiple users or applications. Knowing and managing the state of data in a financial network is important. In this environment it is mandatory to inform users of stale or lost data.

In order to ensure the maximum efficiency and reliability of data, Triarch makes use of a combination of standard TCP/IP virtual circuits and a specially developed reliable broadcast communication scheme, based on the Reuters Reliable Datagram Protocol (RRDP). The RRDP protocol is used to communicate between the key backbone processes which make up the Triarch Infrastructure. RRDP ensures rapid and reliable delivery of data to multiple nodes, providing packet sequencing, negative acknowledgment, bitmap filtering, and keep-alive messaging between components. The underlying communication protocol is transparent to the application user, and is simplified for the application developer who needs to interact with only the software library—a set of software routines that handle the common communication interactions with the Triarch network.

SFC Developer’s Guide 352

Page 367: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.4.3 Flexibility and ScalabilityThe Triarch Infrastructure has been designed to provide the following aspects of flexibility and scalability:

• Flexible support of differing types of data

Triarch supports both well-defined normalized data types and fully user-definable data types. These user-defined types are integrated with well-defined market data types to allow for the introduction of new data and data types without major system administration or programming overhead.

• Scalability from small to large numbers of users

The network is scalable to permit efficient operation for variable numbers of users and applications. It is possible to create Triarch-based solutions which vary between the extremes of simple systems using a small subset of Triarch features and products, to large and complex integrated systems. These Triarch solutions can also be provided for a variety of network topologies, with the hierarchical nature of the system components permitting easy scalability.

• Support for a large set of off-the-shelf data sources

In excess of 30 different feed handlers are available for Triarch, including source servers to access digital information from Reuters, Telerate, Knight-Ridder, as well as many direct stock exchange and Inter Dealer Broker (IDB) feeds. Handlers, working in conjunction with a Data Contribution Server (DCS), are also available to contribute data back to information vendors.

• Flexibility in the choice of underlying system platforms - through open system design

The Triarch system has been built to be fully distributed using the principles of open system design. As few assumptions as possible are made about the environment in which the distribution software and library routines run. The use of TCP/IP communication protocols allows for great flexibility in physical network implementation. Many types of network have been used as the basis of Triarch solutions, including, Ethernet (e.g., 10base2, 10baseT), Token Ring, ATM, and wide-area links. The protocols and data formats used are such that machines of different types and architectures can communicate and be used interchangeably. Workstation types based on different hardware platforms and operating systems can be mixed freely.

B.4.4 Optimal Resource UsageThe underlying Triarch software has been designed to effectively manage complex and expensive data resources (i.e., those provided by vendor datafeeds). Where multiple source servers are providing a

SFC Developer’s Guide 353

Page 368: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

single service, the system has been designed to provide redundancy as well as to optimize server usage in normal operating circumstances. Optimized management is key when datafeeds provide a complex set of constraints like data storage limitations, data request (or throttle) limitations, or mixed delivery mechanisms.

Several key features are available for resource optimization:

• Optimized Resource Management

Multiple instances of a source server appear as a single service to the users, making the optimization transparent. Where multiple instances of a server are present, the system strives to ensure that any given item should be supplied by only a single server. All the available data item storage (called “cache”) slots will be used before new item requests force items to be removed from storage. When the resources are strictly limited, managed data storage removal (called “preemption”) is available.

A powerful scheme allows the use of priorities to determine the best candidate to be preempted from the cache to make way for a new request. The priority scheme supports various features including the locking of cache items and allowing unconditional candidates for preemption. Automatic re-request management enables the system, rather than the user, to manage request retries. Control is asserted during times of insufficient resources, and server failure or failover is managed gracefully.

• Optimum Response Timing

Requests for data items are managed intelligently. If any source server is already supplying an item stored in its cache, a new request for that item will be fulfilled automatically from that server. If multiple items are requested at once and the data is available on multiple servers, the requests are grouped and sent to different servers for processing in parallel.

• Request Throttling

A source server can indicate that it is temporarily unable to service requests, i.e., it is throttled”, in order to avoid server overload. The server may also indicate the optimum queue size that it is willing to accept.

B.4.5 Fault Tolerance and ResiliencyFault-tolerant operating procedures are mandatory in a mission-critical information distribution system. In the Triarch software, a series of measures are implemented to ensure that backup resources can automatically take the place of operational servers in case of failure. When multiple source servers are

SFC Developer’s Guide 354

Page 369: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

used to implement a single service and an individual server fails, the system automatically recovers failed items while sharing the load equally among the remaining servers.

B.4.6 Single Item Open RequestWhen a sink application opens an item, it remains open until:

• closed by the sink application, or

• closed by the source application or infrastructure with a code indicating that the item is in a non-recoverable state.

If the source application closes an item but indicates that it might be recoverable, the SSL Infrastructure automatically tries to recall the item. A timer-driven retry queue is used for items that cannot be recovered immediately (due to resource shortage or a source problem). The SSL Infrastructure does everything possible to provide data for an open item.

The single open strategy helps to utilize system resources more efficiently and frees sink application developers from having to implement re-request strategies.

B.4.7 Management and Monitoring of StatusTools are available to monitor the main processing components of Triarch. The Network Management Agent reports operational statistics through the use of the Simple Network Management Protocol (SNMP).

B.4.8 Data Access ControlData permissioning and entitlement is enforced using DACS which allows Triarch system administrators to control access rights to information on the network.

B.5 Request Routing and Resource Optimization

To provide a better understanding of how Triarch operates, this section describes how requests are routed to servers.

As far as the sink application is concerned, a request is placed using the SSL Library. The library, in turn, communicates over a TCP virtual circuit with the Sink Distributor. The Sink Distributor masks the fact that two or more datafeeds or source servers from a single information vendor may be required due to heavy trader demand or to ensure redundancy. Thus, the sink application sees a single logical

SFC Developer’s Guide 355

Page 370: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

service. For example, if a Triarch system is configured with two Selectservers, a sink application can determine that the Selectserver service is available, but the sink application is unable to distinguish the actual number of servers.

Figure B.5 shows a typical configuration used in network request routing where (N) source servers of the same type are present on the network. All of these source servers appear as a single service on the network. Each may support a single datafeed or several datafeeds.

Figure B.5: Request Routing Configuration

In SSL 4.x, an optional process (the Service Distributor) performs resource management. Because the Service Distributor is optional, two scenarios exist for request routing:

• Request routing among source servers without the presence of a Service Distributor

• Request routing among source servers when the Service Distributor is present

In either case, the SSL Infrastructure:

• Ensures that all available source servers or datafeeds share the load of responding to requests for data from Triarch users.

• Ensures that if a copy of a given data item is already available on Triarch, then subsequent requests for the same item are satisfied from this copy, rather than by re-requesting the item from

Datafeed of Datafeed of

Source Server A(1)

SourceServer A(N)

SERVICE A

Type A Type A

. . .

Sink(s)

Network Backbone

SFC Developer’s Guide 356

Page 371: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

another datafeed. This avoids so-called cache duplication, where the same item is open simultaneously on several datafeeds.

B.5.1 Basic Request Routing without the Optional Service DistributorRequest routing without the Service Distributor provides reasonable load leveling performance without the need to allocate resources to an additional distributor.

Multiple mechanisms are used to achieve this. All servers periodically broadcast a load level that tells sinks how heavily loaded they are. The algorithm used to calculate this load level is determined by the particular source service. For some types of services, the most critical resource may be available communications bandwidth to the information provider; for others, it may be processor power.

If a sink application makes a retrieval request, the Sink Distributor does the following:

• If the service type is source-driven, the Sink Distributor requests the item from an appropriate source server.

• If the service type is sink-driven, then a special type of request message is sent to each available source server. This message requests that the server respond with an image only if it is available in its cache. If none responds with an image, a regular request is sent to the appropriate source server.

The Sink Distributor’s requests for data items are routed equally to all source servers until one or more source servers reaches a predefined threshold limit. Since the source servers are sent requests in parallel, the cache for all source servers will be used at a fairly equal rate.

After one or more source servers has reached the service threshold, requests are routed equally to all servers not at threshold. This process of filling source servers in parallel continues until all of the servers have reached their threshold. Capacity at threshold does not mean that a server is full, but that it is almost full. Once all source servers reach threshold, the requests are routed to the least loaded servers. When all servers are full, lower priority data items are picked for preemption from source server cache.

If the datafeed line fails, the source server marks its items as being stale and monitors the datafeed line. This allows each Sink Distributor to re-request the items previously supported by the failed source from the remaining available source servers. When the failed line becomes active, the source server announces that it is back on the network.

SFC Developer’s Guide 357

Page 372: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.5.2 Full Resource Management and Request Routing with the Service Distributor

The Service Distributor implements many of the advanced information resource management features of SSL 4.0. It is capable of running on the same node as other components, but will typically be run on its own dedicated node. A single Service Distributor is capable of managing multiple services at the same time. It ensures that requests made by a Sink Distributor are directed to the most appropriate Source Distributor at the optimal rate.

The Service Distributor is an internal piece of the SSL Infrastructure and is not directly accessed by application software. This optional piece of Triarch is designed to reduce network message traffic, provide better request routing among source applications within services, and manage global service preemption. It is increasingly effective as the number of Sink Distributors and the number of source servers that make up a service increase.

The Service Distributor provides the following added benefits for any services that it manages:

• The Service Distributor ensures that requests from a Sink Distributor are directed to the optimal Source Distributor. No polling of servers is required to locate cached items. The Service Distributor has knowledge of all open cache slots and uses this knowledge to efficiently route requests and to manage preemption of data from cache.

• When necessary, the Service Distributor leads the recovery process for a failed source server based on its knowledge of where items watched by all of the Sink Distributors on the network are cached. (Refer to the SSL 4.0 Architecture Overview for more information about this feature.)

When the Service Distributor is operating, request traffic is directed from the Sink Distributor to the Service Distributor (for applicable services). Using the information it maintains on the cache list for each managed source server and the ability of each server to service requests, the Service Distributor is able to direct these requests to the optimal Source Distributor. Responses to these requests, and subsequent updates, flow directly to the requesting Sink Distributor.

When the Service Distributor is restarted after a failure or interruption, it automatically downloads the necessary information from the Source and Sink Distributors to enable it to restore full information resource management without manual intervention.

In Figure B.6, requests are routed through the Service Distributor. Responses are sent back to the requesting application.

SFC Developer’s Guide 358

Page 373: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

Figure B.6: Service Distributor Resource Management

B.5.3 System Resiliency (“Failover”)Resilience is a system property which minimizes disruption of service in the event of a system failure. A resilient aspect of the Triarch network is its ability to share the load carried by a datafeed among other available datafeeds of the same type. When a source server goes down, capacity is absorbed by the remaining servers of the same type on the network. The server loss has little effect on applications through the complete use of available Triarch facilities. In addition, resilience is enhanced by the functionality provided for request routing.

If one of the source servers fails, the system informs user applications on an item-by-item basis that service has been interrupted. The system will try to retrieve the data from other sources within the service, and will maintain the stale state of such data until the data is retrieved from another server or the original server is back up.

When a failed source server recovers or when a new server is added, the system automatically registers this action. As servers or services are added to or removed from the network, the SSL

Source Server

SourceServer

DatafeedDatafeed

ServiceDistributor

SinkDistributor

Application

Request RoutingResponse Routing

SFC Developer’s Guide 359

Page 374: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

Infrastructure tracks this activity. The system is dynamic; i.e., a new workstation may be added without restarting the system. When an additional source server of an existing type is added to the network, the network protocol ensures that all workstations are automatically able to access it. When a new service is added to the network, the protocol ensures that workstations are informed.

The network protocol suite supports “Keep Alive” messages from both sources and sinks. These messages, which are sent out at regular intervals, are used to detect the presence and absence of network nodes. Keep Alive messages are particularly important for source servers. Sinks, and the Service Distributor when active, receive these messages from all active sources and use this information in deciding where to address requests for data items.

If a source fails, the Keep Alive messages from that server are no longer seen by the sinks. After the absence of several such messages, a sink presumes that the server has failed, and any data from the failed source is immediately marked as stale. If another source server can provide this data, the data will be retrieved from it. Otherwise, the system places the items in an automatic recovery queue and maintains the stale status of this data until the source recovers or the application is no longer interested in the data. The sinks stop sending requests to a failed source until that source server has recovered and again sends Keep Alive messages.

NOTE: The length of time a sink (or source) will wait before assuming failure of a node is a config-urable parameter. This time interval should be kept fairly short to ensure that any data that has recently become stale is not presumed to be valid.

SFC Developer’s Guide 360

Page 375: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6 SSL Library Configuration

B.6.1 OverviewThe SSL Library configuration file provides a centralized configuration database functionality for all SSL applications. This allows for consistent SSL Library behavior across many interrelated nodes and applications. In addition, tuning and troubleshooting of SSL applications may be performed without program recompilation. The SSL Library configuration file consists of a number of configuration variable settings which may be specified on a per installation, per hosts, or per application name basis.

B.6.2 File Entry Rules and Formats

B.6.2.1 Location of the FileThe location of the SSL Library configuration file is determined by the value of the SSLAPI_CONFIG environment variable or the \HKEY_LOCAL_MACHINE\Software\Reuters\SSL\SSLAPI_CONFIG registry entry. These variables can be used to point the ssl api configuration to the same file that the SFC application is using for configuration. If a sslapi.cnf file exists in the current directory, it will always be used instead of the configured file. If the sslapi.cnf file does not exist, the ipcroute file will be located per SSL 4.0 guidelines.

B.6.2.2 Special Configuration File Entry CharactersThe configuration file uses the # (hash mark) character as the comment character. A commented line must have the # character as the first non-white-space character on the line.

Each entry in the configuration file contains two fields separated by the ‘:’ character. The first field is the parameter specification and the second field is the parameter value. The syntax of a database entry is defined below.

B.6.2.3 Configuration File Entry FormatThe configuration file entry format is as follows:

<ClientHost>.<AppInstanceID>.<AppName>.<SSLVersion>.<ParamName>:<ParamValue>

where:

SFC Developer’s Guide 361

Page 376: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.2.4 Binding of Configuration EntriesEntries in the SSL Library configuration file can be bound together in two ways:

• tightly with a . (dot) character, or

• loosely with an * (asterisk) character.

A tight binding signifies that the qualifiers on either side of the binding must be sequential (i.e., in the order specified). An entry with a loose binding begins with an *. The loose binding works as a wildcard enabling zero or more unspecified qualifiers between the loosely bound qualifiers. Loose bindings serve the purpose of allowing matching of several possible entries and will still match if the entries change within the wildcarded section.

For example, the following entry sets event logging file size to 5000 bytes for all SSL applications:

*eventLogging:5000

However, if applications running on node test1 require a larger file size, the following can be specified:

ClientHost is the name of the machine where the application that requests con-nection to the SSL Library will run.

AppName is a string which identifies the SSL application on the machine.

AppInstanceID is used to uniquely identify an instance of an application with a spe-cific AppName on the specific ClientHost.

SSLVersion is used to restrict the version number of the SSL Library to which the entry applies. For SSL Library version 4.5, specify “SSLAPI_V45” .

ParamName is the name of the configuration variable.

CAUTION: Do not put any whitespace between the parameter name and the colon that follows it. If whitespace is found, the parameter will not be recognized and, thus, will be ignored.

ParamValue is a string which is the value assigned to the ParamName.

SFC Developer’s Guide 362

Page 377: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

test1*eventLogging:20000

B.6.2.5 Order of PrecedenceThe SSL Library configuration file need not contain a specification for every available parameter. The Library has built-in default values for all parameters. If a parameter specification is omitted from the configuration file, the corresponding default takes effect.

An SSL application may choose to override a value specified in the configuration file at run time. This can be done by setting a mount option or via an sslSetProperty() function call, but only for those configuration parameters which have a corresponding SSL_ property.

The SSL Library determines the value of every configuration variable by the following order of precedence:

B.6.2.6 Updating the Configuration FileIn addition to run-time property setting, the SSL Library allows updates to the configuration file to take affect without restarting the application. This is accomplished by retrieving parameter values in the course of executing appropriate SSL function calls. For example, the numBuffers parameter is examined every time an sslSnkMount() call is issued or when a session reconnection attempt is made.

B.6.3 Valid Configuration File Parameters

B.6.3.1 eventLogging

Default Value: 10000 (bytes)

Related Property: SSL_OPT_LOG_EVENT_FAIL

Becomes Effective: sslQueryInterface() call

Run-timeproperty setting

Configuration file setting

SSL Librarydefault

SFC Developer’s Guide 363

Page 378: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.2 functionLogging

B.6.3.3 ipcConnectionTimeout

B.6.3.4 ipcRoute

Parameter Function: Automatically enables the logging of event handling failures with a specified file size. The name of the log file is SSL_elog<pid>, where <pid> is a unique numeric process ID assigned by the operating sys-tem.

Default Value: 10000 (bytes)

Related Property: sslErrorLog() call

Becomes Effective: sslQueryInterface() call

Parameter Function: Automatically enables function call error logging with a specified file size. The name of the log file is SSL_elog<pid>, where <pid> is a unique numeric process ID assigned by the operating system.

Default Value: 10 (seconds)

Related Property: None

Becomes Effective: sslSnkMount() call

Parameter Function: Controls the amount of time the sslSnkMount() call is allowed to take when making a connection to a source application.

Default Value: Source application: Not Used Sink application: triarch_sink localhost

Related Property: None

Becomes Effective: sslSnkMount() or sslMsgMount() call

SFC Developer’s Guide 364

Page 379: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.5 ipcRouteName

Parameter Function: Allows specification of the SSL IPC server and host name pair.

Syntax 1:*ipcRoute: ipcService [hostname...]

Syntax 2:*name1.ipcRoute: ipcService [hostname1...] *name2.ipcRoute: ipcService [hostname2...] ...Syntax 1 specifies the TCP service port and host to which a sink application will be connected when no value is set for SSL_SNK_MO_IPC_ROUTE_NAME as part of sslSnkMount().

Syntax 2 allows the sink application to control which port/host it will be connected to when SSL_SNK_MO_IPC_ROUTE_NAME is set to name1 or name2, etc.

Syntax 2 is also used when SSL_SNK_MO_IPC_ROUTE_NAME is not specified on the mount call but instead the ipcRouteName parameter is present. By scoping multiple ipcRouteName entries, a single configuration file can be used by multiple machines to steer each one’s mount requests to a different source host (or port).

Multiple host names may be specified in order to configure redundant source applications. The default hostname is “localhost”. The default ipcService is “triarch_sink”. The ipcService must also be defined in the TCP/IP service definition file (e.g. /etc/services). This parameter is not used by source applications.

Default Value: None

Related Property: Mount option

Becomes Effective: sslSnkMount() or sslMsgMount() call

SFC Developer’s Guide 365

Page 380: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.6 ipcServer

B.6.3.7 maxMounts

Parameter Function: Controls which ipcRoute entry will be used by sink applications that do not specify an SSL_SNK_MO_IPC_ROUTE_NAME value with sslSnkMount(). Only useful if multiple named ipcRoute entries are present. If SSL_SNK_MO_IPC_ROUTE_NAME is specified, that value overrides this parameter. This parameter is not used by source applications. See ipcRoute for more information.

Default Value: None

Related Property: The IPCServerName argument to the sslSrcMount() call or the SSL_OPT_IPC_SERVER_NAME property.

Becomes Effective: sslSrcMount() call

Parameter Function: Allows specification of the name of the SSL IPC service provided by the source application. The ipcServer must also be defined in the TCP/IP service definition file (e.g. /etc/services). This parameter is not used by sink or message applications.

Default Value: 4 less than the per-process file descriptor limit set by the operating system

Related Property: SSL_SRC_MAX_SESSIONS

Becomes Effective: sslSrcMount() call

Parameter Function: Controls the maximum number of sessions supported by a single source channel.

SFC Developer’s Guide 366

Page 381: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.8 maxProcessBuffers

B.6.3.9 maxRemountDelay

B.6.3.10 maxUnconfirmedMsgs

Default Value: 1048576

Related Property: None

Becomes Effective: sslQueryInterface() call

Parameter Function: Controls the maximum number of 3300-byte message buffers that can be dynamically allocated for a single process for its buffer pool. Buffers from the pool are shared between channels up to this per-pro-cess limit.

Default Value: 30 (seconds)

Related Property: SSL_SNK_MAX_RETRY_DELAY

Becomes Effective: sslSnkMount() call or successful channel recovery

Parameter Function: Controls the maximum delay between channel reconnection attempts.

Default Value: 10

Related Property: SSL_OPT_MAX_UNCONFIRMED_MSG_COUNT

Becomes Effective: SSL_ET_SESSION_ACCEPTED event and sslSnkMount() call

Parameter Function: Controls the setting of the preferred number of unconfirmed IPC mes-sages.

SFC Developer’s Guide 367

Page 382: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.11 messageTracing

B.6.3.12 messageTracingFlags

B.6.3.13 minRemountDelay

Default Value: 10000 (bytes)

Related Property: None

Becomes Effective: sslQueryInterface() call

Parameter Function: Automatically enables IPC message tracing with the specified file size. The name of the log file is IPCTRACE<pid>, where <pid> is a unique numeric process ID assigned by the operating system.

Default Value: None

Related Property: None

Becomes Effective: sslQueryInterface() call

Parameter Function: Controls the granularity of message formatting in the message trace file. Any or all of the following valid flags may be specified:SSL_TRACE_IN — Trace inbound messages.SSL_TRACE_OUT — Trace outbound messages.SSL_TRACE_DATA — Trace data portion of the message.SSL_TRACE_HEX — Include hex dump of traced data.

Default Value: 1 (second)

Related Property: SSL_SNK_MIN_RETRY_DELAY

Becomes Effective: sslSrcMount() or successful channel recovery

Parameter Function: Controls the minimum delay between channel reconnection attempts.

SFC Developer’s Guide 368

Page 383: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.14 msgMountDelimiter

B.6.3.15 numInputBuffers

B.6.3.16 numOutputBuffers

Default Value: “-”

Related Property: Mount option

Becomes Effective: sslMsgMount() call

Parameter Function: Controls the delimiter in the sslMsgOpen() filter string.

Default Value: 2

Related Property: None

Becomes Effective: SSL_ET_SESSION_ACCEPTED event or sslSnkMount() call

Parameter Function: Controls the number of 3300-byte SSL message input buffers used to handle and store incoming messages per channel. There must be at least two input buffers per channel.

Default Value: 3000

Related Property: None

Becomes Effective: SSL_ET_SESSION_ACCEPTED event or sslSnkMount() call

Parameter Function: Controls the maximum number of 3300-byte output buffers that can be used to handle and store outgoing SSL messages per channel. Two buffers are allocated per SSL channel and additional buffers can be taken from the dynamic buffer pool up to this per-channel limit.

SFC Developer’s Guide 369

Page 384: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.17 pingInterval

B.6.3.18 serviceId

Default Value: 20 (seconds)

Related Property: SSL_OPT_SESSION_TIMEOUT

Becomes Effective: SSL_ET_SESSION_ACCEPTED event and sslSnkMount() call

Parameter Function: Controls the amount of time that a channel is allowed to remain idle. Ping messages are sent automatically by the SSL Library to ensure that the channel remains operational. Session timeout occurs if no response is received to three consecutive ping messages. (Note that since the ping interval used is the lesser of the values set for the source and client applications, in order to increase the timeout from the default, the value of this parameter must be increased on both sides.)

The minimum value for pingInterval is 3 seconds.

Default Value: None

Related Property: None

Becomes Effective: SSL 4.0 session establishment

SFC Developer’s Guide 370

Page 385: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.3.19 snkResponseThrottle

B.6.3.20 tcpQuickAck

Parameter Function: Controls the mapping of service names to numeric service IDs. Required for every service so that the source application can support Bandwidth Enhancement capabilities. Used when an SSL 4.0 sink application is connected to an SSL 4.5 source application and the sink application requires access locks. This parameter is used to translate permission data format into access lock format. The servi-ceId parameter must be specified as a suffix of the string containing the actual service name; e.g.: IDN_SELECTFEED.serviceID: 20. This statement assigns a service ID of 20 to the IDN_SELECTFEED service.

Default Value: 10 (requests)

Related Property: SSL_SNK_RESPONSE_THROTTLE

Becomes Effective: SSL_ET_SESSION_ACCEPTED event or sslSnkMount() call

Parameter Function: Controls the number of outstanding image requests on a channel. (If this is set too high, it could cause the SSL channel to be cut.)

Default Value: FALSE

Related Property: None

Becomes Effective: sslSnkMount() or sslSrcMount() calls

SFC Developer’s Guide 371

Page 386: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

B.6.4 Sample Configuration FileThe following example illustrates various configuration file parameters:

## All apps will try initial connect for 10 seconds*ipcConnectionTimeout: 10## Default for all sink applications on all hosts*ipcRoute: ssl_sink richs236## Allow sink applications to specify which RDF to mount to# by using SSL_SNK_MO_IPC_ROUTE_NAME on the sslSnkMount() call.*rdf1.ipcRoute: triarch_sink rdfchgwc0102*rdf2.ipcRoute: triarch_sink rdfchgwc0202## SSL4.5 sink applications on richs256, with a route name of# “sink_client”,connect to the service named “ssl_sink” on host # richs128richs256*SSLAPI_V45.ipcRouteName: sink_client*sink_client.ipcRoute: ssl_sink richs128# # Service ID translation*IDN_RDF.serviceId: 25*IDN_SELECTFEED.serviceId: 20## Concurrent source sessions and max unconfirmed messages*maxMounts: 10*maxUnconfirmedMsgs: 15

Parameter Function: Enable or disable the TCP_QUICKACK socket option from the SSL configuration file, sslapi.cnf . It is disabled by default and is effective only on Linux platforms.

If the TCP_QUICKACK socket option is enabled, the ACK packet will be sent immediately, and the latency spikes problem will be reduced. However, setting the TCP_QUICKACK socket option might cause a performance problem on SSL API, and the latency result may vary across hardware/OS platforms.

SFC Developer’s Guide 372

Page 387: sfc

APPENDIX B: TRIARCH INFRASTRUCTURE

## Session timeout is 3X pingInterval*pingInterval: 10*msgMountDelimiter: +## Disable message trace#*messageTracingFlags: SSL_TRACE_IN SSL_TRACE_OUT SSL_TRACE_DATA SSL_TRACE_HEX#*messageTracing: 20000## Enable logging*functionLogging: 20000*eventLogging: 20000

SFC Developer’s Guide 373

Page 388: sfc

APPENDIX C: TIB INFRASTRUCTURE - SASS2

C.1 Overview

The TIB infrastructure uses the SASS protocol to deliver market data to client applications over a Rendezvous network. The infrastructure is highly scaleable. It broadcasts updates to take advantage of a large number of users looking at the same data.

See TIB/Rendezvous Concepts for more information on Rendezvous.

C.2 Architecture

The SFC on TIB enables client applications to either publish data or consume data from a TIB infrastructure using Rendezvous. A TIC must be used to cache published data. The SASS2 protocol must be used with the TIB infrastructure. Figure C.1 illustrates the possible deployments that can be achieved. The following the sections describe the type of deployment that can be interfaced to by the SFC API.

C.2.1 TIC-based Publish/SubscribeIn a TIC-based publish/subscribe, the data that is published from the publishing application need not contain a complete set of fields. The intermediate application, the TIC, will cache the image, and provide delta updates to the client applications. All that needs to be sent are the fields that have changed.

NOTE: It is necessary that a publisher provide a record template when operating with an SFC client or the TIC will not cache the data. Record template also must be supplied to support historical Ren-dezvous based market data products

SFC Developer’s Guide 374

Page 389: sfc

APPENDIX C: TIB INFRASTRUCTURE - SASS2

Figure C.1: SFC Applications in a TIB Infrastructure

C.2.2 Publishing to Support ciServer SubscribersIn order to support older ciServer-based applications via a TIC, a publishing application must supply a record template number. This template number allows the TIC to coerce the data into the QForm data format required by these applications. The record format is used by ciServer-based clients in order to extract the fields that are in the data. An SFC publisher can publish the record template number in the

Network

SFCPublishingApplication

TIC(Cache Process)

ciServer-BasedConsumerApplication

SFC RV-BasedConsumerApplication

RV Daemon

Data Flow

RV Daemon ciServer Daemon

Data FlowData Flow

ciServer DaemonRV Daemon

Data FlowData FlowData Flow

Data Flow Data Flow

SFC Developer’s Guide 375

Page 390: sfc

APPENDIX C: TIB INFRASTRUCTURE - SASS2

REC_TYPE field using the setRecordTemplateNumber(RTRString *) method. See section 5.5.3 for details.

C.2.3 ConfigurationThe following things may need to be configured in the TIC configuration file to support the SFC:

1. Communicate via Rendezvous and the SASS2 protocol. (This can be done for both publishing clients and subscribing clients.)

RV_TRANSPORT_IN TRUE; RV_TRANSPORT_OUT TRUE;RV_SASS2_SUPPORT TRUE;

2. If you use the RTRTIBFidDb (which is needed to download the data dictionary from the TIC), you must configure a TIC to send the data dictionary to clients.

PROVIDE_DATA_DICTIONARY TRUE;

3. If you are publishing to a new service, you must configure a TIC to accept the messages for that service.

BROADCAST{

SOURCE “MYSOURCE”;# ...

}

4. If any of the the following configuration values are specified in the TIC configuration file:

RV2_OUTPUT_SERVICERV2_OUTPUT_NETWORKRV2_OUTPUT_DAEMONRV2_PUBLISH_SERVICERV2_PUBLISH_NETWORKRV2_PUBLISH_DAEMON

Then SFC publishers will need to include the following configuration in the SFC configuration file:

TIBDistribution*pingInterval : 0

SFC Developer’s Guide 376

Page 391: sfc

APPENDIX C: TIB INFRASTRUCTURE - SASS2

Also, to download a dictionary for the publisher, a RTRTIBFidDb will need to be created external to the publishing service, using a different RTRTIBConnection. See section 5.5.4.3 for an example of the workaround.

Other configuration may be needed depending on your environment and usage.

If TIB Entitlements 4 (ETIC) is configured to send entitlement data on a different multicast channel or broadcast service port than the data from the TIC, then SFC will need to be configured to use the global entitlement session. See section 5.5.10 for details on how to set the configuration parameters. See section 4.8.1.3 for information on how to set the parameters programmatically.

SFC Developer’s Guide 377

Page 392: sfc

APPENDIX D: TIB INFRASTRUCTURE - SASS3

D.1 Overview

The TIB infrastructure can be configured to use the SASS3 protocol, also used by RMDS, to deliver market data over TIBCO Rendezvous. In a TIB SASS3 infrastructure, the protocol, entitlement system, and data quality (DQA) mechanisms are the same as RMDS, but the data content is the same as a TIB network.

See TIBCO Rendezvous Concepts for more information on Rendezvous.

D.2 Architecture

The SFC enables client applications to either publish data or consume data from a TIB SASS3 infrastructure using Rendezvous. The TIC must be version 10.x or later. Figure D.1 illustrates the possible deployments that can be achieved.

Figure D.1: SFC Applications in TIB SASS3 Infrastructure

TIC

RV Daemon

Distribution Layer (TIB/RV)

SFC TIB-BasedConsumer

SFC TIB-BasedPublisher

RV Daemon

RV DaemonDACS Daemon

DACSServer

SFC Developer’s Guide 378

Page 393: sfc

APPENDIX D: TIB INFRASTRUCTURE - SASS3

The TIC in Figure D.1 can be replaced with a DTIC. To support a DTIC, the SFC’s service provider discovery mechanism must be disabled. See section 5.5.6.2 for details. In the rest of this section, DTIC can be interchanged with TIC.

The following sections describe the type of deployment that can be interfaced to by the SFC API.

D.2.1 TIB-Based PublisherThe TIB record publishing implemenation in SFC can be used to publish locally on the Rendezvous broadcast network. The TIC must be configured to accept messages for that service. The data is published in TIBMsg self-describing format using the SASS3 protocol. TIB field definitions are used (either loaded from the tss_fields.cf files or downloaded from a TIC).

D.2.2 TIB-Based ConsumerThe TIB page and record subscription implementations in SFC can be used to request data on the distributions network. The data could be delivered in TIBMsg self-describing or QForm format. The data will be using TIB field definitions. As long as field names are used instead of FID numbers, SFC will hide the data format and semantics from the application, so it does not need to be concerned with the underlying data format.

Entitlement checking is performed in the consumer application. A DACS sink daemon must be run on the client to retrieve an entitlement profile from the DACS server.

The field definitions that SFC uses can programmatically be overridden by passing a RTRFidDb into a service. If this is done, both the source and client applications must be configured the same way so they can understand the data.

D.3 TMF

The SFC enables client applications to consume data from either a SASS3 TIC or SASS3 TMF in a TIB infrastructure. A TIC must be set up to publish images and updates separately. The TMF receives the updates from the TIC, aggregates the updates, and publishes the updates out on the distribution LAN. Figure D.2 illustrates a possible deployment that can be achieved.

NOTE: It is necessary that a publisher provide a record template when operating with an SFC client or the TIC will not cache the data. Record template also must be supplied to support historical Ren-dezvous based market data products

SFC Developer’s Guide 379

Page 394: sfc

APPENDIX D: TIB INFRASTRUCTURE - SASS3

SFC can set TMF connection parameters either with configuration (section 5.5.10.1) or programmatically (section 4.8.1.3).

Figure D.2: SFC Application in TIB SASS3 infrastructure with TMF

D.4 Configuration

The following things may need to be configured to support SFC on your TIB SASS3 infrastructure:

1. Rendezvous and SASS3 must be enabled in the client communication configuration file (typically tic.cf or dtic.cf).

RV_TRANSPORT_IN TRUE; RV_TRANSPORT_OUT TRUE;RV_SASS3_SUPPORT TRUE;

2. If you use the RTRTIBFidDb to download the data dictionary from the network, you must configure the TIC to send the data dictionary to clients in the tic.cf.

TICimage port: 7501update port: 7505

TMFupdate(in) port: 7505update(out) port: 7600

RV Daemon

Distribution Layer (TIB/RV)

SFC TMF Subscriberimage port: 7501update port: 7600

RV Daemon RV Daemon

RV Daemon

SFC TIC Subscriberimage port: 7501update port: 7505

SFC Developer’s Guide 380

Page 395: sfc

APPENDIX D: TIB INFRASTRUCTURE - SASS3

PROVIDE_DATA_DICTIONARY TRUE;

3. If you are publishing to a new service, you must configure tic.cf to accept the messages for that service.

BROADCAST{

SOURCE “MYSOURCE”;# ...

}

4. If any of the the following configuration values are specified in the tic.cf:

RV3_OUTPUT_SERVICERV3_OUTPUT_NETWORKRV3_OUTPUT_DAEMONRV3_PUBLISH_SERVICERV3_PUBLISH_NETWORKRV3_PUBLISH_DAEMON

then SFC publishers will need to include the following configuration in the SFC configuration file:

*enablePingSubscription : false

Also, to download a dictionary for the publisher, a RTRTIBFidDb will need to be created external to the publishing service, using a different RTRTIBConnection. See section 5.5.4.3 for an example of the workaround.

5. The following configuration variables must be set in TMF’s configuration file:

SUPPORT_SASS3 TRUERV_UPDATE_SERVICE # match value from RTIC’s RV3_OUTPUT_SERVICERV_UPDATE_NETWORK # match value from RTIC’s RV3_OUTPUT_NETWORKRV_INITIAL_SERVICE # match value from RTIC’s RV3_SERVICERV_INITIAL_NETWORK # match value from RTIC’s RV3_NETWORK

Services must be included in SUBJECTS. For example

SUBJECTS{

ISFS...;

SFC Developer’s Guide 381

Page 396: sfc

APPENDIX D: TIB INFRASTRUCTURE - SASS3

IDN_RDF...;}

6. SFC’s updateService and updateNetwork configuration variables must match these values in the TMF’s configuration file:

RV_OUT_SERVICERV_OUT_NETWORK

7. For the TIC to detect when broadcast, local publishers die, the following configuration must be set:

BC_DQA_MODE TRUE;FEED_FAIL_TIMEOUT 120; # if a message not received every 120

# seconds stale messages are sent for all items.

This mechanism requires TIC 10.1 or later. The groupId must also be configured in the SFC publisher. See section 5.5.5.1 for details.

Other configuration may be needed depending on your environment and usage.

SFC Developer’s Guide 382

Page 397: sfc

APPENDIX E: RMDS INFRASTRUCTURE

E.1 Overview

In addition to supporting the Triarch and TIB infrastructures, the SFC implementations in this release can transparently support the Reuters Market Data System (RMDS) infrastructure. The RMDS infrastructure combines an RRDP-based Market Data Hub with TIBCO Rendezvous distribution to trading floor applications.

If the RTIC is configured to support legacy TIB applications, it behaves more like a SASS3 TIC. While the architecture in this Appendix still applies, for most of the SFC implementation details discussed in Chapter 5, the application will need to be configurated as if it were deployed on a TIB/SASS3 infrastructure. See Appendix E.4 for details on how to detect if an RTIC is configured to support legacy TIB applications.

See TIBCO Rendezvous Concepts for more information on Rendezvous.

E.2 Architecture

The SFC enables client applications to either publish data or consume data from an RMDS infrastructure using Rendezvous. An RTIC must be used to connect RRDP and Rendezvous networks and to cache published data. Figure E.1 illustrates the possible deployments that can be achieved.

SFC Developer’s Guide 383

Page 398: sfc

APPENDIX E: RMDS INFRASTRUCTURE

Figure E.1: SFC Applications in an RMDS Infrastructure

RRDP Market Data Hub

Datafeeds &Feed Handlers

SourceDistributor

SourceDistributor

RTIC

RV Daemon

TSA Distribution Layer (TIB/RV)

SFCSSL-BasedPublisher

SFC TIB-BasedConsumer

SFC TIB-BasedPublisher

RV Daemon

RV DaemonDACS Daemon

DACSServer

SourceDistributor

SFC Developer’s Guide 384

Page 399: sfc

APPENDIX E: RMDS INFRASTRUCTURE

The RTIC in Figure E.1 can be replaced with a DTIC for RMDS (RDTIC). To support an RDTIC, the SFC’s service provider discovery mechanism must be disabled. See section 5.5.6.2 for details. In the rest of this section, RDTIC can be interchanged with RTIC.

The following sections describe the type of deployment that can be interfaced to by the SFC API.

E.2.1 SSL-Based PublisherThe SSL record publishing implementation in SFC can be used to publish directly to a Source Distributor on the RRDP Market Data Hub. The Source Distributor must be configured to connect to the SFC-based source application. The data is published in Marketfeed format using the SSL protocol. IDN field definitions are used (loaded from the appendix_a and enumtype.def files using a RTRFileFidDb).

E.2.2 TIB-Based PublisherThe TIB record publishing implemenation in SFC can be used to publish locally on the Rendezvous broadcast network. The RTIC must be configured to accept messages for that service. The data is published in TIBMsg self-describing format using the SASS3 protocol. Triarch field definitions are used (either loaded from the appendix_a and enumtype.def files or downloaded from a RTIC).

E.2.3 TIB-Based ConsumerThe TIB page and record subscription implementations in SFC can be used to request data on the RMDS distribution network. The data could be delivered in TIBMsg self-describing or Marketfeed format. The data will be using IDN field definitions. As long as field names are used instead of FID numbers, SFC will hide the data format and semantics from the application, so it does not need to be concerned with the underlying data format.

Entitlement checking is performed in the consumer application. A DACS sink daemon must be run on the client to retrieve an entitlement profile from the DACS server.

The field definitions that SFC uses can programmatically be overridden by passing a RTRFidDb into a service. If this is done, both the source and client applications must be configured the same way so they can understand the data.

SFC Developer’s Guide 385

Page 400: sfc

APPENDIX E: RMDS INFRASTRUCTURE

E.3 TMF

The SFC enables client applications to consume data from either an RTIC or TMF in an RMDS infrastructure. An RTIC must be set up to publish images and updates separately. The TMF receives the updates from the RTIC, aggregates the updates, and publishes the updates out on the distribution LAN. Figure E.2 illustrates a possible deployment that can be achieved.

SFC can set TMF connection parameters either with configuration (section 5.5.10.1) or programmatically (section 4.8.1.3).

SFC Developer’s Guide 386

Page 401: sfc

APPENDIX E: RMDS INFRASTRUCTURE

Figure E.2: SFC Applications in RMDS infrastructure with TMF

RTICimage port: 7501update port: 7505

RRDP Market Data Hub

Datafeeds &Feed Handlers

SourceDistributor

SourceDistributor

TMFupdate(in) port: 7505update(out) port: 7600

RV Daemon

Distribution Layer (TIB/RV)

SFCSSL-BasedPublisher

SFC TMF Subscriberimage port: 7501update port: 7600

RV Daemon RV Daemon

RV Daemon

SFC RTIC Subscriberimage port: 7501update port: 7505

SFC Developer’s Guide 387

Page 402: sfc

APPENDIX E: RMDS INFRASTRUCTURE

E.4 Configuration

The following things may need to be configured to support SFC on your RMDS infrastructure:

1. Rendezvous and SASS3 must be enabled in the client communication configuration file (typically rtic.cf or rdtic.cf).

RV_TRANSPORT_IN TRUE; RV_TRANSPORT_OUT TRUE;RV_SASS3_SUPPORT TRUE;

2. If you use the RTRTIBFidDb to download the data dictionary from the network, you must configure the RTIC to send the data dictionary to clients in the rtic.cf.

PROVIDE_DATA_DICTIONARY TRUE;APPENDIX_A /var/triarch/appendix_aENUMTYPE_DEF /var/triarch/enumtype.def

3. If you are publishing to a new service, you must configure rtic.cf to accept the messages for that service.

BROADCAST{

SOURCE “MYSOURCE”;# ...

}

4. If any of the the following configuration values are specified in the rtic.cf:

RV3_OUTPUT_SERVICERV3_OUTPUT_NETWORKRV3_OUTPUT_DAEMONRV3_PUBLISH_SERVICERV3_PUBLISH_NETWORKRV3_PUBLISH_DAEMON

then SFC publishers will need to include the following configuration in the SFC configuration file:

*enablePingSubscription : false

SFC Developer’s Guide 388

Page 403: sfc

APPENDIX E: RMDS INFRASTRUCTURE

Also, to download a dictionary for the publisher, a RTRTIBFidDb will need to be created external to the publishing service, using a different RTRTIBConnection. See section 5.5.4.3 for an example of the workaround.

5. If the following configuration is in the RTIC’s Market Data Hub configuration file (typically triarch.cnf):

*sectorName : REC ! anything besides the default value “ANY”

and SFC includes the configuration

*serviceProvider : RTIC

then SFC must configure the default sector.

*defaultSector : REC

See section 5.5.6.2 for details.

6. The following configuration variables must be set in TMF’s configuration file:

SUPPORT_SASS3 TRUEAPPENDIX_A /var/triarch/appendix_aENUMTYPE_DEF /var/triarch/enumtype.defRV_UPDATE_SERVICE # match value from RTIC’s RV3_OUTPUT_SERVICERV_UPDATE_NETWORK # match value from RTIC’s RV3_OUTPUT_NETWORKRV_INITIAL_SERVICE # match value from RTIC’s RV3_SERVICERV_INITIAL_NETWORK # match value from RTIC’s RV3_NETWORK

Services must be included in SUBJECTS. For example

SUBJECTS{

ISFS...;IDN_RDF...;

}

7. SFC’s updateService and updateNetwork configuration variables must match these values in the TMF’s configuration file:

RV_OUT_SERVICERV_OUT_NETWORK

8. For the RTIC to detect when broadcast, local publishers die, the following configuration must be set:

SFC Developer’s Guide 389

Page 404: sfc

APPENDIX E: RMDS INFRASTRUCTURE

BC_DQA_MODE TRUE;FEED_FAIL_TIMEOUT 120; # if a message not received every 120

# seconds stale messages are sent for all items.

This mechanism requires RTIC 10.1 or later. The groupId must also be configured in the SFC publisher. See section 5.5.5.1 for details.

9. If any of the following configuration is set, then the RTIC may have been configured to support legacy TIB applications.

FIELDS “tss_fields.cf”;RECORDS “tss_records.cf”;CI_SASS2_SUPPORT TRUE;CI_TRANSPORT_OUT TRUE;CI_TRANSPORT_IN TRUE;RV_SASS2_SUPPORT TRUE;RV2_*

When this configuration is set, the RTIC has been configured to look like a TIC. SFC applications should be configured as if deployed on a TIB/SASS3 network. SFC does not support the SASS2 or CI protocols to or from an RTIC.

Note that this configuration should only be used for specific migration situations.

Other configuration may be needed depending on your environment and usage.

SFC Developer’s Guide 390

Page 405: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

G.1 DACS_CsLock()

SynopsisDACS_CsLock (nm_channel, item_name, newLock, newLockLen, lockList, Dacs_Error)

int nm_channel char *item_name unsigned char **newLock int *newLockLen; COMB_LOCK_TYPE lockList[]; DACS_ERROR_TYPE *Dacs_Error

DescriptionThis function is called to combine a list of access locks into a single composite DACS access lock. This function is used to form complex access locks from constituent access locks that were created by a previous call to the DACS_CsLock() or DACS_GetLock() functions.

Function Argumentsnm_channel

The nm_channel parameter is no longer used but it must be 0 (zero) for backward compatibility.

item_name The item_name parameter must be an empty string (“”). (This is also for backward compatibility.)

newLock The newLock parameter is a pointer to an unsigned char pointer that shall point to the generated access lock for the “item” built by the source/compound server. If the pointer is NULL on entry to the DACS_CsLock() function, space for the new access lock will be dynamically allocated using malloc(). It is the responsibility for the caller of DACS_CsLock() to free() the memory allocated when the newly generated access lock is no longer required.

SFC Developer’s Guide 391

Page 406: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

newLockLen The newLockLen parameter is updated to reflect the length of the newly generated lock. If the newLock parameter does not point to a NULL pointer, then the source/compound server application must supply the *newLockLen with the maximum size of the user-supplied access lock pointer. If the *newLockLen parameter supplied by the source/compound server application is less then the length required to fit the access lock, a PERM_FAILURE error is returned.

lockList The lockList parameter is a pointer to an array of pointers to the access locks of associated component items to be combined by the source/compound server. A NULL pointer terminates the list.

Dacs_Error The Dacs_Error parameter points to a data structure of type DACS_ERROR_TYPE in which returned errors will be placed.

Data StructuresThe COMB_LOCK_TYPE data structure is defined to be as follows:

typedef struct { int server_type; char *item_name; unsigned char *access_lock; int lockLen; } COMB_LOCK_TYPE;

where:

server_type must be set to 0 (zero).

item_name is a NULL pointer (for backward compatibility).

access_lock is a pointer to the user-supplied access lock that is to be used as one of the constituent item access locks.

lockLen is the length of the access lock. This value was previously returned from a DACS_GetLock() function.

SFC Developer’s Guide 392

Page 407: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

The DACS_ERROR_TYPE data structure is defined to be as follows:

typedef struct { short dacs_error; short dacs_suberr; } DACS_ERROR_TYPE;

Return ValuesThis function returns DACS_SUCCESS if the function did not encounter a fatal error, and the newLock and newLockLen parameters shall be populated.

DACS_FAILURE is returned if a fatal unrecoverable error was encountered. An ASCII explanation of the error can be further determined by passing the Dacs_Error data structure to the DACS_perror() function.

SFC Developer’s Guide 393

Page 408: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

G.2 DACS_GetLock()

SynopsisDACS_GetLock (service_type, ProductCodeList, LockPtr, LockLen, Dacs_Error)

int service_type; PC_LIST *ProductCodeList; unsigned char **LockPtr; int *LockLen; DACS_ERROR_TYPE *Dacs_Error;

DescriptionThis function is used to make a DACS access lock from a list of entitlement codes (i.e., codes specified by the data vendor on which all permissioning is based).

Function Argumentsservice_type

The service_type parameter is used to pass the service type of the server that is to be encoded into the DACS access lock. This value is a unique numeric ID assigned to a Triarch service by the service’s serviceId parameter in the global Triarch configuration file.

ProductCodeList The ProductCodeList parameter is used to pass the list of entitlement codes which shall be encoded into the DACS access lock.

LockPtr The LockPtr parameter is a pointer to an unsigned char pointer that shall point to the generated access lock that represents the entitlement code list in DACS lock format. If the pointer is NULL on entry to the DACS_GetLock() function, space for the new access lock will be dynamically allocated using malloc(). It is the responsibility for the caller of DACS_GetLock() to free() the memory allocated when the newly generated access lock is no longer required.

NOTE: If the DACS_GetLock() function returns an error, then no space for the access lock will have been allocated.

SFC Developer’s Guide 394

Page 409: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

LockLen The LockLen parameter is a pointer to an int. This parameter is updated to reflect the length of the newly generated access lock. If the LockPtr parameter does not point to a NULL pointer on entry, then the user must supply the LockLen with the maximum size of the user-supplied access lock buffer. If the user-supplied LockLen is less then the length required to fit the access lock, then a DACS_FAILURE error is returned.

Dacs_Error The Dacs_Error parameter points to a data structure of type DACS_ERROR_TYPE in which returned errors will be placed.

Data StructuresThe PC_LIST data structure is defined to be as follows:

typedef struct { char operator; unsigned short pc_listLen; unsigned long pc_list[/* pc_listLen */];; } PC_LIST;

where:

operator is the user-supplied operation that shall be imposed on the entitle-ment code list that is supplied. The operator field must have one of the following formats.

The ampersand character ‘&’ (for an “AND” list) — The implication is that the user of the item must be permissioned for all the entitlement codes contained within the access lock.

The vertical bar character ‘|’ (for an “OR” list) — The implication is that the user of the item only needs access to any one of the entitlement codes contained within the access lock.

pc_listLen is used to flag the number of entries that are contained within the pc_list array.

SFC Developer’s Guide 395

Page 410: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

The DACS_ERROR_TYPE data structure is defined to be as follows:

typedef struct { short dacs_error; short dacs_suberr; } DACS_ERROR_TYPE;

Return ValueThis function returns DACS_SUCCESS if the function did not encounter a fatal error.

DACS_FAILURE is returned if a fatal unrecoverable error was encountered. An ASCII explanation of the error can be further determined by passing the Dacs_Error data structure to the DACS_perror() function.

pc_list is a numerically ascending sorted list of unsigned long values that shall be interpreted as the entitlement codes to be encoded into a DACS access lock.

SFC Developer’s Guide 396

Page 411: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

G.3 DACS_CmpLock()

SynopsisDACS_CmpLock (Lock1Ptr, Lock1Len, Lock2Ptr, Lock2Len, Dacs_Error)

unsigned char *Lock1Ptr; int Lock1Len; unsigned char *Lock2Ptr; int Lock2Len; DACS_ERROR_TYPE *Dacs_Error;

DescriptionThis function is used to compare two access locks for equality. This function can be used to verify whether or not a new access lock is different from a previously generated access lock, thus reducing the possible overhead incurred in redistribution of an unchanged access lock.

Function ArgumentsLock1Ptr

The Lock1Ptr parameter is a pointer to the first access lock that is to be compared.

Lock1Len The Lock1Len parameter is an integer. This parameter is the length of the first access lock that is to be compared.

Lock2Ptr The Lock2Ptr parameter is a pointer to the second access lock that is to be compared.

Lock2Len The Lock2Len parameter is an integer. This parameter is the length of the second access lock that is to be compared.

Return ValueThis function returns DACS_SUCCESS if the function did not encounter a fatal error and the access locks were logically identical.

SFC Developer’s Guide 397

Page 412: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

DACS_DIFF is returned if a fatal error was not encountered but the two access locks were logically different.

DACS_FAILURE is returned if a fatal unrecoverable error was encountered. An ASCII explanation of the error can be further determined by passing the Dacs_Error data structure to the DACS_perror() function.

SFC Developer’s Guide 398

Page 413: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

G.4 DACS_perror()

SynopsisDACS_perror (err_buffer, buffer_len, text, Dacs_Error);

unsigned char *err_buffer; int buffer_len; unsigned char *text; DACS_ERROR_TYPE *Dacs_Error;

DescriptionThis function is used to create a textual message describing the last error generated by a DACS Library call. The message is saved to the supplied buffer. The error number is taken from the location Dacs_Error -> dacs_errno variable pointed to by the user application, when a library function returns a DACS_FAILURE.

Function Argumentserr_buffer

The err_buffer parameter contains the destination address for the generated error string. If the supplied buffer is smaller then the generated error string, DACS_FAILURE will be returned.

buffer_len The buffer_len is a variable that indicates the maximum size of the err_buffer.

text The text parameter is a pointer to a null-terminated character string that is placed into the buffer before the DACS error message. This string and the error message will be separated by a colon and a blank space. If an empty character string is specified, only the DACS Library error message will be placed into the err_buffer.

Dacs_Error The Dacs_Error parameter points to a data structure of type DACS_ERROR_TYPE into which returned errors shall be placed.

SFC Developer’s Guide 399

Page 414: sfc

APPENDIX G: DACS LIBRARY FUNCTIONS

Return ValuesThis function returns DACS_SUCCESS if the function did not encounter a fatal error.

DACS_FAILURE is returned if a fatal unrecoverable error was encountered.

SFC Developer’s Guide 400

Page 415: sfc

INDEX

Symbols_RV.ERROR.RV.DATALOSS 309_RV.ERROR.RV.DATALOSS.INBOUND 309_RV.ERROR.RV.DATALOSS.OUTBOUND 309_RV.ERROR.SYSTEM.CLIENT.FASTPRODUCER

308_RV.ERROR.SYSTEM.CLIENT.NOMEMORY 308_RV.ERROR.SYSTEM.CLIENT.SLOWCONSUMER

308_RV.ERROR.SYSTEM.LICENSE.EXPIRE 308_RV.WARN.SYSTEM.EVENTLOOP.STARVATION

308

Aabstraction 6, 7access locks 371, 2accessing pages from a service 162accessing records from a service 43accessing time-series from a service 180addClient() method 19, 196allowUpdatesToChangeStateToOk 308ANSI data 141, 293, 322appendix_a 283, 292, 304, 306application ID 271application name 362assertions 8, 9, 278automatic data recovery 355

BBackus Naur Form (BNF) notation 270boolean type 4buffer read iterator 159, 163buffer write iterator 196buffer_len (DACS Library) 9buffers 367, 369

Ccache 286, 357, 358cache duplication 357cacheType 286channel 348class identifier 245, 250class names 3COMB_LOCK_TYPE structure 2communication protocols 203, 217configuration file 361configuration variables 330configuring software components 244connected() method 204connection parameters 325connection timeout 364contributions 324control loop 13, 46, 260creating record fields 69Custom Event Loop 237

DDACS 270, 355DACS Access Locks 272DACS Daemon 274DACS_CmpLock() 7DACS_CsLock() 1Dacs_Error 2, 5, 9DACS_ERROR_TYPE structure 3, 6DACS_GetLock() 4DACS_perror() 9DACS_retry_connection_interval 274DACS_user_login_retry_interval 275Data dictionary

customizing for performance 283data dictionary 301, 302, 303, 304, 306, 380, 388data item 11data samples 172

SFC Developer’s Guide 401

Page 416: sfc

Index

data statusitem 307service 307

data stream 156, 329database

configuration variables 55, 245, 250, 261field definitions 39, 81, 176

dataLossInboundInterval 309dataLossOutboundInterval 309Debug

configuration 289decimalSize 297decimalSize 292, 297defaultSector 317delimiter character 369design by contract 8dispatchInterval 327DQA 382, 390dropClient() method 19, 32, 196DTIC 311, 379, 385

Eeffects pages 141, 322, 323enableEntitlements() method 269encapsulation 7Entitlements

configuration 276, 326, 327configuration for DACS access locks 272content based entitlements 266Publishing Entitlement Data 267required config for DACS access locks 272required config for publishing DACS locks 272service name mapping requirement 272, 273subject based entitlements 266supported configurations 267Trouble

entitlement data is not published 272lock data does not get published 273

user based entitlements 266enumerations 293err_buffer (DACS Library) 9error logging 364ETIC 340event dispatching loop 235event logging 253event notifier 235events

arrival and departure of services 18field updates 16I/O 236logging 253page state changes 141page updates 149, 167propagation to clients 19, 218received from RTRRTPage 149, 160received from RTRRTRecord 41record state changes 16, 71record udpates 47service state changes 17, 145, 158timing 211

example applications 87

Ffailover 359fault tolerance 354FID database 301fidDbLocation 302field definition 15, 39, 81, 176field identifier 15field updates 34Field-to-Field implementation 87Field-to-SSL implementation 87forceInfrastructureDrivenRecovery 310forceSFCDrivenRecovery 310function names 4

SFC Developer’s Guide 402

Page 417: sfc

Index

GglobalSujectMapFile 316

Hhash table size 279Hint 296historical record of market activity 172

Iimage pacing 287imageInterval 288imagesPerInterval 288Inactive event 21, 23, 29, 76indicateInsertFailed() method 194indicateInsertSucceeded() method 194Infrastructure compatibility 291initialOpenLimit 288In-process RTRRTRecordService Publisher 86insert client 193insert data 193insert server 194insert service 193instance ID 362instance identifier 246, 250IPC mechanism 351IPC message tracing 368ipcRoute 364ipcRouteName 365IPCServerName 366item_name (DACS Library) 1

KKeep Alive messages 360

LlastMessageReceived() method 204

load level 357localSubjectMapFile 316lock 2Lock1Len (DACS Library) 7Lock2Len (DACS Library) 7LockLen (DACS Library) 5lockList (DACS Library) 2LockP1tr (DACS Library) 7LockP2t (DACS Library) 7LockPtr (DACS Library) 4log file 289, 290Logging 278

MMapping SFC symbol names to TIB subject names 85Market Data Hub 264Marketfeed 300, 301maxCache 286memory management guideline 4memory usage 278, 282, 283message buffers 369message read iterator 204message session 203

pseudo-code for reading/writing messages 206TCP implementation 218

message session client 205, 211message write iterator 204MFC 236model

message session 203real-time pages 141, 144, 158real-time record publication 80real-time records 15, 36SFC infrastructure 226software configuration 244TCP client/server 218time-series 172, 175

modularity 7

SFC Developer’s Guide 403

Page 418: sfc

Index

mount option 365MS Windows 13, 249

NN2_UBMS 320Network Management Agent 355newInsert() method 193newLock (DACS Library) 1newLockLen (DACS Library) 2news headlines 320newsEnabled 320newsPrefix 321newsSectorList 321nm_channel (DACS Library) 1notFoundAsRecoverable 307NotStale event 20number_of_items 279, 286, 316

Oopen system design 353openLimit 286outstanding image requests 371

Ppage

attributes 323configuration 323next page 320previous page 320

page client 156, 160page data 141, 145, 158, 163page records 322page service 145, 156, 158page service pool 157page snapshot 148, 160page state 141, 143, 157PC_LIST structure 5

pending limit 284performance 278permissioning 355permissioning information 270ping messages 370pingInterval 370pool events 54preemption 354, 357preemptionLocation 286pre-load SFC’s cache 282, 288price field 292processInsertRequest() method 194processNewSession() method 219processRTRecordServiceAdd() method 54processSeriesComplete() method 191processSessionMessage() method 206processSnapshotSync() method 43processStreamSync() method 163processTimerEvent() method 236processUpdateComplete() method 50ProductCodeList (DACS Library) 4providers of record items 17Published records 61Publisher

source driven 287Publisher service 62pubSubjectPrefix 85putInstanceVariable() method 251

QQForm 379

Rreal-time record 16real-time record model 35REC_TYPE 300, 301record chain 17

SFC Developer’s Guide 404

Page 419: sfc

Index

record client 15, 41record data 15, 37, 80record iterator 33, 37, 38, 81Record publication

accessing records 73adding fields 69Changing record state 72CloseTick event 68CorrectionTick event 68creating new fields 69DACS access lock entitlement format 78GroupNotStale event 76GroupStale event 76Inactive event 67Informational events 67In-process publisher service 86managing record resources 79mapping fiddef types to field types 70mixed mode 65NotStale event 67publishing entitlement data 77publishing to Triarch 83Record Initialization 69record state 65Record state diagram 65removing records 65Resync event 66ResyncComplete event 67resynchronizing record data 73RTRRTRecordImpl 62RTRRTRecordServiceImpl 62sink-driven mode 64source-driven mode 63Stale event 67states and events 69Sync event 66TIB publisher service 85TIB subject names 85

Tick event 68Triarch/SSL application main() 112UpdateComplete event 68Updating record fields 71valid field types 69

Record publishing 61sending message 282setting field 280

record service 17, 39, 81record service pool 18record service state 17record state 15, 19, 71record template 288, 356record templates 292, 300, 301recovery queue 360recovery, led by Service Distributor 358registering interest in

field events 16I/O events 236insert notifications 196page events 141pool events 54record events 15

Rendezvous 5 328Rendezvous 6 328Rendezvous advisory messages 308Rendezvous connection parameters 325Rendezvous Distribution Layer 264request queue 284request routing 355, 358request throttling 354request timing 285requestTS1RealTime 173resiliency 354, 359resource allocation 17resource management 354, 358resource optimization 354, 355resource usage 353

SFC Developer’s Guide 405

Page 420: sfc

Index

response timing 354Resync event 20retry queue 355Reuters Reliable Datagram Protocol (RRDP) 352RIC 312, 314RMDS infrastructure 264RTR prefix 4RTRBOOL 4RTRBufferReadIterator 159, 163RTRConfig 252, 261RTRConfigDb 245, 250, 261RTRConfigVariable 245, 261RTRDefaultConfigDb 252, 262RTRDefaultInsertServicePool 194, 196RTRDefaultLogger 254, 255, 262RTRDefaultRTPageService 36, 146, 159, 165RTRDefaultRTPageServicePool 159RTRDefaultRTRecordService 46RTREventNotifier 13, 235, 260RTREventNotifierInit 235RTRExternalValue 261RTRFidDb 39, 81RTRFidDefinition 15, 39, 82RTRField 280RTRFileFidDb 265, 303, 306RTRInsert 193RTRInsertClient 193RTRInsertService 193, 194RTRInsertServiceClient 194RTRIOClient 236, 260RTRListOfExternalValue 261RTRMDConnection 269RTRMDServiceClient 39, 81, 145, 146, 158, 159RTRMDSServicePoolFactory 331RTRMessageReadIterator 204RTRMessageSession 204, 217RTRMessageSessionClient 204, 205, 211RTRMessageWriteIterator 204

RTRMgmtEvent 253, 262RTRObjectId 245, 247, 261RTRPage 142RTRPageClient 142RTRPageRegion 142RTRPageRegionClient 142RTRPageService 156RTRPageServicePool 157RTRPageServicePoolClient 157RTRRecordChain 17, 19, 39RTRRecordChainClient 17, 19, 39RTRRecordChainElement 17, 19, 39RTRRecordChainElementClient 17, 19, 39RTRRecordChainIteratorPtr 39RTRRegistryDb 250, 262RTRRequestItem 284RTRRTAlphanumericField 16, 61RTRRTField 16, 33, 37, 81, 280RTRRTFieldClient 35, 38, 283RTRRTFieldClients 280RTRRTFieldToFieldRecordService 282RTRRTFieldToSSLRecordService 265RTRRTFieldToTIBRecordService 265RTRRTFieldUpdateList 72, 281RTRRTPage 145, 156, 158RTRRTPageClient 145, 149, 156, 158, 160RTRRTPageService 145, 156, 158RTRRTPageServicePool 145, 157, 158RTRRTPageServicePoolClient 145, 157, 158RTRRTRecord 16, 30, 33, 37, 80RTRRTRecordClient 16, 31, 32, 37, 41, 81RTRRTRecordImpl 62RTRRTRecordImplClient 80RTRRTRecordIterator 37, 50, 81, 280RTRRTRecordService 18, 38, 81RTRRTRecordServiceImpl 62RTRRTRecordServiceIterator 279RTRRTRecordServicePool 18, 38

SFC Developer’s Guide 406

Page 421: sfc

Index

RTRRTRecordServicePoolClient 18, 38, 54RTRRTRecordUpdateIterator 34, 37, 50, 81, 280RTRSelectNotifier 13, 46, 235, 261RTRSeriesValue 176RTRSeriesValueDefinition 176RTRServiceCustomizer 316RTRSimpleSeries 173, 176RTRSnapshotField 16, 38RTRSnapshotRecord 16, 38RTRSnapshotRecordClient 16, 38RTRSnapshotRecordIterator 38RTRSnapshotRecordService 39RTRSSLConnection 265, 268, 270RTRSSLConnectionServer 265, 268, 270, 273RTRSSLDispatcher 165, 265RTRSSLInsertRequest 194RTRSSLInsertService 265RTRSSLPageService 265RTRSSLRTRecordService 265RTRSSLServicePoolFactory 265, 310RTRString 261RTRTcpClientSession 218, 223RTRTcpServerSession 218RTRTcpSessionServer 218RTRTIBConnection 265, 268, 270, 273, 327RTRTIBCustomizer 265, 314, 316, 318, 321RTRTIBFidDb 265, 303, 304, 306RTRTIBPageService 265RTRTIBRTRecordService 265RTRTIBServicePoolFactory 265, 310, 327RTRTimerCmd 211, 236, 261RTRTimeSample 172, 175RTRTimeSeries 172, 175, 187RTRTimeSeriesClient 172, 176, 178RTRTimeSeriesService 173, 176RTRTS1TimeSeriesService 176, 182RTRTSAInsertService 265RTRTSValDefDb 176

RTRTSValDefDbClient 176RTRUTF8String 263RTRWindowsNotifier 235, 236, 261RTRXFileDb 247, 262, 286RTRXtNotifier 241, 261RTRXViewNotifier 243, 261

Ssamples provided by time-series 172SASS3 307, 378sector 311, 312, 314, 322sectorList 316select() system call 13, 261sendInsert() method 196sendSymbolFields 293service 12, 354, 356

added to or removed from network 359Service Distributor 357, 358

restart after failure or interruption 358service ID 272, 276, 371service pool 18, 53service pool factory 302, 310service state 17service_type (DACS Library) 4serviceId 370serviceProvider 311setRecordTemplateNumber() method 301setView() method 187Simple Network Management Protocol (SNMP) 355single open 355sink application 350Sink Distributor 351sink-driven source server 357snapshot record 16snapshot record data 38snkResponseThrottle 371Source Distributor 272, 286, 287, 324source led recovery 358

SFC Developer’s Guide 407

Page 422: sfc

Index

source server 356failure and recovery 359

source-driven 63source-driven source server 357SSL Adapter 311, 312SSL configuration 327, 330SSL implementation 264SSL session 36, 159, 165SSL_ET_SESSION_ACCEPTED event 367, 369,

370, 371SSL_OPT_IPC_SERVER_NAME option code 366SSL_OPT_LOG_EVENT_FAIL option code 363SSL_OPT_MAX_UNCONFIRMED_MSG_COUNT

option code 367SSL_OPT_SESSION_TIMEOUT option code 370SSL_SNK_MAX_RETRY_DELAY option code 367SSL_SNK_MIN_RETRY_DELAY option code 368SSL_SNK_MO_IPC_ROUTE_NAME option code 365,

366SSL_SNK_RESPONSE_THROTTLE option code 371SSL_SRC_MAX_SESSIONS option code 366SSLAPI_CONFIG 361sslErrorLog() 364sslMsgMount() 369sslMsgOpen() 369sslQueryInterface() 363, 364sslSetProperty() 363sslSnkMount() 364, 369, 370, 371sslSrcMount() 371sslSrcMount() 366Stale event 20, 29, 75state transitions 20, 28, 65, 75states 11stopPublicationWhenDACSDowns 274stopSubscriptionWhenDACSDowns 274stream client 156subject map file 316, 317subjectMapSize 316

Sync event 20, 22, 28, 50, 75

TTCP client 218TCP/IP 218, 352, 353, 355tcpNoDelay 327tcpQuickAck 371text (DACS Library) 9text() method 21, 29, 31, 67, 76threads 328threshold limit 357throttle 354, 371TIB 4-part subject 312, 318TIB effects pages 322TIB implementation 264TIB Publisher Service 85timer command 211, 261timer events 236time-series client 172, 178time-series data 172time-series service 173TMF 227, 325, 379, 386Tracing 278trapping log events 254Triarch 264Triarch Publisher Service 83TS1 data 176tss_fields.cf 303, 304, 306, 379

Uunconfirmed messages 367update event 32, 37, 68, 81updateDaemon 325updateNetwork 325updates to record fields 71updateService 325Updating fields 72

SFC Developer’s Guide 408

Page 423: sfc

Index

username 270username method 270

Vvariable() method 247, 250version number 362

WWindows 235Windows NT registry 249

XX-Windows 13, 247

SFC Developer’s Guide 409