question

Upvotes
Accepted
1 0 0 1

RMC API - not showing all variables

I am trying to write a utility that will dump out all the objects/variables from a shared memory segment.

The examples do not show how to do this and my attempt is not working as expected.

I can either get all the 'static variables' but none which are dynamic example, a user making a mount as the program is running.

Or I can get the dynamic variables but then it fails to update when the user is mounted/dismounted/mounted again.

I have attached a modified version of monitorRoots which is what I am trying to get going...

Thanks

Louis



//|---------------------------------------------------------------------------

//| Copyright (C) 1997,2020 Refinitiv --

//| All rights reserved. Duplication or distribution prohibited --

//|---------------------------------------------------------------------------

//

//

//Functionality: This C++ RMC1.0 consumer application displays all the

// root managed object information, all the corresponding

// managed variable information , and all the root

// man. object and man. variable updates as they are generated.

#include <iostream>

#include <sstream>

#include <string>

#include <vector>

#include "monitorRoots.h"


using namespace std;


#define FILTER false


//version 4 should use classes - add to class, value, [lastValue, tmLastValue for showAsRate] , [numerator, denominator for showAsPercentage]

//rename RMCTemplateRecord to RMCField, so an RMCView will contain a vector of RMCField(s)

//figure out how to search this pattern $host.$instance.adh.serviceGenerator.srcPrdServicePool.<key><field>

//how to match pattern <ANY> <NUMBER> <TEXT>

//a single toolkit with hardcoded config

//4.1 make config file attempt to create it?

vector <void *> vecPtr, vecVar;


Monitor::Monitor( RTRProxyManagedObjectServerPool& p ) : _pmosp(p)

{

// Register with the Server Pool to receive events.

_pmosp.addClient(*this);

RTRLinkedListCursor<RTRProxyManagedObjectServer> iter = _pmosp.servers();

for (iter.start(); !iter.off(); iter.forth())

processProxyManagedObjectServerAdded(_pmosp, (RTRProxyManagedObjectServer&)*iter);

}



void Monitor::processProxyManagedObjectSync(const RTRProxyManagedObject& pmo)

{

RTRProxyManagedObjectHandleIterator it = pmo.childHandles();

for (it.start(); !it.off(); it.forth())

{

RTRProxyManagedObjectPtr pmoPtr = pmo.childByName(it.item().name());


if( addToList(pmoPtr) == true)

pmoPtr->addClient( (RTRProxyManagedObjectClient &) *this );


if ( pmoPtr->inSync() == RTRTRUE )

processProxyManagedObjectSync(*pmoPtr);

}


RTRProxyManagedVarHandleIterator pmvIterator = pmo.variableHandles();

for ( pmvIterator.start(); !pmvIterator.off(); pmvIterator.forth() )

{

RTRProxyManagedVariablePtr pmvPtr = pmo.variableByName(pmvIterator.item().name());


if (pmvPtr->error())

continue;


if( addToList(pmvPtr) == true)

pmvPtr->addClient(*this);


if ( pmvPtr->inSync() == RTRTRUE )

processProxyManagedVariableSync(*pmvPtr);

}

}




Monitor::~Monitor()

{

// Be sure to drop client

if ( _pmosp.hasClient(*this) )

_pmosp.dropClient(*this);

}



// Event processing for RTRProxyManagedObjectServerPoolClient

void Monitor::processProxyManagedObjectServerAdded( RTRProxyManagedObjectServerPool& pmosp, RTRProxyManagedObjectServer& pmos)

{

if(pmos.inSync() == RTRTRUE)

processObjectServerSync(pmos);

pmos.addClient(*this);

}


void Monitor::processProxyManagedObjectServerRemoved(RTRProxyManagedObjectServerPool& pmosp, RTRProxyManagedObjectServer& pmos)

{

cout << "pmosp event: Removed a pmos @" << pmos.text() << endl;

pmos.dropClient(*this);

}



//event processing for RTRProxyManagedObjectServerClient

void Monitor::processObjectServerError( RTRProxyManagedObjectServer& pmos)

{

cout << "pmos event: Error @" << pmos.text() << endl;

// Drop client since this Server is no longer valid.

pmos.dropClient(*this);

}


void Monitor::processObjectServerSync(RTRProxyManagedObjectServer& pmos )

{

RTRProxyManagedObjectHandleIterator pmosIterator = pmos.roots();

for ( pmosIterator.start(); !pmosIterator.off(); pmosIterator.forth() )

{

RTRProxyManagedObjectPtr pmoPtr = pmos.object(pmosIterator.item());


if( addToList(pmoPtr) == true)

pmoPtr->addClient( (RTRProxyManagedObjectClient &) *this );


if ( pmoPtr->inSync() == RTRTRUE )

processProxyManagedObjectSync(*pmoPtr);

}

}


void Monitor::processObjectServerRootAdded(RTRProxyManagedObjectServer& pmos,const RTRProxyManagedObjectHandle& pmoH)

{

cout <<"pmos event: Added a root on pmos @" << pmos.text() << endl;


RTRProxyManagedObjectPtr pmoPtr = pmos.object(pmoH);


// Maintain a smart pointer reference to the Proxy Managed Object

if( addToList(pmoPtr) == true)

pmoPtr->addClient( (RTRProxyManagedObjectClient &) *this );


if ( pmoPtr->inSync() == RTRTRUE )

{

cout << "pmoPtr is inSync" << endl;

processProxyManagedObjectSync(*pmoPtr);

}

}


void Monitor::processObjectServerRootRemoved(RTRProxyManagedObjectServer& pmos, const RTRProxyManagedObjectHandle& pmoh )

{

cout <<"pmos event: Removed a root from pmos @" << pmos.text() << endl;

}

//

// Event processing for RTRProxyManagedObjectClient

//

void Monitor::processProxyManagedObjectError(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: Error @" << pmo.text() << endl;

}


void Monitor::processProxyManagedObjectDeleted(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: Deleted" << endl;

}


void Monitor::processProxyManagedObjectInfo(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: Info @" << pmo.text() << endl;

}


void Monitor::processProxyManagedObjectInService(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: InService" << endl;

}


void Monitor::processProxyManagedObjectRecovering(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: Recovering" << endl;

}


void Monitor::processProxyManagedObjectWaiting(const RTRProxyManagedObject& pmo )

{

cout << "pmo event: Waiting" << endl;

}


void Monitor::processProxyManagedObjectDead(const RTRProxyManagedObject& pmo)

{

cout << "pmo event: Dead" << endl;

}


void Monitor::processProxyManagedObjectChildAdded(const RTRProxyManagedObject& pmo, const RTRProxyManagedObjectHandle& pmoh )

{

RTRProxyManagedObjectHandleIterator it = pmo.childHandles();

for (it.start(); !it.off(); it.forth())

{

RTRProxyManagedObjectPtr pmoPtr = pmo.childByName(it.item().name());

if (pmoPtr == NULL) continue;


if( addToList(pmoPtr) == true) // fail if not in

pmoPtr->addClient( (RTRProxyManagedObjectClient &) *this ); //fail if not it


string s = pmo.instanceId().to_c() + string("/") + it.item().name().to_c();

//cout << "Adding ChildObj: " << s << " count=" << ix++ << endl;

}

}


void Monitor::processProxyManagedObjectChildRemoved(const RTRProxyManagedObject& pmo,const RTRProxyManagedObjectHandle& pmoh)

{

cout << "pmo event: ChildRemoved" << endl;

}


void Monitor::processProxyManagedObjectVariableAdded(const RTRProxyManagedObject& pmo, const RTRProxyManagedVariableHandle& pmoh)

{

cout << "pmo event: VariableAdded" << endl;


RTRProxyManagedVarHandleIterator pmvIterator = pmo.variableHandles();

for ( pmvIterator.start(); !pmvIterator.off(); pmvIterator.forth() )

{

RTRProxyManagedVariablePtr pmvPtr = pmo.variableByName(pmvIterator.item().name());


if (pmvPtr == NULL) continue;


if (pmvPtr->error())

exit(1);


if( addToList(pmvPtr) == true)

pmvPtr->addClient(*this);


if ( pmvPtr->inSync() == RTRTRUE )

processProxyManagedVariableSync(*pmvPtr);

}


}


void Monitor::processProxyManagedObjectVariableRemoved(const RTRProxyManagedObject& pmo, const RTRProxyManagedVariableHandle& pmoh)

{

cout << "pmo event: VariableRemoved" << endl;


}




//Event processing for RTRProxyManagedVariableClient

void Monitor::processProxyManagedVariableError( RTRProxyManagedVariable& pmv)

{

cout << "pmv event: Error @" << pmv.text() << endl;

}


void Monitor::processProxyManagedVariableSync(RTRProxyManagedVariable& pmv)

{


RTRProxyManagedObject& pmo = pmv.context();

cout << "<SYNC> " << pmo.instanceId() << "/" << pmv.name() << "=" << pmv.toString() << endl;

}


void Monitor::processProxyManagedVariableUpdate(RTRProxyManagedVariable& pmv)

{

RTRProxyManagedObject& pmo = pmv.context();

cout << "<UPDATE> " << pmo.instanceId() << "/" << pmv.name() << "=" << pmv.toString() << endl;

}


