Persistence Service

AstuteDDS provides a built-in Persistence Service (<astutedds/dcps/persistence_service.hpp>) that implements TRANSIENT and PERSISTENT durability as specified in OMG DDS 1.4 Section 2.2.3.4 and Section 2.2.3.20.

Overview

The Persistence Service allows late-joining DataReaders to receive data that was written before they were created. Two levels of persistence are supported:

Durability Kind Storage Survives writer restart Survives service restart
TRANSIENT_LOCAL In process memory (writer) No No
TRANSIENT In-memory (service) Yes No
PERSISTENT File-backed on disk Yes Yes

Configuring Durability QoS

Set the appropriate DurabilityQosPolicyKind on a DataWriter:

#include <astutedds/dcps/qos.hpp>

// TRANSIENT: samples survive DataWriter deletion but not service restart
auto transient_qos = astutedds::dcps::DataWriterQosBuilder()
    .durability(astutedds::dcps::DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS)
    .build();

// PERSISTENT: samples survive service and writer restart
auto persistent_qos = astutedds::dcps::DataWriterQosBuilder()
    .durability(astutedds::dcps::DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS)
    .build();

The matching DataReader should request at least the same (or weaker) durability:

auto reader_qos = astutedds::dcps::DataReaderQosBuilder()
    .durability(astutedds::dcps::DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS)
    .build();

QoS Compatibility

A writer with PERSISTENT durability is compatible with readers requesting VOLATILE, TRANSIENT_LOCAL, TRANSIENT, or PERSISTENT durability.

Controlling Sample Retention

Use DurabilityServiceQosPolicy on the DataWriter to limit how many samples the Persistence Service retains:

astutedds::dcps::DurabilityServiceQosPolicy svc_qos;
svc_qos.history_kind = astutedds::dcps::HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
svc_qos.history_depth = 100;
svc_qos.max_samples = 1000;
svc_qos.max_instances = astutedds::dcps::LENGTH_UNLIMITED;
svc_qos.max_samples_per_instance = 100;

auto writer_qos = astutedds::dcps::DataWriterQosBuilder()
    .durability(astutedds::dcps::DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS)
    .durability_service(svc_qos)
    .build();

Configuring the Storage Directory

By default, persistent stores are written to .astutedds_persistence/ in the working directory. Override with:

astutedds::dcps::PersistenceService::instance().set_persistence_dir("/var/lib/astutedds");

This creates one binary file per topic under the configured directory. The files use the ADPS magic header and are forward-compatible across AstuteDDS versions.

How It Works

  1. When a DataWriter publishes a sample with TRANSIENT or PERSISTENT durability, the sample is forwarded to PersistenceService::store_sample().
  2. On first write for a topic with PERSISTENT durability, any previously persisted samples are loaded from disk first, so the in-memory store is always complete.
  3. When a late-joining DataReader matches a durable writer, historical samples are delivered via PersistenceService::get_samples().
  4. PersistenceService::notify_writer_deleted() is called when a writer is destroyed. For TRANSIENT topics the in-memory store is cleared; for PERSISTENT topics the file-backed store is retained.

Purging Persistent Stores

To remove the on-disk store for a topic:

astutedds::dcps::PersistenceService::instance().purge_persistent_store("MyTopic");

Warning

This permanently deletes the backing file. Use with care in production systems.