Issue 3070: The use of italics is wrong in some grammar rules
Issue 3162: C++ mapping for PSDL storage object references
Issue 3163: PSS-FTF issue: Need additional C++ helpers
Issue 3164: PSS FTF issue: ConnectorRegistry made redundant by
Issue 3186: PSS FTF issue: PSS & Thread-Safety
Issue 3188: PSS FTF issue: Restrictions on PSDL concrete types
Issue 3192: PSS FTF: Read-only operations on storage objects
Issue 3226: PSS: factory_dcl syntax
Issue 3227: PSS: Mapping for catalogs and abstract storage homes
Issue 3228: PSS: provides_dcl production misnamed
Issue 3251: Mistakes in CosPersisentState.psdl presented in chapter 11.
Issue 3252: usage of user defined catalogs unclear.
Issue 3644: no parameter order for operations _create(...) defined
Issue 3978: Some others ways to get an abstract storage type reference
Issue 4039: New PSS Issue: Interface Inheritance
Issue 4040: New PSS Issue: Is the PSDL Grammar Too Complicated?
Issue 4041: New PSS Issues: Full Scopes for Storage Objects
Issue 4042: New PSS Issue: Private state members
Issue 4074: PSS storage model and associated object interactions unclear
Issue 4644: PSS-FTF: PSDL grammar problems
Issue 4984: cross-referencing PSS and CosCollections
Issue 3070: The use of italics is wrong in some grammar rules (pss-ftf)
Click here for this issue's archive.
Source: Humboldt-Universitaet (Mr. Harald Boehme, nobody)
Nature: Enhancement
Severity:
Summary:
The use of italics is wrong in some grammar rules. In most cases only the "|" has to be non-itallic. In rule 10 local_op_dcl is also italic, but this nonterminal is not from IDL it is part of PSDL. The spec dosenīt say to wich version of OMG IDL refers.
The editor will fix the style problems. PSDL refers to OMG IDL v2.4 (since the only thing it really needs is "local interface" which is in 2.4).
There is a number of problems with the C++ mapping for storage object references: * abstract storage type references are mapped to abstract C++ classes; this implies that references are dynamically allocated and freed, and typically handled through pointers. The dynamic allocation is expensive and error prone (risk of memory leaks), and handling 'smart pointers' through pointers to these smart pointers is very unusual. * The mapped C++ classes inherit from each other, to mimic the implicit widening of regular pointers. Using inheritance for this purpose is a mistake, since it does not correspond to the behavior of real pointers -- if class B derives from class A, a B instance is a A, but a B* is not a A*, it is only implictly converted into an A*. The correct way to provide this implicit widening is through conversion operators. I propose to change the mapping and adopt concrete 'smart-pointer' ref classes, that applications allocate on the stack. The proposed mapping is implemented in Orbix2000 beta 2 (available from IONA web site).
Interfaces and other IDL constructs have lots of helpers that storage type don't have. In particular it would be useful to add - _out classes - _duplicate static functions - _downcast static functions - a CosPersistentState::release() static function that releases a ref-count on the given storage object instance (if not null), or releases the given CosPersistentState::StorageObjectRef.
The Joint Revised Portable Interceptor submission (document orbos/99-12-02) defines a new operation on the ORB interface, register_initial_reference. With this operation, there is no need for a separate ConnectorRegistry (local) object obtained from ORB::resolve_initial_references. In practice, I expect that calls to register_initial_reference will occur behind the scene -- not in the middle of application code. For example with our new ORB (Orbix 2000), it is possible to use configuration to control the behavior of resolve_initial_references, in particular have resolve_initial_references dynamically load and initialize a plug-in. The plug-in per-ORB initialization calls register_initial_reference on the given ORB instance.
The Persistent State Service draft specification does not say anything
about thread-safety. For portability, it is necessary to define the
guarantees provided by a thread-safe PSS implementation.
Proposal
--------
A catalog (session or session pool) can be either thread-safe or
thread-unsafe. A compliant implementation does not need to provide
thread-safe catalogs.
All objects provided directly or indirectly by a thread-unsafe
catalog are thread-unsafe -- the application must serialize access
to any of these objects, typically by using a single thread.
(1) A storage object incarnation provided by a thread-safe catalog
is like a struct: concurrent reads are safe and do not require any
locking by the application; concurrent writes (or a concurrent
read and a concurrent write) are not thread-safe -- the application
must ensure mutual exclusion to avoid problems.
Flushing a storage object is like reading this object. 'Refreshing'
a storage object is like updating it.
(2) Further, the following Session operations are not thread safe:
they are not supposed to be called concurrently, and no thread
should be using the target session (or anything in the target
session, such as an incarnation or a storage home) when they are
called:
Session::free_all
Session::refresh
Session::close
TransactionalSession::start
TransactionalSession::suspend
TransactionalSession::end
OTS operations are however safe; for example one thread can call
tx_current->rollback() while another thread calls start, suspend or
end on a session involved in this transaction, or while a thread
is using storage objects managed by that session.
A number of restrictions on concrete PSDL types have the effect to force PSS users to use abstract types. For example keys can only be defined on abstract storage homes, so in order to define a key (and the implied finder operations), a PSS user needs to define an abstract storage type and an abstract storage home. Accessing storage objects and storage homes through abstract storage types and homes provides flexibility (with some PSS implementations this allows you to switch from one PSS implementation to another one without recompiling or relinking the code that uses the storage objects) but is also more complex since it doubles the number of PSDL constructs you need. For applications that don't need this flexibility, abstract types are overkill -- and make PSDL look quite complex to understand and use. I propose to review the restrictions on concrete types to make them usable without abstract types.
With some object oriented programming languages (C++, Ada95), it is possible to specify a method as read-only or read-write. For example in C++, a 'const' member function has read-only access to the data members of the target object. So far in IDL and PSDL, there is no way to mark an operation as read-only -- this makes sense for interfaces, since a CORBA object exposes only operations, not state. For stateful objects, such as PSDL storage objects and IDL values, being able to specify an operation as read-only would be very useful. For example in C++ a 'in storage object' parameter could be mapped to a pointer to a const C++ object, which is exactly the semantics of 'in'. More generally, writing const-correct program in C++ (Ada etc.) with PSS would become possible.
The draft PSS specification, in section 1.3.2, uses the production
<factory_dcl>. This production is not defined in the grammar
summary. Instead, it is later given as
<factory_dcl> ::= "factory" <identifier> <factory_parameters>
<factory_parameters> ::=
"(" <simple_declarator> [{ "," <simple_declarator> }*] ")"
|"(" ")"
This definition contradicts with the production <factory_dcl> from the
CORBA components draft (ptc/99-10-04), where it is defined as
*lt;factory_dcl> ::=
"factory" <identifier> "(" [ <init_param_decls> ] ")" [
<raises_expr> ]
Here, the init_param_decls where introduced together with OBV
(formal/98-12-01), where each parameter has an "in" direction and a
type, and a name.
There is also potential confusion with the init_dcl, which represents
factories for value types.
At a minimum, one of the production names should be changed, and it
should be made clear which syntax is used for the "factory" keyword in
what context. It would be even better if the syntax for factories is
always the same.In section 1.4.2 of the PSS draft, catalogs and abstract storage homes are mapped to local interfaces. However, it is not clear how the <catalog_body> and the <abstract_storagehome_body> is converted into the body of the local interface. In particular, the mapping for key and factory_dcl is not specified. Apparently, the intent is that the mapping follows the rules presented in section "Keys" and "Factory Operations" are applied - even though those sections talk about mapping to implementation languages, not to a local interface. Also, if this mapping in these sections is applied, the resulting operations consume and produce "ref<S>" values, which are not legal for operations in local interfaces (according to the Core specification of local interfaces).
· Catalogs were removed by the resolution to issue #3252 · Define the mapping of abstract storage homes directly in each language mapping, without equivalent local interfaces.
In the PSS draft, a production provides_dcl is used. The same
production name is also used in the draft Core spec (ptc/99-10-03),
where it means
<provides_dcl> ::= "provides" <interface_type> <identifier>
In the PSS draft, however, it is
<provides_dcl> ::= "provides" <abstract_storagehome_name>
<simple_declarator>;
Because of this conflict, one of the productions must be renamed.
concerning mistakes in CosPersisentState.psdl presented in chapter 11. First, the keyword "factory" defined in chapter 7.2.2 is used as parameter name in the signature of the operations "register_XXX_factory()". Second, the declaration of ConnectorRegistry is not contained in the summary in chapter 11.
To my mind the usage and mapping of user defined catalogs is weakly specified. It is not clearly described what is generated and what has to be implemented by user. Furthermore it is unclear, how to get access to an catalog. Subsequently I consider C++ only. I guess, a new implementation class has to be defined for each catalog, inheriting from the mapped class of that catalog and from Session. This is necessary to use the operation create_basic_session() returning a Session. Further I guess, the parameter catalog_type_name of this operation denotes a catalog supported by a prior registered user implemented session factory. Furthermore chapter 6.2 does not sufficiently explain the parameter storage_home_id of operation find_storage_home() from CatalogBase. In particular the sentence "In the case of type-specific catalogs (declared in PSDL), the provide declarations define valid storage_home_id parameters." allows multiple interpretations. What is meant?
A storagehome is mapped to a C++ class providing _create() member functions. In the specification is said, that there have to be parameters for all state members of the storagehomes storagetype, but the order is not defined. As a solution the parameter list could begin with the base type of the storage type, proceed with the leftmost implemented abstract storage type and end with the state members defined in the storage type itself. In every case the declaration order should be followed.
At this time, the PSDL mapping does not provide a way to create an object and to directly get its reference. It means that if you want to have an abstract storage type reference, you only have to solution : - to use the _create operation from the storage home ( not very flexible ) - to find an storage type thanks to a find_ref_by_xxx from the abstract storage home I think that the "factory" mapping should be changed : Currently : ( PSS spec, p 56 ) factory create( accno ); // it's like // Account create( in string accno ) After changes : factory create( accno ); <pre> // it's like // Account create( in string accno ); // ref<Account> create_ref( in string accno ); </pre> Moreover, the catalog currently provides : StorageObject find_by_pid( byte [] pid ); It should be very useful to provide another method : StorageObjectRef find_ref_by_pid( byte [] pid );
In the PSS specification (orbos/99-07-07), no provision is made for [abstract] storagetypes or [abstract] storagehomes to inherit from interface definitions. It appears this is an oversight as the omission does not seem reasonable. I have found cases in which a home would expose the same interface as a storage object, where the home subsequently delegates to a specific object however selected. Interfaces are a perfect mechanism whereby the operational signatures could be standardized, thus eliminating potential errors caused by changing one but not the other. Since storage objects are assumed to exhibit only local interface behavior, it would not matter whether the inheritance was from a local or remote interface definition. This could be accomplished using a supports clause in the inheritance specification similar to that of valuetypes.
Discussion: This is not an omission. A storage object is a simple object managed by a database system. Giving to such objects the ability to be servants would complicate their implementation with no real benefit. During the elaboration of the PSS specification, this was one reason to define a new construct instead of reusing/extending valuetypes.
When examining the PSDL grammar in the Persistent State Service, orbos/99-07-07, I came too the conclusion that it is over-specified. Looking through the IDL grammar, great care is taken to avoid overexpansion of the declarator productions. In particular, semantic rules are employed to restrict the use of scoped names (acting as types) in those situations where a particular use may be invalid. These rules could be applied in the same way to the declarator syntax for state members. Thus, there is no need to restrict the grammar to "abstract storagetype" types for declarators; any scoped name should work as elsewhere. Certainly, however, there should be semantic rules that only abstract storagetype types may be used in an abstract storagetype definition.
This looks like a misreading of the specification: state members are not restricted to be abstract storagetype reference -- they can be pretty much any IDL type. See 3.2.5.2 "Abstract Storagetype State Members".
In the PSDL grammar of the Persistent State Service, orbos/99-07-07, it specifically states that storage definitions are not full scopes. That is, they cannot contain type or constant definitions. What is the rationalebehind this limitation? Storage types and homes are almost the same as valuetypes. It seems perfectly reasonable to have embedded types local (encapsulated) to the storage scope that are for internal representations only.
Storage object and homes were designed to be really simple -- in between valuetypes and structs. Like structs, they don't define scopes.
In the PSDL grammar of the Persistent State Service, orbos/99-07-07, state members are merely declared. This makes all such members inherently public. What is the rationale behind public-only state members? Since storage objects are almost the same as valuetypes, it seems an obvious extension that any object, persistent or not, might have members that should not be exposed to external objects or even derived types. Could this syntax be changed to more closely resemble valuetypes? (See also issue 3226 on factory declarators and the (currently unnumbered) issues on scoping and grammar complexity.)
Concrete storagetypes are already an implementation detail. To avoid exposing such implementation detail -- in particular avoid the exposition of "private" data members, just use an abstract storagetype. Abstract storagetypes are unlike abstract valuetypes: they can contain (abstract) state definitions.
See the Persistent State Service specification, orbos/99-07-07, section 5.2.2 (or thereabouts) and section 7. I am confused by the storage model "overview" given in section 5.2.2 and the more comprehensive treatment in the discussion of the PSDL grammar in section 7. The treatment of abstract storage types, homes, and their (concrete) implementations is inadequately mapped between the two, leading to very unclear semantics. My specific concerns: * It is explicitly stated in the text that types, homes, and their independent derivation lines are taken from a Java model. Why this explicit dependence on Java? Could the submitters not come up with a more generic model? Has anyone tried to map these concepts to Smalltalk, which doesn't have the same kinds of object representation and implementation difficulties as Java and C++? Even though I am a Smalltalk expert, my attempts at such a mapping on the proposed model have been less than exciting. * Although the keyword "abstract" was already defined, why are abstract storagetypes and storagehomes "abstract"? They certainly seem concrete enough to me, since I would expect that the definition is sufficient to generate code equivalent to a valuetype. This ambiguates both the general IDL concept of abstraction and concrete storagetypes in particular: in all other places abstract types represent non-instantiable objects that have no explicit state, and it is not at all clear how concrete storagetypes are more "concrete" than their abstract relatives. * The text indicates that each storagetype must have its own home. Is that abstract types, concrete types, or both? Why? Whatever happened to polymorphism? If I have multiple storagetypes with similar or compatible keying properties, why cannot they all be indexed or managed together? I should only require a different home if the behavior is different. Even if a language mapping [read that as "implementation"] should require such, please don't make that a general limitation of the entire model. This is a very useful service; let's not restrict its utility or expressive power by playing to language limitations. * I can understand that you want to keep factory, finder, and management behavior separate from storage object behavior, but has anyone actually articulated the reasons behind this? (This also affects the component model.) What are they? I can see several reasons for keeping the factory and finder operations with the storagetype, in the same way valuetypes specify factory operations. I am also concerned about the apparently artificial complexity introduced by requiring parallel derivations of storagetypes and storagehomes. Why not generate the homes automatically when needed? * Why are keys placed on the storagehome? It would seem more logical that you define the keys (as properties) of the storagetype and then optionally map those to indices in a datastore, catalog, or storagehome. Perhaps we should indicate that, for a particular storagetype, certain state members may participate in a key. Why isn't at least one key identified as a primary key? Why cannot I explicitly define some keys as unique leaving others as non-unique to form inverted indices? * The text indicates that a concrete storagetype "implements" one or more abstract storagetypes. What does this mean? How is this accomplished? What are the navigation paradigms, especially for multiple storagetypes? What interfaces are expected? This whole concept is too weakly specified, and the example in section 10 is too simple to explain multiple type implementation. * What is the purpose of a catalog and its limitation of singleton instances of storagehomes? I can think of reasons why I would want multiple instances of a particular storagehome, especially for configuration management in the datastores. Can one have multiple catalogs, and if so, how do you select one of them, since "by name" might not be the best keying property?
No issue here, just a serie of questions, which should have been sent directly to the PSS FTF list.
In ptc/01-06-02: Production 10, rhs refers to a 'storagetype_local_op_dcl' which is defined in production 24 as a 'storage_type_local_op_dcl. Pick one or the other and change references as required... Production 4 and Production 23 abstract_storagehome_name are defined twice still. Remove one and reindex all proceeding productions. Add the 'state' keyword to the keywords table it seems to have gone missing between edits :) Perhaps a mention that the 'factory' and 'const' keywords are in common to PSDL and IDL and that the 'provides' keyword is in common to PSDL and CIDL. It might also be worth mentioning that the sharing is syntax only as some people may confuse the keyword with the semantics they most commonly use it in IDL / CIDL as opposed to the semantics it is employed within PSDL...
Resolution: Incorporate suggested fixes. Remove provides keyword (a leftover from the adopted resolution to issue #3252).
Can you add issue cross-referencing PSS and CosCollections. Under PSS the work "key" is a reserved work. The CosCollections IDL interface uses "key" as an operation name under the Operations interface. This needs to be changed to something else. I propose changing the operation name from "key" to "user_key", reflecting the operation semantics.