19.1 Instance States

Instances can be in one of three states:

  • ALIVE: An existing DataWriter has written a sample of the instance.
  • NOT_ALIVE_DISPOSED: A DataWriter that has written the instance has called dispose() on the instance. (See 31.14.3 Disposing Instances for further clarification when using EXCLUSIVE Ownership.)
  • NOT_ALIVE_NO_WRITERS: All DataWriters that have written the instances have gone away (more on that later), or called unregister_instance() to unregister themselves from the instance.

Figure 19.1: Overview of Instance States and Transitions

(1) If RECOVER_INSTANCE_STATE_RECOVERY is used in the RELIABILITY QosPolicy, then, upon recovering liveliness with a DataWriter, instances will transition from NOT_ALIVE_NO_WRITERS to their current state on the DataWriter (NOT_ALIVE_DISPOSED, ALIVE, or NOT_ALIVE_NO_WRITERS). Transition to NOT_ALIVE_DISPOSED also requires setting reader_qos.protocol.propagate_dispose_of_unregistered_instances to TRUE.

(2) If reader_qos.protocol.propagate_unregister_of_disposed_instances is set to TRUE.

(3) If reader_qos.protocol.propagate_dispose_of_unregistered_instances is set to TRUE.

19.1.1 ALIVE Details

The ALIVE instance state indicates that there is a DataWriter actively updating that instance, and no DataWriter has declared the instance to be “disposed” (see below).

An instance becomes ALIVE when either of the following is true:

  • A DataWriter writes a sample of that instance.
  • A DataWriter that lost liveliness regains liveliness, instance state consistency is enabled, and the instance is still ALIVE on the DataWriter. See 19.1.5 Transition after NOT_ALIVE_NO_WRITERS.

Instances and OWNERSHIP QoS: If the DataWriters’ QoS is configured with exclusive ownership, the DataWriter with the highest OWNERSHIP_STRENGTH that has written the instance is the owner of the instance, unless it unregisters the instance, loses liveliness, or is deleted. If the instance is in the NOT_ALIVE_DISPOSED state, only the DataWriter that owns that instance can make it transition to the ALIVE state. See 47.17 OWNERSHIP QosPolicy.

19.1.2 NOT_ALIVE_DISPOSED Details

The NOT_ALIVE_DISPOSED instance state indicates that a DataWriter has changed the state of an instance to NOT_ALIVE_DISPOSED either explicitly by calling the dispose() method on the instance or implicitly by calling the unregister() method on the instance when autodispose_unregistered_instances in the 47.31 WRITER_DATA_LIFECYCLE QoS Policy is set to TRUE (not the default). The meaning of an instance becoming NOT_ALIVE_DISPOSED is part of the design of a system.

When a DataWriter calls dispose() on an instance, a dispose message is propagated from the DataWriter to its matching DataReaders to tell those DataReaders that the instance’s state is changed to NOT_ALIVE_DISPOSED.

Many systems use the NOT_ALIVE_DISPOSED instance state to indicate that the object that the instance represents has gone away. For example, in a “FlightData” topic, a system may use the NOT_ALIVE_DISPOSED instance state to indicate that the aircraft tracked by a radar system has landed.

One common misconception is that the memory belonging to a disposed instance is immediately freed when the DataWriter calls dispose(). This is not true, because the dispose message needs to be propagated to DataReaders. This means that information about the instance—and the fact that it was disposed—is kept in the DataWriter's queue based on QoS policies such as 47.21 RELIABILITY QosPolicy, 47.9 DURABILITY QosPolicy, 47.12 HISTORY QosPolicy, and 47.6 DATA_WRITER_RESOURCE_LIMITS QosPolicy (DDS Extension). See 19.2.2 QoS Policies that Affect Instance Management for more information on managing resources for instances.

An instance can transition from NOT_ALIVE_DISPOSED to ALIVE if a DataWriter writes a new sample of that instance. An example of a system that transitions an instance to NOT_ALIVE_DISPOSED and then back to ALIVE is a radar system at an airport. It could be tracking a flight with the following key fields:

airline = UA

flight_num = 901

In this example, when the flight appears on radar, the instance becomes ALIVE. When the flight lands, it becomes NOT_ALIVE_DISPOSED. The same flight flies every day, so it transitions from NOT_ALIVE_DISPOSED to ALIVE when the flight appears on radar again the next day. This maps to the state diagram shown in Figure 19.2: Instance State Diagram: Example for Flight Data.

Figure 19.2: Instance State Diagram: Example for Flight Data

Instances and OWNERSHIP QoS: If the DataWriters’ QoS policy is set to OWNERSHIP = EXCLUSIVE, the DataWriter with the highest OWNERSHIP_STRENGTH that has written the instance is the owner of the instance. It is also the only DataWriter that can dispose the instance. It does not lose ownership by disposing. Other DataWriters can call dispose(), but their dispose will have no effect on the instance state. OWNERSHIP is generally used for redundancy purposes, so it makes sense for only one owning DataWriter at a time to affect the instance state. See 47.17 OWNERSHIP QosPolicy for further details.

19.1.3 NOT_ALIVE_NO_WRITERS Details

The NOT_ALIVE_NO_WRITERS instance state indicates that there are no active DataWriters that are currently updating the instance.

An instance becomes NOT_ALIVE_NO_WRITERS if all DataWriters that have written that instance have unregistered themselves from the instance or become not alive themselves (through losing liveliness or being deleted). This means that if all DataWriters that have written samples for an instance are deleted, the instance changes state to NOT_ALIVE_NO_WRITERS. Take for example a system where there is only a single DataWriter of an instance. If that DataWriter loses liveliness due to a temporary network disconnection, the DataReaders will detect that the instance is NOT_ALIVE_NO_WRITERS.

When the network disconnection is resolved, the DataReaders will detect that the DataWriter has regained liveliness, but will not restore the instance state to ALIVE until one of the following is true:

19.1.4 Transitions between NOT_ALIVE States

By default, there is no state transition between the NOT_ALIVE_NO_WRITERS and NOT_ALIVE_DISPOSED states, but this can be overridden by using the QoS settings propagate_dispose_of_unregistered_instances and propagate_unregister_of_disposed_instances on a DataReader via the 48.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension).

Setting propagate_dispose_of_unregistered_instances to true means that if all DataWriters unregister the instance or lose liveliness (so the instance becomes NOT_ALIVE_NO_WRITERS), and then a DataWriter calls dispose() on the instance, the DataReader will recognize that instance as NOT_ALIVE_DISPOSED once it receives the dispose sample, or once the DataWriter regains liveliness if instance state consistency is enabled (see 19.1.5 Transition after NOT_ALIVE_NO_WRITERS)

Setting propagate_dispose_of_unregistered_instances to true could also mean that the first message a DataReader receives about an instance is NOT_ALIVE_DISPOSED. In Figure 19.3: Instance State Transitions: propagate_dispose_of_unregistered_instances = true, there is a new initial state transition from a DataReader never having seen an instance to seeing it as NOT_ALIVE_DISPOSED. In this case, the DataReader recognizes that the instance went from never existing (as far as the DataReader is concerned) to NOT_ALIVE_DISPOSED.

It is recommended that if you set propagate_dispose_of_unregistered_instances to true, you also set serialize_key_with_dispose to true (see 47.5 DATA_WRITER_PROTOCOL QosPolicy (DDS Extension)). This QoS will allow the subscribing application to retrieve the key value of the instance through the FooDataReader_get_key_value API, even though a valid sample for that instance has not been received.

Figure 19.3: Instance State Transitions: propagate_dispose_of_unregistered_instances = true

Transitions shown with dashed lines are only available when propagate_dispose_of_unregistered_instances = true.

The propagate_unregister_of_disposed_instances QoS setting in the 48.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension) allows instances to transition directly from the instance being disposed to NOT_ALIVE_NO_WRITERS. See Figure 19.4: Instance State Transitions: propagate_unregister_of_disposed_instances = true. By default, only the resources for instances in the NOT_ALIVE_NO_WRITERS instance state are reclaimable in the DataReader queue. In a system with finite instance resource limits, the propagate_unregister_of_disposed_instances setting allows an application to dispose instances to signal that the instance has gone away and then unregister those instances to make sure that the instances’ resources are reclaimable for use by new instances. Depending on your system requirements, another approach to reclaiming instance resources in the DataReader queue is to set autopurge_disposed_instances_delay to zero. See 40.8.6 Instance Resource Limits and Memory Management for more details.

Figure 19.4: Instance State Transitions: propagate_unregister_of_disposed_instances = true

Transitions shown with dashed lines are only available when propagate_unregister_of_disposed_instances = true.

19.1.5 Transition after NOT_ALIVE_NO_WRITERS

The NOT_ALIVE_NO_WRITERS instance state indicates that there are no active DataWriters that are currently updating the instance. When this happens, the DataReader transitions the instance to NOT_ALIVE_NO_WRITERS. Sometimes the instance state is NOT_ALIVE_NO_WRITERS because the last DataWriter that was writing the instance lost liveliness. When the DataReader rediscovers that DataWriter, there are two possible results depending on how you've set the instance_state_recovery_kind in the 47.21 RELIABILITY QosPolicy:

  • (default) NO_INSTANCE_STATE_RECOVERY: the state of the instance is not restored on the DataReader (it stays in the NOT_ALIVE_NO_WRITERS state) until the DataWriter sends a new sample of the instance. This could lead to inconsistent instance states: if the DataWriter hasn't updated the instance yet, a late-joining DataReader has the correct instance state by virtue of discovery and receiving historical samples from the DataWriter, whereas existing DataReaders have the wrong state until they receive a new sample.
  • (experimental) RECOVER_INSTANCE_STATE_RECOVERY: the DataReader automatically transitions instances to their current state after it reconnects with a DataWriter, even before the DataWriter sends a new sample.
  • The DataReader sends the request for missed instance state transitions to the DataWriter using the ServiceRequest channel. Responses to the request are sent using a builtin DataWriter that is created for each Publisher that has at least one DataWriter with RECOVER_INSTANCE_STATE_RECOVERY enabled. The DataReader processes the response, which contains the relevant instance state data, and automatically transitions the instances to their current state in its queue. Any instance state transitions that occur due to this response sample are presented to the user application in the form of samples with the valid_data flag set to FALSE in the associated SampleInfo. (See 40.8.3 Valid Data Flag.)

    Note: Since instance state consistency uses the ServiceRequest channel, the RECOVER_INSTANCE_STATE_RECOVERY setting requires the enabled_builtin_channels field in the 44.3 DISCOVERY_CONFIG QosPolicy (DDS Extension) to be set to DDS_DISCOVERYCONFIG_SERVICE_REQUEST_CHANNEL (by default, it is).

    To achieve the highest level of instance state consistency, the following QoS must be set:

    • instance_state_recovery_kind set to RECOVER_INSTANCE_STATE_RECOVERY in the 47.21 RELIABILITY QosPolicy for the DataReader and DataWriter (not the default setting).
    • reliability kind set to DDS_RELIABLE_RELIABILITY_QOS in the 47.21 RELIABILITY QosPolicy for both the DataReader and DataWriter (not the default setting for the DataReader). This setting is required in order to enable instance state consistency.
    • keep_minimum_state_for_instances set to true in the 48.2 DATA_READER_RESOURCE_LIMITS QosPolicy (DDS Extension) for the DataReader (default setting). The minimum state includes the last known state of the instance, which RECOVER_INSTANCE_STATE_RECOVERY uses to restore the instance state. See 40.8.7 Active State and Minimum State.
    • propagate_dispose_of_unregistered_instances set to true in the 48.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension) for the DataReader (not the default setting). Setting this to true enables the transition from the instance state NOT_ALIVE_NO_WRITERS to NOT_ALIVE_DISPOSED. When this is set to false, Connext cannot recover the instance state in this case.
    • serialize_key_with_dispose set to true in the 47.5 DATA_WRITER_PROTOCOL QosPolicy (DDS Extension) for the DataWriter (not the default setting). When an instance is disposed, the serialized key is sent to the DataReader. The DataReader can then access the key_value of the disposed instance. When serialize_key_with_dispose is set to false, Connext cannot get the key_value of the disposed instance.

    If a kind of BY_SOURCE_TIMESTAMP is used in the 47.8 DESTINATION_ORDER QosPolicy, Connext will only apply transitions that have occurred after the most recent update for an instance (most recent being defined as the newest source timestamp).