19.1 Instance States

Instances can be in one of three states:

  • ALIVE: A DataWriter considers an instance to be ALIVE as long as it has not disposed the instance or unregistered from it. A DataReader considers an instance to be ALIVE as long as there is at least one active DataWriter maintaining the instance in the ALIVE instance state. See 19.1.1 ALIVE Details.
  • NOT_ALIVE_DISPOSED: DataWriters and DataReaders consider an instance to be NOT_ALIVE_DISPOSED when a DataWriter that has written the instance has disposed the instance. See 19.1.2 NOT_ALIVE_DISPOSED Details.
  • NOT_ALIVE_NO_WRITERS: This instance state is used only by DataReaders, not by DataWriters. A DataReader considers an instance to be NOT_ALIVE_NO_WRITERS when all known DataWriters for an instance have either explicitly unregistered themselves from the instance using the unregister() API or lost liveliness. See 19.1.3 NOT_ALIVE_NO_WRITERS Details.

Figure 19.1: Overview of Instance States and Transitions

(1) If RECOVER_INSTANCE_STATE_CONSISTENCY 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 (either because they have lost liveliness or because they have unregistered themselves from 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_consistency_kind in the 47.21 RELIABILITY QosPolicy:

  • (default) NO_RECOVER_INSTANCE_STATE_CONSISTENCY: 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. See Figure 19.5: Behavior without Instance State Consistency Enabled.
  • RECOVER_INSTANCE_STATE_CONSISTENCY: the DataReader automatically transitions instances to their current state after it reconnects with a DataWriter, even before the DataWriter sends a new sample. See Figure 19.6: Behavior with Instance State Consistency Enabled.
  • Consider using RECOVER_INSTANCE_STATE_CONSISTENCY if you plan to use instances and their states in applications where there may be a loss of liveliness between DataReaders and DataWriters. Such loss is particularly relevant in networks susceptible to disruptions and disconnections. See also 47.21.6 System Resource Considerations.

    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_CONSISTENCY 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_CONSISTENCY 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).

    RECOVER_INSTANCE_STATE_CONSISTENCY is not fully supported by the RTI Infrastructure Services. See Known Issues with Instance Lifecycle in the RTI Connext Core Libraries Release Notes for more information.

    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).

Figure 19.5: Behavior without Instance State Consistency Enabled

Figure 19.6: Behavior with Instance State Consistency Enabled

19.1.5.1 QoS Settings Related to RECOVER_INSTANCE_STATE_CONSISTENCY

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

  • instance_state_consistency_kind set to RECOVER_INSTANCE_STATE_CONSISTENCY 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_CONSISTENCY 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.

Optional QoS settings related to instance state consistency are autopurge_remote_not_alive_writer_delay and max_remote_writers in the 48.2 DATA_READER_RESOURCE_LIMITS QosPolicy (DDS Extension).

19.1.5.2 Security Plugins and RECOVER_INSTANCE_STATE_CONSISTENCY

You can use the Security Plugins to protect the service request channel (through which instance state updates are requested) and the instance state itself. For details, see "Interactions with Instance State Consistency" in Advanced Cryptography Concepts, in the RTI Security Plugins User's Manual.

19.1.5.3 Special Considerations while Using RECOVER_INSTANCE_STATE_CONSISTENCY

19.1.5.3.1 Removed Instances During Disconnections

When an instance is removed from the DataWriter's queue during a disconnection, the instance will remain in the NOT_ALIVE_NO_WRITERS state in the DataReader queue. The DataReader will not transition it to the last known state.

For example:

  1. The instance is ALIVE on the DataWriter and DataReader.
  2. The DataWriter and DataReader are disconnected: the DataReader sees a state of NOT_ALIVE_NO_WRITERS (assuming no other writers are writing the instance).
  3. On the DataWriter side, during the disconnection, the instance is NOT_ALIVE_DISPOSED.
  4. The instance is removed altogether from the DataWriter queue (because, for example, the DataWriter is configured with autopurge_disposed_instances_delay in its 47.31 WRITER_DATA_LIFECYCLE QoS Policy to a value less than the duration of the disconnection).
  5. The DataWriter and DataReader are re-connected.

The resulting status on the DataReader side is NOT_ALIVE_NO_WRITERS, because:

  • The DataReader cannot possibly know the NOT_ALIVE_DISPOSED state, which occurred during the disconnection. The DataWriter cannot possibly tell the DataReader that state because the instance has been purged.
  • Connext does not transition the instance to the ALIVE state on the DataReader (the last known state to the DataReader before the disconnection), because that is not the correct state, either.
  • The DataReader sees the state as NOT_ALIVE_NO_WRITERS, because NOT_ALIVE_NO_WRITERS is the state of an instance when no DataWriters are actively maintaining the instance in the ALIVE or NOT_ALIVE_DISPOSED states.
19.1.5.3.2 Previously Unregistered Instances Not Recovered After Reconnection

The instance state consistency feature only applies to instances that a DataWriter was actively maintaining at the time of a disconnection between a DataReader and DataWriter. This means that if a DataWriter has unregistered from an instance before a disconnection and then updates the state of the instance resulting in it being ALIVE or NOT_ALIVE_DISPOSED before reconnecting, the state of the instance will not transition to that state on the DataReader when they are reconnected.

19.1.5.3.3 Interactions with DataReader Instance Removal

The INSTANCE_REMOVAL options (in the instance_replacement field, in the 48.2 DATA_READER_RESOURCE_LIMITS QosPolicy (DDS Extension)) configure when an instance can be removed from a DataReader queue, if ever. INSTANCE_REMOVAL applies to instances in a FIFO manner, so that the oldest updated instance of the instances that are eligible for removal will be removed first. Instance state transitions due to the instance state consistency feature do not currently count as an 'update' to the instance, and therefore may affect in what order instances are removed when the max_instances resource limit (in the 47.22 RESOURCE_LIMITS QosPolicy) is reached.

19.1.5.3.4 Possible Non-Deterministic Instance States across DataReaders when Multiple DataWriters Update Same Instances

Multiple DataWriters may update the same instance and may maintain the instance in different states from each other (that is, one considers it ALIVE and another considers it NOT_ALIVE_DISPOSED). In these cases, a matching DataReader may see the instance in one state or another depending on which DataWriter the DataReader regains liveliness with first.

This happens because when using instance state consistency upon reconnection with a DataWriter, DataReaders only update instances that are in the NOT_ALIVE_NO_WRITERS state upon the reconnection. Otherwise, the DataReaders keep the instances in the most current state from the active DataWriters of the instance.