Remove instance from persistence service's database using filesystem

8 posts / 0 new
Last post
Offline
Last seen: 2 weeks 21 hours ago
Joined: 09/10/2022
Posts: 30
Remove instance from persistence service's database using filesystem

Hi,

I use rti v6.0.0

Im using persistence service. I set the "datawriter durability qos" in my project in "persistent". And i set the xml for that saves datas in file system.

When i unregister an instance that registered before, i expect that the instance won't publish by persistence service even when datawriter that calls dispose destructed and removed from domain. But unexpectedly when i destruct datawriter that caled unregister_instance persistence service publishes that instance from its history.

 

Have can i delete an instance from persistence service's history that it don't publish it at all?

Howard's picture
Offline
Last seen: 6 hours 16 min ago
Joined: 11/29/2012
Posts: 608

Disposing an instance, tells DDS that an instance no longer exists, and then DDS will remove data samples of that instances from the caches of DataWriters, DataReaders, Persistence Service.

Unregistering an instance just tells DDS that a DataWriter will no longer publish data for an instance.

But disposing instance by a DataWriter first requires the DataWriter to register to send information about an instance.  So the proper way is to first Dispose() and then Unregister().

Using the WriterDataLifecycle QosPolicy, you can configure the DataWriter to autodispose_unregistered_instances(), see

https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/api/connext_dds/api_cpp2/classdds_1_1core_1_1policy_1_1WriterDataLifecycle.html#ac6d18d9510c187cdb1ba3a0a7d98a937

https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/manuals/connext_dds_professional/users_manual/users_manual/WRITER_DATA_LIFECYCLE_QoS_Policy.htm#47.31_WRITER_DATA_LIFECYCLE_QoS_Policy

While the concept of "instances" make DDS unique and powerful, it also makes things more complicated...lots of QoS have instance-specific behavior.  And you have to manage instance lifecycle if you want to control memory usage and such.

Here's documentation on instances and how DataWriters and DataReaders deal with instances:

https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/manuals/connext_dds_professional/users_manual/users_manual/WorkingWithInstances.htm

https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/manuals/connext_dds_professional/users_manual/users_manual/Managing_Data_Instances__Working_with_Ke.htm#Disposin

https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/manuals/connext_dds_professional/users_manual/users_manual/AccessingManagingInstances.htm#40.8__Accessing_and_Managing_Instances_(Working_with_Keyed_Data_Types)

Offline
Last seen: 2 weeks 21 hours ago
Joined: 09/10/2022
Posts: 30

In connext dds version 6.0.0 default value for autodispose_unregistered_instances is true, therefor when I unregister an instance it will be disposed automatically.

I dont know if instance cleared from persistance data writer cach, but i am sure it wont delete the instance from file system (database still saved the instance and didnt cleared it).

You can try it by rebooting system. If you reboot the system, persistence service will publish the instance again

Howard's picture
Offline
Last seen: 6 hours 16 min ago
Joined: 11/29/2012
Posts: 608

With the Persistence Service, you have to configure it to purge the samples for disposed instances.  The Persistence Service stores data received in the history cache (on disk if configured) of the DataWriter that is used to send the data to new DataReaders.

That when the Persistence Service DataReader receives a "disposed" sample from a user app, it will write that sample with its DataWriter...in essense call writer->dispose().

With all DataWriters (users' app or Persistence Service), disposing instances does not immediately purge/remove samples of the disposed instance from its history cache. 

There's a QoS parameter called WriterDataLifecycle::auto_purge_instances_delay, that controls when DDS removes samples of disposed instances (as well as information about instances).

For Durable DataWriters (which are used by Persistence Service), this can be 0 (immediately) or INFINITE (never). 

By default, this value is set to INFINITE (by the way, I think that the documentation for Connext 6.0.0 has a typo and indicates that the default value is 0...which is not true). 

So by default, Persistence Service does not remove the samples of disposed instances...actually, regular DataWriters also behave this way by default.

To configure Persistence Service to delete the samples of disposed instances, you will have to modify the QoS of the DataWriter used by Persistence Service (and should also do so for your application's DataWriters if you don't want your application's DataWriters to store samples/info about disposed instances)...for example,

 

<qos_library name="TestPersistenceQosLib" base_name="BuiltinQosLib::Generic.StrictReliable">
    <qos_profile name="QosProfile">
      <datawriter_qos>
        <writer_data_lifecycle>
          <autopurge_disposed_instances_delay>
            <sec> 0 </sec>
            <nanosec> 0 </nanosec>
          </autopurge_disposed_instances_delay>
        </writer_data_lifecycle>
      </datawriter_qos>
    </qos_profile>
  </qos_library>

  <!-- ================================================================= -->
  <!-- Persist all data in disk -->
  <!-- ================================================================= -->
  <persistence_service name="TestPersistenceUserDisk">
    <persistent_storage>
      <filesystem>
        <!-- <directory>MyDirectory</directory> -->
        <file_prefix>defaultUserDisk_</file_prefix>
        <synchronization>NORMAL</synchronization>
        <journal_mode>WAL</journal_mode>
        <vacuum>FULL</vacuum>
      </filesystem>
    </persistent_storage>
    <participant name="defaultParticipant">
      <domain_id>0</domain_id>
      <persistence_group name="persistAll">
        <filter>*</filter>
        <datawriter_qos base_name="TestPersistenceQosLib::QosProfile"/>       
        <datareader_qos base_name="TestPersistenceQosLib::QosProfile"/
      </persistence_group>
    </participant>
  </persistence_service>

Offline
Last seen: 2 weeks 21 hours ago
Joined: 09/10/2022
Posts: 30

Thanks a lot Mr Howard, it works, but there is a delay in deleting instances from datawriters' cach (late joiners receive disposed instances about 5 seconds after disposing the instance), do you have any suggestion for decreasing that delay?

Offline
Last seen: 2 weeks 21 hours ago
Joined: 09/10/2022
Posts: 30

I found the problem. The problem was that i set rtps_reliable_writer(rti::core::policy::RtpsReliableWriterProtocol()) after setting AutoDisposeUnregisteredInstances().

The currect way is to set AutoDisposeUnregisteredInstances() after rtps_reliable_writer(rti::core::policy::RtpsReliableWriterProtocol())

Howard's picture
Offline
Last seen: 6 hours 16 min ago
Joined: 11/29/2012
Posts: 608

Hi,

Hmm, the WriterDataLifecycleQosPolicy should be independent from the DataWriterQosPolicy.  You should be able to set them in any order in a DataWriterQos object.

Can you send/post the code that didn't work?  I assume that you set custom values for the WriterDataLifecycleQosPolicy and DataWriterQosPolicy in a DataWriterQos object and then use the DataWriterQos to create a DataWriter?

Offline
Last seen: 2 weeks 21 hours ago
Joined: 09/10/2022
Posts: 30

Thank you, the problem was that I set direct_communication(true) for data reader, and I set history::keepAll() for data writer.

But there is another big problem rhat when there is not any subscriber in domain, publisher can not dispose the instance and throws exception. I dont know why!? I attach the projects and persistence xml to this messages.

Error is:

WriterHistoryMemoryPlugin_addSample:!precondition

PRESWriterHIstoryDriver_unregisterInstance:addSample

PRESPsWriter_unregisterInstanceInternal:collator unregisterInstance

File Attachments: