Issue 8892: subset of OMG IDL
Issue 9506: Order of parameters incorrect in PSM
Issue 9547: Invalid DURABILITY_SERVICE reference on the DataWriter
Issue 9574: Need to clarify what is meant by "RELATED_OBJECTS"
Issue 9575: clarify allowable (spec compliant) ways to implement ObjectReference[].
Issue 9964: create_contentfilteredtopic Method Prototype and Description Out
Issue 10357: Section: 2.1.1.2.1
Issue 10358: Section: 2.1.2.2.1.9
Issue 10359: Section: 2.1.2.3.1
Issue 10360: Section: 2.1.2.3.2
Issue 10361: Section: 2.1.2.3.6.1
Issue 10362: Section: 2.1.2.5.1.3
Issue 10363: Section: 2.1.2.5.3
Issue 10364: Section: 2.1.2.5.3.8
Issue 10365: Section: 2.1.2.5.3.9
Issue 10366: Section: 2.1.3
Issue 10367: Section: 2.1.3.5
Issue 10368: Section: 2.1.3.14
Issue 10369: Section: 2.1.3.18
Issue 10370: Section: 3.1.4.5
Issue 10542: PIM Spec should have separate tables for Foo types, like DCPS section does
Issue 10543: DLRL Issue: Diagrams in Fig 3.5 and Fig 3.6 look improperly captioned
Issue 10544: Request clarification on a WRITE_ONLY CacheAccess, cloning, and refresh()
Issue 10545: DLRL Issue: Need clarification on limitations of bi-directional association
Issue 10546: Request clarification of how to handle a dangling related object
Issue 10547: DLRL Issue: Int the future, allow DLRL valuetype implementations?
Issue 10548: DLRL Issue: Request clarification on the behavior of is_modified
Issue 10549: Should "set" method called outside of writable CacheAccess throw exception?
Issue 10550: DLRL Issue: Error in the ownership of a SelectionCriterion
Issue 10551: DLRL Issue: Error in the IDL for the SelectionListener
Issue 10552: IDL interfaces for ObjectListener and FooListener are inconsistent
Issue 10553: Request clarification: what can you do with a deleted object?
Issue 10554: Request clarification on interface of DLRL object with multi-attribute
Issue 10555: Can a CacheAccess::refresh() throw an AlreadyClonedInWriteMode exception?
Issue 10556: DLRL Issue: Mismatch between DLRL and CORBA on enumerations
Issue 10557: Proposed Enhancement: allow QoS directly on a DLRL object type?
Issue 10581: Section: 2.2.3
Issue 10661: Unclarities in section 3.1.4.2.3
Issue 10662: Unclarities in table in section 3.1.6.2 the row regarding the CacheAccess
Issue 10663: Clarify usage of create_cache operation
Issue 10664: Clarify usage of refresh operation on the CacheBase, section 3.1.6.3.2
Issue 10665: Clarify usage of cache_usage operation on the CacheBase, section 3.1.6.3.2
Issue 10666: Which exceptions can be raised under which circumstances?
Issue 10667: Clarify what happens in the purge operation of the CacheAccess
Issue 10668: Rewrite sentence on page 3-1, section 3.1
Issue 10669: Clarify exception condition
Issue 10670: Clarify usage of find_home_by_name
Issue 10671: Clarify exceptions with operation register_all_for_pubsub
Issue 10672: Clarify various things with operation enable_all_for_pubsub
Issue 10673: Clarify exceptions for enable_updates and disable_updates operations of Cac
Issue 10674: In section 3.1.6.3.5 regarding the CacheListener clarify some things
Issue 10675: In section 3.1.6.3.6 regarding the Contract clarify some things
Issue 10676: In section 3.1.6.3.7 regarding the ObjectHome clarify some things
Issue 10677: In section 3.1.6.3.11 regarding the FilterCriterion clarify some things
Issue 10678: getter/setter/is_modified operations
Issue 10679: Clarify usage of the destroy() operation on the ObjectRoot
Issue 10680: Clarify usage of the is_modified() operation on the ObjectRoot
Issue 10681: Description not detailed enough
Issue 10682: Clarify text on page 3-35 directly following the operation descriptions.
Issue 10683: Clarify exceptions for add/put operations on List in section 3.1.6.3.16
Issue 10684: Clarify exceptions
Issue 10685: Clarify listeners
Issue 10686: (last) end_updates call on CacheListeners
Issue 10687: Clarify typical scenario for read mode of a CacheAccess in section 3.1.6.5.
Issue 10688: Clarify typical scenario for write mode of CacheAccess in section 3.1.6.5.2
Issue 10689: Clarify what happens with selection->refresh if auto_refresh is true The Implied IDL needs to be extended with attribute examples for class Foo
Issue 10690: The Implied IDL needs to be extended with attribute examples for class Foo
Issue 10691: The generated class FooImpl is not mentioned in the implied idl
Issue 10692: Usage of Undefined unclear
Issue 10693: Clarify exceptions/usage for remove operation on List in section 3.1.6.3.16
Issue 10694: Clarify usage of Fully qualified names in the model tags in section 3.2.2.3
Issue 10695: Section 3.1.3.1 on page 3-3
Issue 10696: Unclear sentence in section 3.1.6.1.1
Issue 10697: Section 3.2.1.2.1 Generic DLRL Entities get_instance
Issue 10698: The read_state of a cache object contains some typos
Issue 10699: Clearly separate default mapping from pre-defined mapping
Issue 10700: Cache
Issue 10701: non-existing elements
Issue 10702: Unregistered objects
Issue 10703: Describe exact event propagation in case of inheritance + multiple listener
Issue 10704: samples from the underlying DataReaders
Issue 10705: Change description on mapping rules for Exceptions or return values
Issue 10706: Add exceptions, clarify usage of other exceptions
Issue 10707: DCPSError also becomes a 'runtime' exception
Issue 10717: Remove the CacheDescription object
Issue 10718: Add attribute to CacheAccess (section 3.1.6.3.3)
Issue 10719: Add an attribute to get the home_index
Issue 10720: Relationships to objects that have been deleted are not allowed.
Issue 10721: getters of relationships
Issue 10722: Prevent writing contents of CacheAccess while 'invalid' relations exists
Issue 10723: Let the attach/detach listener operation return a boolean
Issue 10724: set_query and set_parameters operation
Issue 10725: Introduce the clear() operation on the Collection interface.
Issue 10726: Support local class in Mapping XML
Issue 10727: Enable_all_for_pubsub operation
Issue 10728: set_auto_deref, deref_all, underef_all operations
Issue 10729: Cache should have a getter to obtain its related DomainParticipant.
Issue 10732: Proposal to make the is_xxx_modified operation optional
Issue 10733: The classname in FullOid makes no sense in case of a 'local' Object model
Issue 10734: Add an operation to the Cache
Issue 10735: Selection should have a non-listener way of obtaining the members
Issue 10736: FilterCriterion
Issue 10737: How are deleted objects treated in a CacheBase and a Selection
Issue 10738: objects instances in a writeable CacheAccess
Issue 10739: Describe exact behaviour of compositions and associations in the DLRL.
Issue 10740: DLRL object
Issue 10741: There is a lot of redundancy in the XML file.
Issue 10742: Indicate the semantics of merging separate topics into one single object
Issue 10743: instance_state of a DCPS instance becomes NOT_ALIVE_NO_WRITERS
Issue 10744: Extend the XML to allow optional relationships
Issue 10745: cloned objects
Issue 10746: Minor typo's and inconsistencies
Issue 10747: Typo in section 3.1.4.2.1
Issue 10748: Typo in section 3.1.6.1.2.1
Issue 10749: Various typos in section 3.1.6.3.4, Cache
Issue 10750: Various typos in section 3.1.6.3.7, ObjectHome
Issue 10751: which_contained_modified operation should be removed
Issue 10752: Typos in section 3.1.6.4.1
Issue 10753: Typos in section 3.1.6.4.3 & 3.1.6.4.4 Typos in section 3.1.6.6
Issue 10754: Typos in section 3.1.6.6
Issue 10755: Typos in section 3.2.1.2 IDL description
Issue 10756: Typos in section 3.2.1.2 IDL description
Issue 10757: section 3.2.1.2 IDL description on page 3-52
Issue 10758: section 3.2.1.2.2 Implied IDL
Issue 10759: In section 3.2.2.3.2.11 MultiAttribute.
Issue 10760: In section 3.2.2.3.2.11 MultiAttribute, the example xml code
Issue 10761: section 3.2.2.3.2.13 MultiRelation, 3rd bullet
Issue 10762: section 3.2.2.3.2.10 MonoAttribute, 3.2.2.3.2.12 MonoRelation
Issue 10763: In section 3.2.3.5 Code example, several typos
Issue 10764: Figure 3-4 and section 3.2.1.2.2 Implied IDL
Issue 10765: section 3.2.2.3.2.13 MultiRelation - XML code
Issue 10766: Section 3.2.1.1 Mapping Rules regarding error reporting
Issue 10768: Inconsistency in attribute definitions for valuetype ObjectRoot
Issue 10769: Figure 3-4 on page 3-16 is missing some operations in some classes
Issue 10770: use case for multiple valueFields
Issue 10771: Give each CacheAccess its own Publisher and DataWriters
Issue 10804: A descriptive name
Issue 10805: DataReader semantics for historical data are insufficient
Issue 10806: Invalid DURABILITY_SERVICE reference on the DataWriter
Issue 10807: Add name attribute to Entity
Issue 10808: Semantics instance liveliness and ownership unclear
Issue 10809: Missing TypeSupport operations
Issue 10810: Inconsistent lookup semantics
Issue 10811: Default built-in ReaderDataLifecycle values
Issue 10812: Cancel transaction
Issue 10813: Get entity enabled state
Issue 10980: Section: 2.1.2.5.2
Issue 10993: DDS DCPS Issue: PRESENTATION=GROUP and QoS
Issue 10994: Specify names of mono-relation and multi-relation fields for default mappin
Issue 10995: DDS DLRL Issue: Clarification on the use of a Set in a DLRL Query
Issue 10996: create_object and create_unregistered_object
Issue 10997: clarify behavior of content_filters in an inheritance hierarchy
Issue 10998: DDS DLRL Issue: Clarify behavior of a Composition
Issue 12212: DDS typos and omissions
Issue 12276: DURABILITYSERVICE_POLICY_NAME
Issue 12360: Specify the allowed IDL Types within DDS Topic structs
Issue 8892: subset of OMG IDL (data-distribution-rtf)
Click here for this issue's archive.
Source: Naval Surface Warfare Center (Ms. Traci McDonald, traci.mcdonald@navy.mil)
Nature: Uncategorized Issue
Severity:
Summary:
In the DDS specification version 05-03-09, page 2-1 specifies that the PSM is for the OMG IDL platform. In section 2.2.1 (page 2-193), more detail is given as to what this PSM looks like. One area I don't see covered is the subset of OMG IDL that the DDS specification supports from a user's perspective. When a user defines an IDL file, what data types should and shouldn't be used? It looks as though valuetypes are not supported, but is it possible to explicitly specify what OMG IDL types are supported by implementations of the DDS specification?
The RTF agrees that this area is underspecified. However, it could not come to a resolution on this. The types that should be supported by DDS implementations as well as the mechanisms for extending those types are currently under investigation by the DDS SIG. Therefore is expected that this issue will be resolved in a subsequent RTF.
In the PSM for get_discovered_topic_data() and get_discovered_participant_data() on the DomainParticipant, the data parameter should be first followed by the handle. The order is correct in the PIM. Proposed Resolution: Make the suggested modifications. Proposed Revised Text: Section 2.2.3 DCPS PSM : IDL In the DomainParticipant interface: Change the order of the parameters to get_discovered_participant_data from "in InstanceHandle_t participant_handle, inout ParticipantBuiltinTopicData participant_data" to inout ParticipantBuiltinTopicData participant_data, in InstanceHandle_t participant_handle". Change the order of the parameters to get_discovered_topic_data from "in InstanceHandle_t topic_handle, inout TopicBuiltinTopicData topic_data" to inout TopicBuiltinTopicData topic_data, in InstanceHandle_t topic_handle".
Summary:
In the QoS table (section 2.1.3. Supported QoS) the 'concerns' row illegally specifies the DataWriter for the DURABILITY_SERVICE QoS.
Proposed Resolution:
Proposed Revised Text:
Section 2.1.3 Supported QoS, QoS Table:
Entry for DURABILITY_SERVICE QoS, remove the word 'DataWriter' from the 'concerns' column.
The RTF could not come to a resolution on this. deferred
Need to clarify what is meant by "RELATED_OBJECTS" -- ObjectRoot has an is_modified method that takes a scope, OBJECT_ONLY, CONTAINED_OBJECTS and RELATED_OBJECTS. Whereas it is clear that OBJECT_ONLY means only attributes on this ObjectRoot and that CONTAINED_OBJECTS includes any changes to objects that this object refers to, it is not clear what RELATED_OBJECTS means.
Need to clarify and/or enumerate allowable (spec compliant) ways to implement ObjectReference[]. The method definitions have return values or parameters specified by ObjectReference[]. Given that this is part of the platform independent model, it would appear that one could approach the implementation of this in C++ in one of two ways -- as std::vector<ObjectReference *> or as an ObjectReference array. It is unclear which would be the preferred spec compliant way to do this. Alternatively, one could implement this as a language specific container, vector, list, map or whatever is the best performing container for the given situation, but would that not be in compliance with the spec at all?
I was looking at the DDS specification and saw that the name of the first parameter for DomainParticipant's create_contentfilteredtopic method is "name" in the table of methods (section 2.1.2.2.1) and it is "topic_name" in the method description (section 2.1.2.2.1.7). I assume the name should be consistent.
I don't think that it is explicitly stated anywhere in this spec that each DataWriter and each DataReader maintains its own set of samples. Samples are not maintained by Publishers, Subscribers. It is implied in several places, e.g. the fact that RESOURCE_LIMITS applies to DataWriter and DataReader and not to Publisher and Subscriber. It took me a while to figure this out. It is possible for a Publisher to have more than one DataWriter with the same topic, and a Subscriber to have more than one DataReader with the same topic. The semantics of DataReader.take, for instance, are unclear unless it is understood that each DataReader has its own samples. Evidently a take operation on one DataReader does not disturb the samples of another DataReader with the same Publisher and Topic. Please clarify the specification in this regard. Figure 2-1 and accompanying text would be one place.
Context: "The resulting type is specified by the type_name argument." What happens if the specified type is inconsistent with the subscription_expression?
The class description for TopicDescription says "no attributes" but in fact two attributes are listed immediately below.
Context: "A Topic is identified by its name, which must be unique in the whole Domain." There is nothing in the description of create_topic that indicates that this constraint is enforced. Is it possible for multiple domain_participants to execute create_topic with the same name? What happens if they specify different types?
Context: "The application may pass nil as the value for the type_name. In this case the default typename as defined by the TypeSupport (i.e., the value returned by the get_type_name operation) will be used." What happens if register_type is given a type_name that differs from the result of get_type_name?
Context: "For each instance the middleware internally maintains an instance_state." Obviously this instance_state could be different for different DomainParticipants. Might it be different for two Subscribers of the same DomainParticipant? How about two DataReaders of the same Subscriber?
Context: DataReader.read operation Why are sample_states, view_states, and instance_states provided as separate parameters? Aren't they contained in sample_infos? More explanation required.
Context: "The use of this variant allows for zero-copy access to the data and the application will need to “return the loan” to the DataWriter using the return_loan operation (see Section 2.1.2.5.3.20 )." Should be DataReader?
Context: "The act of taking a sample removes it from the DataReader so it cannot be ‘read’ or ‘taken’ again." See my earlier comment. Apparently if there are other DataReaders for the same Topic and the same Subscriber, their samples are not disturbed. Assuming this is true, it should be stated.
Context: "And three integers: history_depth, max_samples, max_instances, max_samples_ per_instance" There are four integers here.
Context: "The “persistence service” is the one responsible for implementing the DURABILITY kinds TRANSIENT and PERSISTENCE." You mean PERSISTENT
Context: "In other words, the DataReader may miss some datasamples but it will never see the value of a data-object change from a newer value to an order value." You mean "older".
Context: "If the kind is set to KEEP_ALL, then the Service will attempt to maintain and deliver all the values of the instance to existing subscribers. The resources that the Service can use to keep this history are limited by the settings of the RESOURCE_LIMITS QoS. If the limit is reached, then the behavior of the Service will depend on the RELIABILITY QoS. If the reliability kind is BEST_EFFORT, then the old values will be discarded." This violates the ordinary English meaning of KEEP_ALL. Can't the same effect be achieved by specifying KEEP_LAST with history_depth=max_samples_per_instance? If so, then KEEP_ALL should not be allowed for RELIABILITY=BEST_EFFORT.
Context: "However an exiting DCPS model by construction is unlikely to rely heavily on inheritance between its ‘classes.’" You mean "existing".
It would be helpful if the DLRL section's Platform-Independent Model broke out separate interface tables for its generated types, as the DCPS spec does with FooTypeSupport, FooDataReader, FooDataWriter, etc. This would enable the spec to clarify some slightly confusing tables, such as the table for a SelectionListener that shows on_object_in, on_object_out, and on_object_modified accepting an ObjectRoot parameter, when we really know it accepts a Foo. Breaking out a separate FooSelectionListener to demonstrate this would be useful, as it was for the DCPS section.
It looks like the Fig 3.5 and Fig 3.6 diagrams have incorrect captions. I believe they should be corrected as follows: Fig 3.5: "read_state" and "write_state" should be swapped; the VOID diagram refers to read_state. The caption on the right-hand state chart should be "read_state of a *Cache object* in READ_ONLY or READ_WRITE mode". Fig 3.6's first state chart should have a caption that reads "read_state of a CacheAccess object in READ_ONLY or READ_WRITE mode"; the second state chart's caption should read "CacheAccess object", not just "CacheAccess"
The spec is not completely clear on what you can and cannot do with a WRITE_ONLY CacheAccess. Is it legal to clone an object into a WRITE_ONLY CacheAccess, or are we only permitted to create brand new objects (via create_object) in a WRITE_ONLY CacheAccess? On a related note, is a CacheAccess::refresh() for a WRITE_ONLY CacheAccess always a noop, or should it throw an exception? It seems like it should thrown an exception (such as a WriteOnlyMode exception, which doesn't exist) to be consistent with CacheAccess::write, which throws a ReadOnlyMode exception when you call it from a READ_ONLY CacheAccess.
Bi-directional associations involving multi-relations (either 1-to-N or M-to-N) and underspecified. Modifications to one side of a bi-directional relationship is supposed to be automatically reflected in the other side of the relationship, (see 3.1.3.2.2) but that is not always possible given the provided Collection interfaces.
The behavior is clear if one of the multi-relations involved is a Set.
A change one side of the association causes an add/remove on the Set side of the association.
The behavior is interpretable if one of the multi-relations involved is a List. In a UML 1-to-N or M-to-N relationship, is is expected that there will not be duplicate entries in the "multi" side of the relationship. In other words, in a Foo<->*Bar relationship, the same Bar will not occur more than once in the Foo's list of Bars. Using this interpretation, you can interpret a n "add" to the non-List side of the relationship as implying that a new object is added to the end of the list, and a "remove" as implying that the object is removed from the List. In other words, we can treat the List just like a Set and allow changes to the association from both sides.
The caveat is that you can't have duplicate entries in a List that is involved in a bi-directional association. (Then again, what if you modify the association from the List side, and you put duplicate values? Do we allow that?)
Bi-directional assoications get very tricky when IntMaps or StrMaps are involved.
If two maps are involved (e.g. IntMap to StrMap), then it is impossible to modify the association. If I add to it from the IntMap side, then I have to somehow specify the key to use on the StrMap side. The Collection interfaces provide no mechanism to to this.
If only one map is involved (either 1-to-N or M-to-N), then I must to all modifications from the map side. Otherwise, I have no way to indicate the Map key when I modify the association.
So, the specification need to be clarified on bi-directional associations:
1. The behavior of a List in a bi-directional association must be clarified. Is what I said above correct, or should there be limitations on how you can use a List in a bi-directional association?
2. The usage of IntMaps and StrMaps must be clarified. There are several possibilities:
a. IntMaps and StrMaps are not allowed in bi-directional associations
b. IntMaps and StrMaps are allowed, but you must make all modifications to the association from the Map side of the association.
Map-to-Map associations are not allowed.
c. All types of associations are allowed, and the OMG will add to the Collection API to provide the methods needed to set the map keys appropriately from either directionHow should dangling relationships be handled? For example, suppose I have a Foo->Bar relationship. My Foo has a related Bar. 1. I clone the Foo and the Bar into the CacheAccess. 2. Someone deletes the Bar, but does not update the Foo's relationship. 3. I refresh the CacheAccess, which deletes my Bar in the CacheAccess, but my Foo thinks it's still related. What should happen when I call Foo.get_bar()? a. throw an exception? (NotFound? AlreadyDeleted?) b. return a NULL?
The DLRL spec uses CORBA valuetypes to specify DLRL objects. The implementations of these CORBA valuetypes (e.g. Foo) are completely provided by the DLRL -- the user doesn't have to implement anything, which is great from a simplicity standpoint. However, this limits the DLRL valuetypes to being not much more that fancy structs with inheritance and relationships, but no behavior. One of the capabilities of standard CORBA valuetypes is the ability to specify valuetype operations in IDL and then implement them in the target language. The CORBA valuetype specification has permits the user to write the valuetype's implementation class, providing behavior for the methods specified in IDL. The user then implements a valuetype factory as a hook to create instances of the user-written valuetype implementation. I can see a similar comcept as useful to DLRL. It would probably be useful for a user to specify valuetype operations in DLRL IDL and implement them in the target language. One way to do this is to have the DLRL compiler generate a Foo class with a pure virtual method for each valuetype operation. The user inherits from it, implementing a MyFoo with implemntations of the pure virtual methods. We also need a factory; naturally, we'd use the FooHome. The generated FooHome would include a pure virtual "create()", or something like it, which the user would implement in a derived MyFooHome class to create instances of his MyFoo. Instead of creating a FooHome and registering it with the Cache, the user creates a MyFooHome and registers it with the Cache. The DLRL core uses the MyFooHome's overridden create() method to make new Foo handles (which are actually MyFoo handles, containing the user's behavior). There may be holes in this, but the basic idea is probably useful. It would permit a DLRL object model to be a full object model.
The spec implies that is_modified is only valid in the context of a listener callback (I suppose that would be an ObjectListener or a SelectionListener callback). See section 3.1.6.4.1, general scenario, which says that after end_updates is called, the "modification states of the updated objects is cleaned". Does that mean that, outside of an ObjectListener or SelectionListsner, a call to is_modified always returns false? Also, the spec is not clear about what happens in a CacheAccess. A CacheAccess, of course, has no listeners. So, for the is_modified() methods to be useful from a CacheAccess, they'd have to be valid from outside of a listener for an object in a CacheAccess. Is that the case? There is also the corner case of a manual Selection. A manual Selection might not have a listener. There wouldn't be any way to call is_modified () on an object in a manual Selection that doesn't have a Listener -- you'd have to attach a Listener to the manual selection, and call is_modified in the callback that happens when you call refresh(). Is that what the spec intends?
A set_<attribute> call on a DLRL object is only valid from within a writable CacheAccess. It seems that, if an application calls set_<attribute> on a DLRL object outside of a writable CacheAccess, then set_<attribute> should throw an exception -- probably a PreconditionNotMet exception. However, the spec doesn't indicate that an exception should be thrown in this case. It only mentions the case where the attribute is a key field in the non-default mapping (3.1.6.3.14)
The spec says that the Selection takes ownership of the SelectionCriterion parameter passed in create_selection (see 3.1.6.3.7, ObjectHome, create_selection bullet item). However, this violates CORBA "in" parameter passing semantics, in which the client owns an "in" parameter and is responsible for it. The right way (in CORBA terms) to do this is for the client to create the FooSelectionCriterion on the heap, store it in a FooSelectionCriterion_var smart pointer, and let the smart pointer release it when it goes out of scope. The Selection can make a "copy" of the FooSelectionCriterion, presumably by bumping up its reference count.
The IDL for SelectionListsner has an error. The base SelectionListener class shows on_object_out() accepting an ObjectRoot; but the generated FooSelectionListener shows on_object_out (correctly) accepting a Foo. Putting the base SelectionListener's on_object_out() inside of the comment would fix this.
The base IDL and implied IDL are inconsistent for ObjectListener and FooListener: 1. The return values are "boolean" in the base class, "void" in the derived. Should be "boolean" for all. 2. The comments in ObjectListener IDL imply that only on_object_modified has a Foo-specific version generated in the derived class. But FooListener has Foo-specific versions for all three operations. FooListener version is correct.
If I have a handle on an object (such as a Foo), and the Foo is deleted from underneath me, I understand that I'll get an AlreadyDeleted exception if I try to do anything (call a setter or a getter) on the Foo. However, it seems like you should be able to get the OID and the read_state (which should be OBJECT_DELETED) from a deleted object. Can you? Can I call oid() and read_state() on a deleted object without getting an AlreadyDeleted exception?
Does a Collection attribute have a setter?
For example, suppose I have a Foo with a List<Long> in it (this isn't valid IDL, please humor me):
valuetype Foo : DDS::ObjectRoot
{
public List<long> my_longs;
}
That generates a Foo::get_my_longs() in the target language. Should it also generate a Foo::set_my_longs() in the target language?
Or should there simply be a Foo::get_my_longs(), and I modify the List<long> via add, put, etc?
Can a CacheAccess::refresh() throw an AlreadyClonedInWriteMode exception? Suppose an object is cloned into a writable CacheAccess with scope=RELATED_OBJECTS and some depth >1. Now, suppose object2, which is unrelated, is cloned into a different writable CacheAccess. Then, suppose incoming updates cause object and object2 to be related, where a subsequent CacheAccess::refresh() would pull object2 into the first writable CacheAccess. But, wait, it's already in the other writable CacheAccess. Does that cause an exception on the refresh()?
The DLRL spec indicates that enumerations are mapped to 8-bit integers or strings, not to IDL enums. See 3.1.4.2.3 Can that be right? An IDL enum is a 32-bit integer. See 3.11.2.4 in the 04-03-01 CORBA spec. It seems strange not to map a DLRL enum to an IDL enum. Is there a reason?
It might be useful to allow QoS settings directly on a DLRL object type. For things like HISTORY, it would be a lot cleaner to apply QoS at the DLRL object type level (say, an object type and everything related to a certain depth) and let DLRL pass it through to DCPS. That way, the user doesn't need to know his application's DLRL-to-DCPS mapping -- the same QoS application code could be used regardless of how the DLRL-to-DCPS mapping is configured. The user's QoS code wouldn't depend on the details of the application's mapping, which could change.
The PSM mapping of BuiltinTopicKey_t is defined to be as; struct BuiltinTopicKey_t { BUILTIN_TOPIC_KEY_TYPE_NATIVE value[3]; }; But the DDS Interoperability Wire Protocol (RTPS) specifies that GUID consists of 12 bytes GuidPrefix and 4 bytes EntityId. In order to map GUID and BuiltinTopicKey, we should define BuiltinTopicKey as the following; struct BuiltinTopicKey_t { BUILTIN_TOPIC_KEY_TYPE_NATIVE value[4]; };
Problem: Various things are unclear in this section, for example the last bulleted list in this section does not take the Set type of a multi-valued attribute into account. A bullet needs to be added to state that the set does not contain an index key. Also replace 'row' with the word 'instance' in accordance with other issues. Also it needs to be indicated that in case of predefined mapping that the user defined keys identify the object, not the OID. In accordance with another issue, replace the word 'row' with 'instance'. Replace the word 'cell' with 'field' Solution: Replace: Mono-valued attributes and relations are mapped to one (or several) cell(s)7 in a single row whose key is the means to unambiguously reference the DLRL object (i.e., its oid or its full oid, depending on the owner class characteristics as indicated in the previous section): With: Mono-valued attributes and relations are mapped to one (or several) field(s)7 in a single instance whose key is the means to unambiguously reference the DLRL object (i.e. its oid, its full oid, or its user defined keys, depending on the owner class characteristics as indicated in the previous section): Replace (in the first bulleted list of the section): reference to another DLRL object (i.e., relation) -> as many cells as needed to reference unambiguously the referenced object (i.e., its oid, or its full oid as indicated in the previous section). With: reference to another DLRL object (i.e., relation) -> as many fields as needed to reference unambiguously the referenced object (i.e., its oid, its full oid, or its user defined keys as indicated in the previous section). Replace: Multi-valued attributes are mapped to one (or several) cell(s) in a set of rows (as many as there are items in the collection), whose key is the means to unambiguously designate the DLRL object (i.e., oid or full oid) plus an index in the collection. o For each item, there is one instance that contains the following, based on the type of attribute: o simple basic type -> one cell of the corresponding DCPS type; o enumeration -> one cell of type integer or string; o simple structures -> as many cells as needed to hold the structure; o reference to another DLRL object -> as many cells as needed to reference unambiguously the referenced object (i.e., its oid, or its full oid as indicated in the previous section). o The key for that row is the means to designate the owner's object (i.e., its oid or full oid) + an index, which is: o An integer if the collection basis is a list (to hold the rank of the item in the list). o A string or an integer9 if the collection basis is a map (to hold the access key of the item in the map). With: Multi-valued attributes are mapped to one (or several) field(s) in a set of instances (as many as there are items in the collection), whose key is the means to unambiguously designate the DLRL object (i.e., oid or full oid, or its user defined keys) plus an optional index in the collection. o For each item, there is one instance that contains the following, based on the type of attribute: o simple basic type -> one field of the corresponding DCPS type; o enumeration -> one field of type integer or string; o simple structures -> as many fields as needed to hold the structure; o reference to another DLRL object -> as many fields as needed to reference unambiguously the referenced object (i.e., its oid, its full oid, or its user defined keys as indicated in the previous section). o The key for that row is the means to designate the owner's object (i.e., its oid, full oid, or its user defined keys) + an optional index, which is: o An integer if the collection basis is a list (to hold the rank of the item in the list). o A string or an integer9 if the collection basis is a map (to hold the access key of the item in the map). o No index if the collection basis is a set (The item value field is implicitly the key in this case)
Problem: In the table in section 3.1.6.2 in the row regarding the CacheAccess it should be clarified that one CacheAccess should be used by one thread. If multiple threads require access to the same CacheAccess it is the application responsibility to ensure thread safety. Solution: Replace: Class that encapsulates the access to a set of objects. It offers methods to refresh and write objects attached to it; CacheAccess objects can be created in read mode, in order to provide a consistent access to a subset of the Cache without blocking the incoming updates or in write mode in order to provide support for concurrent modifications/updates threads. With (sentence at the end added): Class that encapsulates the access to a set of objects. It offers methods to refresh and write objects attached to it; CacheAccess objects can be created in read mode, in order to provide a consistent access to a subset of the Cache without blocking the incoming updates or in write mode in order to provide support for concurrent modifications/updates threads. A CacheAccess should only be used by one thread, if multiple threads require access to the same CacheAccess then it is the responsibility of the application to ensure thread safety.
Problem: The create_cache operation is responsible for creating a DCPS publisher and/or subscriber, depending on the cache usage. If this creation fails a DCPSerror should be thrown, the text should state this. It should also be stated that a cache is created by default with updated_enabled() returning false, forcing the application to explicitly enable the cache for updates. This prevents that the application immediately starts receiving updates after the enable_all_for_pubsub. It should also be clarified that the QoS settings on the participant determine if the publisher/subscriber will be created as enabled or disabled entities. IE if the QoS setting for autoenable_created_entities is set to true on the partcipant the Subscriber and Publisher are created in an enabled state, if set to false then both entities will be created in a disabled state. Solution: Replace: Depending on the cache_usage a Publisher, a Subscriber, or both will be created for the unique usage of the Cache. These two objects will be attached to the passed DomainParticipant. With: Depending on the cache_usage a Publisher, a Subscriber, or both will be created for the unique usage of the Cache. These two objects will be attached to the passed DomainParticipant. If the creation of the Publisher and/or Subscriber required by the Cache fails a DCPSError is raised. The Cache is created with updates disabled by default (updates_enabled() returning false). The autoenable_created_entities QoS setting of the entity_factory of the passed DomainParticipant determines if the Publisher and/or Subscriber will be created in an enabled or a disabled state. If this QoS setting is set to true then these entities will be created in an enabled state, if set to false then these entities will be created in a disabled state. The Publisher and/or Subscriber themselves will always have their entity_factory.autoenable_created_entities QoS setting set to false, ensuring that DataWriter and DataReader entities are created in a disabled state, this setting may be overridden before the register_all_for_pubsub() call to the created Cache, which will result in the DataWriter and DataReader entities to be created as enabled entities, in this scenario updates will be received from the moment the register_all_for_pubsub is called, but can only be viewed after a call to the enable_all_for_pubsub. The creation of Topic entities during the register_all_for_pubsub is also slaved to the passed DomainParticipant's entity_factory.autoenable_created_entities QoS setting at the time the register_all_for_pubsub() is called.
Problem: In section 3.1.6.3.2 in the explantion of the refresh operation it should be stated a DCPSError may be raised if an error occurred while trying to read data from DCPS. And it should be stated a PreconditionNotMet exception is raised in case the cache_usage of the cache base excludes read operations. Solution: Replace: o Refresh the contents of the Cache with respect to its origins (DCPS in case of a main Cache, Cache in case of a CacheAccess). With: o Refresh the contents of the CacheBase with respect to its origins (DCPS in case of a main Cache, Cache in case of a CacheAccess). A PreconditionNotMet is raised if the cache_usage excludes read operations. A DCPSError is raised if an error occurred while trying to read data from DCPS. If the CacheBase represents a Cache that has updates_enabled set to true, then this operation is considered a no-op. In section 2.2.1.2 IDL Description on page 3-57 regarding the definition of the local interface CacheBase replace: void refresh( ) raises (DCPSError); With: void refresh( ) raises (DCPSError, PreconditionNotMet);
Problem: The explanation of the cache usage only talks about the intent to support write operations. However if the usage is WRITE_ONLY there is no intent to support read operations, such as refresh as well. This should be stated as such. Solution: Replace: The cache_usage indicates whether the cache is intended to support write operations (WRITE_ONLY or READ_WRITE) or not (READ_ONLY). This attribute is given at creation time and cannot be changed afterwards. With: The cache_usage indicates whether the cache is intended to support write operations only (WRITE_ONLY) or read operation only (READ_ONLY) or both read and write operation (READ_WRITE). This attribute is given at creation time and cannot be changed afterwards.
Problem: The description of the write operation does not specify which exceptions can be thrown. Not that the IDL description on page 3-57 also states the ReadOnlyMode exception can be raised, but that exception no longer exists! So fix this as well. See issue XXX and XXX for mention of the TimeOut and InvalidObjects exceptions. Solution: Replace: o Write objects (write). If the CacheAccess::cache_usage allows write operation, those objects can be modified and/or new objects created for that access and eventually all the performed modifications written for publications. With: o Write objects (write). If the CacheAccess::cache_usage allows write operation, those objects can be modified and/or new objects created for that access and eventually all the performed modifications written for publications. A PreconditionNotMet is raised if the CacheAccess::cache_usage does not allow the write operation (i.e. usage is READ_ONLY). A TimeOut exception is raised if one of the underlying DCPS DataWriter entities timed out. A DCPSError is raised if the write failed due to an error in the DCPS layer. In section 3.2.1.2 on page 3-57 regarding the IDL description of the write() operation of the interface CacheAccess replace: void write () raises ( ReadOnlyMode, DCPSError); With: void write () raises (DCPSError, PreconditionNotMet, InvalidObjects, TimeOut);
Clarify which exceptions can be raised under which circumstances in the write operation (section 3.1.6.3.3, page 3-21)
Problem: The purge operation needs to be further detailed as what the consequences of the operation are. Also the wrong quotation mark at the end of the description needs to be removed as well. Solution: Replace: Detach all contracts (including the contracted DLRL Objects themselves) from the CacheAccess (purge)." With: Detach all Contracts (including the contracted ObjectRoots themselves) from the CacheAccess (purge). If the CacheAccess is writeable then the CacheAccess will unregister itself for each purged (previously written) ObjectRoot. If the CacheAccess was the last writeable CacheAccess within the scope of the owning Cache for the purged (previously written) ObjectRoot, then an explicit unregister_instance is performed for that instance at the respective DataWriter entity. A DCPSError is raised if the purge failed due to an error on DCPS level. In section 3.2.1.2 on page 3-57 IDL description regarding the CacheAccess interface replace: void purge (); With: void purge () raises (DCPSError);
Clarify what happens in the purge operation of the CacheAccess (section 3.1.6.3.3, page 3-21
Problem: DLRL is unmistakenly linked with DCPS. DLRL requires DCPS entities to create a cache for example, and one can directly request the publisher or subsriber from such a Cache. A DLRL not built on top of DCPS is not a DLRL at all. Solution: Replace: It is an optional layer that may be built on top of the DCPS layer. With: It is an optional layer that is built on top of the DCPS layer.
Problem: The explaination on page 3-24 for the create_cache operation states that a PreconditionNotMet is only raised if the usage of the access is not compatiable with the usage of the cache. It should also say that a PreconditionNotMet is raised if an access is attempted to be created while the cache is not yet enabled for pub sub. Solution: Add the new reason in the description.
Clarify exception condition for precondition not met in the create_access operation of the Cache in section 3.1.6.3.4 on page 3-24
Problem: In section 3.1.6.3.4 on page 3-23 in the description of the operation find_home_by_name of the Cache entity it states that an already registered home can be retrieved using its name. It should be clarified that this name is the fully qualified name (in IDL sense, with '::' as seperator). The name of ObjectHome for Object Foo which is defined in module test thus becomes 'test::Foo'. Solution: Replace: o retrieve an already registered ObjectHome based on its name (find_home_by_name) or based on its index of registration (find_home_by_index). If no registered home can be found that satisfies the specified name or index, a NULL is returned. With: o retrieve an already registered ObjectHome based on its fully qualified name (in IDL sense, meaning for an ObjectHome representing class 'Foo' which was defined in module 'test' has the name "test::Foo") (find_home_by_name) or based on its index of registration (find_home_by_index). If no registered home can be found that satisfies the specified name or index, a NULL pointer is returned.
Problem: Description of the register_all_for_pubsub operation on page 3-23 in section 3.1.6.3.4 doesn't say under which conditions the DCPSError exception is raised Solution: Add the following sentence to the description of the register_all_for_pubsub operation: A DCPSError is raised if an error was encountered while trying to create the DCPS entities
Problem: In section 3.1.6.3.4 on page 3-23 regarding the operation enable_all_for_pubsub several clarifications should be made: 1) In the first sentence before the word 'QoS' is should say (immutable) to clarify it's mainly the idea that immutable QoS settings can be changed at that time. 2) The expression "those two operations" in the second sentence should be replaced by "this operation and the register_all_for_pubsub operation". 3) It should state the DCPSError is raised if an error occurred while enabling the DCPS entities. Solution: Replace: o enable the derived Pub/Sub infrastructure (enable_all_for_pubsub). QoS setting can be performed between those two operations. One precondition must be satisfied before invoking the enable_all_for_pub_sub method: the pubsub_state must already have been set to REGISTERED before. A PreconditionNotMet Exception is thrown otherwise. Invoking the enable_all_for_pub_sub method on an ENABLED pubsub_state will be considered a no-op. With: o enable the derived Pub/Sub infrastructure (enable_all_for_pubsub). Changes to the (Immutable) QoS settings can be performed between this operation and the register_all_for_pubsub operation. One precondition must be satisfied before invoking the enable_all_for_pub_sub method: the pubsub_state must already have been set to REGISTERED before. A PreconditionNotMet Exception is thrown otherwise. A DCPSError is raised if an error occurred while enabling the DCPS entities. Invoking the enable_all_for_pub_sub method on an ENABLED pubsub_state will be considered a no-op.
Problem: In section 3.1.6.3.4 on page 3-23 for the descriptions of the enable and disable updates operation it should state a PreconditionNotMet is thrown if the cache is created with a usage of WRITE_ONLY. It should also state that multiple calls to the operations is considered a no-op. It should also be stated that calling the disable_updates operation results in all cache listeners being triggered with the on_updates_disabled call and for the enable the on_updates_enabled is called in scope of the thread making the call to enable or disable updates. Solution: Replace (see issue XXX(PT-DLRL-TYPO-0011) which already made changes to the disable_updates description): o disable_updates causes incoming but not yet applied updates to be registered for further application, any update round in progress will be completed before the disable updates instruction is taken into account. o enable_updates causes the registered (and thus not applied) updates to be takeninto account, and thus to trigger the attached Listener, if any. With: o disable_updates causes incoming but not yet applied updates to be registered for further application, any update round in progress will be completed before the disable updates instruction is taken into account. All registered CacheListeners will be triggered with the on_updates_disabled call (in scope of the thread calling the disable_updates operation) signaling, to any interested party, that updates on the Cache will no longer be automatically processed and no longer result in listener triggers. If the cache_usage of the Cache is WRITE_ONLY then a PreconditionNotMet is raised. o enable_updates causes the registered (and thus not applied) updates to be taken into account, and thus to trigger the attached CacheListeners, if any. All registered CacheListeners will be triggered before any updates are applied with the on_updates_enabled call (in scope of the thread calling the enabled_updates operation) signaling, to any interested party, that the updates on the Cache will be automatically processed and thus result in listener triggers. If the cache_usage of the Cache is WRITE_ONLY then a PreconditionNotMet is raised. In the IDL description in section 3.2.1.2 on page 3-58 replace: // --- Updates management void enable_updates (); void disable_updates (); With: // --- Updates management void enable_updates () raises (PreconditionNotMet); void disable_updates ()raises (PreconditionNotMet);;
Clarify exceptions for the enable_updates and disable_updates operations of the Cache. Also clarify that the cache listener should be triggered within the scope of these operations
Problem (1/3): In the description for the on_begin_updates it says at the end '(assuming that updates_enabled is true)', which is a bit vague as to the context of that statement. Replace it with something like "This operation will only be triggered for a Cache which has updates_enabled set to true." That statement should also be added at the end of the on_end_updates operation. This clarification is required because the other two operations are not dependant on the state of the updates_enabled… Solution (1/3): Replace: o on_begin_updates indicates that updates are following. Actual modifications in the cache will be performed only when exiting this method (assuming that updates_enabled is true). o on_end_updates indicates that no more update is foreseen. With: o on_begin_updates indicates that updates are following. Actual modifications in the Cache will be performed only when exiting this method. This operation will only be triggered for a Cache which has updates_enabled set to true. o on_end_updates indicates that no more update is foreseen. This operation will only be triggered for a Cache which has updates_enabled set to true. Problem (2/3): The paragraph following the descriptions for all operations says: "In between, the updates ….". Since two new operations where added in the last spec revision this statement is now unclear. In between which operations? This should be clarified to state in between the on_begin_updates and on_end_updates. Solution (2/3): Replace: In between, the updates are reported on home or selection listeners. Section 3.1.6.4, "Listeners Activation," on page 3-41 describes which notifications are performed and in what order. With: In between the on_begin_updates and the on_end_updates calls the updates are reported on home or selection listeners. Section 3.1.6.4, "Listeners Activation," on page 3-41 describes which notifications are performed and in what order. Problem (3/3): The description for the on_updates_enabled and on_updates_disabled both start with a wrong quotation mark. It should be removed. Solution (3/3): Replace: o "on_updates_enabled - indicates that the Cache has switched to automatic update mode. Incoming data will now trigger the corresponding Listeners. o "on_updates_disabled - indicates that the Cache has switched to manual update mode. Incoming data will no longer trigger the corresponding Listeners, and will only be taken into account during the next refresh operation. With: o on_updates_enabled - indicates that the Cache has switched to automatic update mode. Incoming data will now trigger the corresponding Listeners. o on_updates_disabled - indicates that the Cache has switched to manual update mode. Incoming data will no longer trigger the corresponding Listeners, and will only be taken into account during the next refresh operation.
In section 3.1.6.3.5 regarding the CacheListener clarify some things… And remove some typos
Problem (1/4) (typo): Each attribute and operation description wrongly starts with a quotation mark, these should be removed. Problem (2/4) (typo): The description of attribute depth talks about a RELATED_OBJECT_SCOPE. This should be RELATED_OBJECTS_SCOPE (objects should thus be plural). Problem (3/4) (clarification): During the description of the scope attribute the various scopes are explained, for clarification purposes insert the type of scope right after the explaination. Problem (4/4) (clarification): In the description for the set_depth operation, indicate that the depth is ignored unless the scope is set to RELATED_OBJECTS_SCOPE, just like it says at the getter for the depth attribute. Solution: Replace: o "The top-level object (contracted_object). This is the object that acts as the starting point for the cloning contract. o "The scope of the cloning request (i.e., the object itself, or the object with all its (nested) compositions, or the object with all its (nested) compositions and all the objects that are navigable from it up till the specified depth). o "The depth of the cloning contract. This defines how many levels of relationships will be covered by the contract (UNLIMITED_RELATED_OBJECTS when all navigable objects must be cloned recursively). The depth only applies to a RELATED_OBJECT_SCOPE. It offers methods to: o "Change the depth of an existing contract (set_depth). This change will only be taken into account at the next refresh of the CacheAccess. o "Change the scope of an existing contract (set_scope). This change will only be taken into account at the next refresh of the CacheAccess. With: o The top-level object (contracted_object). This is the object that acts as the starting point for the cloning contract. o The scope of the cloning request (i.e., the object itself (SIMPLE_OBJECT_SCOPE), or the object itself along with all its (nested) compositions (CONTAINED_OBJECTS_SCOPE), or the object itself along with all its (nested) compositions and all the objects that are navigable from it up till the specified depth (RELATED_OBJECTS_SCOPE)). o The depth of the cloning contract. This defines how many levels of relationships will be covered by the contract (UNLIMITED_RELATED_OBJECTS when all navigable objects must be cloned recursively). The depth only applies to a RELATED_OBJECTS_SCOPE. It offers methods to: o Change the depth of an existing contract (set_depth). This change will only be taken into account at the next refresh of the CacheAccess. The depth only applies to a RELATED_OBJECTS_SCOPE. o Change the scope of an existing contract (set_scope). This change will only be taken into account at the next refresh of the CacheAccess.
In section 3.1.6.3.6 regarding the Contract clarify some things… And remove some typos
Problem 1 The description for the name attribute (see issue XXX) needs to be clarified into saying that the name attribute gives the fully qualified name using IDL '::' as seperators (i.e. ObjectHome representing class Foo in module test has as name 'test::Foo'). Solution 1: Replace: o the public name of the application-defined class (name). With: o the public fully qualified name (using IDL seperators '::') of the application-defined class (name). For an ObjectHome representing class Foo in module test it's name becomes 'test::Foo'. Problem 2: The description for the index attribute of the object home needs to specify what the index is in case the home is not yet registered with any Cache. It is our suggestion to make this operation return -1 as value for an ObjectHome which has not yet been registered to any Cache. The description also contains a type, as it talks about index, but it should be registration_index. Solution 2: Replace: o the index under which the ObjectHome has been registered by the Cache (see Cache::register_home operation). With: o the index (registration_index) under which the ObjectHome has been registered by the Cache (see Cache::register_home operation). If the ObjectHome was not yet registered to any Cache then -1 is returned as value. In the IDL description in section 3.2.1.2 on page 3-53 the attribute type of the registration_index needs to be replaced from unsigned_long to long to allow -1 as return value. Replace: readonly attribute unsigned long registration_index; With: readonly attribute long registration_index; In the IDL description in section 3.2.1.2 on page 3-58 regarding the Cache interface description change the return value of the register_home operation from unsigned_long into long: Replace: unsigned long register_home ( in ObjectHome a_home) raises ( PreconditionNotMet); With: long register_home ( in ObjectHome a_home) raises (PreconditionNotMet); Problem 3: The description for the selections and listeners attributes should be in plural, furthermore the attribute names in the description should be bold . Solution 3: Replace: o the list of attached Selection (selections). o the list of attached ObjectListener (listeners). With: o the list of attached Selection objects (selections). o the list of attached ObjectListener objects (listeners). Problem 4: The description for the set_content_filter operation states that it can only be set before the home is registered to a Cache. But this is not correct, it should state that it must be set while the cache the home is registered to (if any) has a pubsub state of INITIAL. As long as the readers have not been created it should not be prohibited to set the content filter. Solution 4: Replace: o set the content_filter for that ObjectHome (set_content_filter). As a content filter is intended to be mapped on the underlying infrastructure it can be set only before the ObjectHome is registered (see Cache::register_home). An attempt to change the filter expression afterwards will raise a PreconditionNotMet. Using an invald filter expression will raise an SQLError. With: o set the content_filter for that ObjectHome (set_content_filter). As a content filter is intended to be mapped on the underlying infrastructure it can be set only if the Cache to which the ObjectHome belongs (if any) has not yet been registered for pubsub. (see Cache::register_all_for_pubsub). An attempt to change the filter expression afterwards will raise a PreconditionNotMet. Using an invald filter expression will raise an SQLError. Problem 5: The description of the deref_all