0

I have a program that requests values from RTI DDS based on a list of points (DynamicIoRunnable below). The DyamicIoRunnable will request a data instance for each point in the predefined list, it will put the data in a list and once it goes through all items in a predefined list, pass it onto a processor thread (DDSProcessor below - this is slimmed down to the relevant portion) through a shared BlockingQueue. This processor thread will process each item in the list and create a custom object (PointData) for each. To debug this problem, the DynamicIoRunnable only has a single predefined point so I can easily identify it. The issue is, that I am adding the PointData to a list and printing it out as it builds. The print statement before the add always shows the correct value, but as I iterate through the array with print statements after every add, after a few items, previous items change to different data and I am unsure how. Anyone see where things could be altered?

I have a sample results attached below. It shows the first corruption after a few cycles (the first 2 items that were initially added to the list change completely - this does get worse over a few more items and is always older items though I see no consistent pattern as to what the data changes to, when it will change or how many will change).

Shared Queue

public static BlockingQueue<Object> messageProcQueue = new LinkedBlockingQueue<Object>();

DynamicIoRunnable

 public void run()
{
    try
    {
        List<PointData> temp = new ArrayList();

        for (PredefData a : TrendApp.predefPointList)
        {
            if (a.getDdsHandle() != null)
            {
                Object ioData = dds.getTopicRef().get(pv.getTypeString(a.getPointType().value())).read_io(a.getDdsHandle(), io -> io);

                if (ioData != null)
                {
                    PointData val = new PointData(a.getMachineId(), a.getPointType(), a.getIoId(), a.getSubfield(), a.getConfigId(), ioData);
                    temp.add(val);
                }
            }
        }

        TrendApp.messageProcQueue.put(temp);
    } catch (Exception e)
    {
        errorLog.error("Unable to add dynamic IO to message processing queue");
        e.printStackTrace();
    }
}

DDSProcessor

private static List<PointData> writeBuffer = new ArrayList<PointData>();
if (a instanceof PointData)
                {
                    PointData req = (PointData) a;

                    // Add new point to the buffer

                    System.out.println("Enter Point Data: " + req.getData());
                    writeBuffer.add(req);

                    for (int x = 0; x < writeBuffer.size(); x++)
                    {
                        System.out.println("Building Buffer = " + writeBuffer.get(x).getData());
                    }
}

PointData Object

private int machineId;
private jPointType pointType;
private int ioId;
private String subfield;
private int configId;
private long timestamp;
private Object data;

public PointData(int machineId, jPointType pointType, int ioId, String subfield, int configId, Object data)
{
    this.machineId = machineId;
    this.ioId = ioId;
    this.pointType = pointType;
    this.subfield = subfield;
    this.configId = configId;
    this.data = data;
}

Example Results

Add Point Data to list:
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 974.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0


Add Point Data to list: :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 224
value: 0.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0

Building Buffer = :
machineId: 1186
ioId: 31
value: 956.0
Tacitus86
  • 1,314
  • 2
  • 14
  • 36
  • Can you supply the QoS for the writer? Also, it looks you have a helper class or sub-class of the "DDS environment"; what do dds.getTopicRef() and getDdsHandle() do? These aren't Connext syntax (which uses the "c" conventions rather than "java" naming conventions). – rip... Jul 03 '17 at 17:43
  • Hey rip, these are inside our DDS jar file that I don't really have access to, i just use the jar not develop the source. The getTopicRef is supposed to get a topic by name and the getDdsHandle is a simple getter for PredefPoint class that returns the DDS handle for that point that was fetched elsewhere in the program using: InstanceHandle_t handle = dds.getTopicRef().get(pv.getTypeString(a.getPointType().value())).getIoByIndex(a.getIoId()); – Tacitus86 Jul 03 '17 at 19:40
  • Did you need the USER QOS or the NDDS_QOS? – Tacitus86 Jul 03 '17 at 19:42
  • tracing the code it looks like the PointData isn't an IDL-defined type, and the only "DDS" related info in there is the Object data field, which you say is an InstanceHandle_t. The next thing I would look at is the .getData() method. Does it reference the InstanceHandle_t and do a lookup to find the values in that instance/sample, based on the InstanceHandle_t? And if so, how? Or... is this some funky lambda interaction thingy from that read_io(...) earlier, in which case it's above my pay-grade... – rip... Jul 03 '17 at 20:45
  • Reader History qos, but only if the "fetched" is pulling the data from a reader's queue. – rip... Jul 03 '17 at 20:46
  • Perhaps this is what you need? KEEP_LAST_HISTORY_QOS 10 – Tacitus86 Jul 05 '17 at 12:06
  • Hey RIP, I did a test this morning because each of these points are identified by the following: Machine ID, IOType, Io ID. The PointData is constructed by me in the program and contains this information, but the data object that is returned from DDS actually contains it as well. The print outs in the example above is the toString() of the results of PointData.getData(). So I ran it today and compared those versus what I assigned to PointData itself and PointData remains correct while the data object inside is what changes. – Tacitus86 Jul 05 '17 at 12:17
  • I was able to get this to work by processing the primitive out of the Data object and just storing that in Object Data within PointData instead of the entire IDL item that is pulled from DDS. Thank you so much for your help RIP. If you want to mark up as a solution, I will mark it as correct. – Tacitus86 Jul 05 '17 at 12:52
  • I'm not sure what the 'answer' is :) is this it: You requested data from the 3d party jar, it returned (a reference to) "the object", rather than a new object (a reference to a deep clone of "the object"). Because it held the real instance, it felt it was allowed to change the instance variables based on real-time things happening around it. The solution was to make your own clone of the instance, one that you own ... ? – rip... Jul 06 '17 at 19:00
  • Yes. Either that or fetch the primitive that I wanted out of that object before it is changed. – Tacitus86 Jul 06 '17 at 19:03

0 Answers0