void Monitor::processProxyManagedVariableDeleted(RTRProxyManagedVariable& pmv)

{

cout << "pmv event: Deleted" << endl;

pmv.dropClient(*this);

}


bool Monitor::addToList( const RTRProxyManagedObjectPtr obj )

{

RTRProxyManagedObjectPtr objPtr;

RTRBOOL done = RTRFALSE; //used to maintain correct managed object tree structure



void *p = (void *) obj;

for(size_t ix=0; ix< vecPtr.size(); ix++)

{

if( vecPtr[ix]== p)

{

//cout <<"duplicate obj found\n";

return false;

}

}


vecPtr.push_back(p);

//cout << "vecPtr.size() =" << vecPtr.size() << " lastPtr="<< p << endl;


RTRProxyManagedObjectPtr *nPtr = new RTRProxyManagedObjectPtr;

*nPtr = obj;

if ( _pmoList.empty() )

{

_pmoList.addRight( nPtr );

}

else

{

for ( _pmoList.start(); !_pmoList.off(); _pmoList.forth() )

{

objPtr = *(_pmoList.item());


if ( obj->instanceId().parent() == objPtr->instanceId() )

{

_pmoList.addRight( nPtr );

done = RTRTRUE;

break;

}

}

if ( !done )

{

_pmoList.start();

_pmoList.addRight( nPtr );

}

}

return true;

}



//create a linked list that contains

//all the proxy managed variables

bool Monitor::addToList( const RTRProxyManagedVariablePtr var )

{

RTRProxyManagedVariablePtr ptr;

RTRBOOL variable_found = RTRFALSE; //used to ensure that the variables

//added in the same order as we see them


void *p = (void *) var;

for(size_t ix=0; ix< vecVar.size(); ix++)

{

if( vecVar[ix]== p)

{

//cout <<"duplicate var found\n";

return false;

}

}

vecVar.push_back(p);

//cout << "vecVar.size() =" << vecVar.size() << " lastPtr="<< p << endl;


RTRProxyManagedVariablePtr *nPtr = new RTRProxyManagedVariablePtr;

*nPtr = var;


if ( _pmvList.empty() )

{

_pmvList.addRight( nPtr );

}

else

{

for ( _pmvList.start(); !_pmvList.off(); _pmvList.forth() )

{

ptr = *(_pmvList.item());

if (ptr->error()) {

if (ptr->hasClient(*this))

ptr->dropClient(*this);

_pmvList.remove();

return false;

}


if ( var->context().instanceId() == ptr->context().instanceId() )

variable_found = RTRTRUE;


if ( ( variable_found ) && (var->context().instanceId() != ptr->context().instanceId()) )

{

_pmvList.addLeft( nPtr );

return true;

}

}

// New variable added to list

_pmvList.extend( nPtr );

}

return true;

}


#technologyapi
icon clock
10 |1500

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

Upvotes
Accepted
80.3k 259 52 75

@louis.louca

Thank you for reaching out to us.

I modifed the code by focusing on the following callbacks.

  • processProxyManagedObjectChildAdded
  • processProxyManagedObjectChildRemoved
  • processProxyManagedObjectDeleted


void Monitor::processProxyManagedObjectChildAdded(const RTRProxyManagedObject& pmo, const RTRProxyManagedObjectHandle& pmoh )
{
   cout<<"#### processProxyManagedObjectChildAdded: "<< pmo.name().to_c() << " Handle Name: "<<pmoh.name().to_c() <<endl;
...
}
void Monitor::processProxyManagedObjectChildRemoved(const RTRProxyManagedObject& pmo,const RTRProxyManagedObjectHandle& pmoh)
{
cout<<"#### processProxyManagedObjectChildRemoved: "<< pmo.name().to_c() << " Handle Name: "<<pmoh.name().to_c() <<endl;
...
}
void Monitor::processProxyManagedObjectDeleted(const RTRProxyManagedObject& pmo)
{
   cout<<"#### processProxyManagedObjectDeleted " << pmo.name().to_c() <<endl;
   ...
}

If there is a new connection, it will print the following line.

#### processProxyManagedObjectChildAdded: userDatabase Handle Name: mount9

If the client disconnects, it will print the following lines.

#### processProxyManagedObjectChildRemoved: userDatabase Handle Name: mount9
...
#### processProxyManagedObjectDeleted mount9

I hope that this information is of help.


icon clock
10 |1500

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

Upvotes
1 0 0 1

Hi, processProxyManagedObjectChildAdded does not add the child object to any list so that it can be iterated through and maintained.

I am trying to keep a dynamic updating view of all the variables (and its children) I am interested in.

Please advise.

icon clock
10 |1500

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

Write an Answer

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

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