Archived

This forum has been archived. Please start a new discussion on GitHub.

Inheritance/Objekt Identity/Locator

I am confused about how to properly assign object identities for derived classes in Ice. Consider this slice - definition:

interface CDocumentVersion {
...
};

interface CInvoiceDocumentVersion extends CDocumentVersion {
...
};

sequence<CDocumentVersion*> CDocumentVersionSequence;

interface CDocument {
// the returned sequence can contain plain CDocumentVersion
// proxies as well CInvoiceDocumentVersion proxies
CDocumentVersionSequence selectDocumentVersions();
};

The idea here is a general framework providing documents and document versions and an extension for the special case of invoices. This extension should be possible without changing the code or interfaces for the general framework.

CDocument::selectDocumentVersions() creates the object identites for the selected and returned document versions. However, CDocument is not aware if a document version is actually just a CDOcumentVersion or indeed a CInvoiceDocumentVersion. Therefore it will just create object identities of category "CDocumentVersion". Hence if a use locators, the CDocumentVersion - Locator will be used, resulting in the incarnation of a CDOcumentVersion servant for something that is actually a CInvoiceDocumentVersion and has to use the specialised code of the derived class!

Also I wonder: what if another interface returns a CInvoiceDocumentVersion and does know about the specialised character of the object, so that it creates an object identity of category "CInvoiceDocumentVersion". The result is that 2 different object identities (once with category "CDocumentVersion", once with category "CInvoiceDocumentVersion", but both with the same name) identify the same object. This would mean that comparing the object identies is no longer identical with comparing the actual objects!

I'm not sure if this is a conceptual problem of the way how Ice implements object identies or an imminent problem / misunderstanding of mine concerning inheritance. But since I couldn't find hints in the Ice documentation how to properly handle inheritance for interfaces on implementation level I would be most grateful for some help.

Comments

  • marc
    marc Florida
    I'm afraid I don't fully understand what you are trying to do. Identities on the one hand, and object type on the other, are completely independent concepts. Categories are used to look up servant locators, if you choose to use servant locators instead of the active servant map. (Categories also have a few other uses for services such as Glacier.)

    What is it exactly you want to do? Why do you want to use servant locators? Typically you use servant locators if you have for example a back-end database that contains the state of the Ice objects you want to locate. In such case, the information for the type of the Ice object is found in the database. For the name part of the object identity, you then usually use a database record identifier, which allows you to look up the record for the Ice object in the database. With this information, you can instantiate the correct servant in the servant locator, and populate this servant with data from the database record. The identity's category could then be anything you choose, like simply "document".
  • Hi Marc!

    Well, you've hit the nail - we have a back end database with millions of entries, so locators seem to be de rigeur, as well as default servants or evictors. And yep, we have the type info in the database. But the locator should not need to access the database (with default servants this would mean 2 database lookups for the same info, once in the locator and once in the stateless object itself), rather just use the object identity to invoke the right object which does the database lookup on it's own. Hence we must code the type info into the object identity, so that the identity tells which type of object to incarnate.

    Alternatively of course the locator can do a lookup in the database with the given object name to

    find out the object type. But is it really desirable that a locator does a database lookup,

    which might cause some performance penalty and worse, shifts the implementation dependencies to

    the locator? I mean, if I derive a class A from class B, I don't wont to change the code of the

    superclass B. But I would have to change the code of the locator for B.

    So the core of my problem is: how can I design a system with Ice where I can extend it by new

    object types or new behaviour without having to change the existing code?
  • marc
    marc Florida
    There are many solutions to this problem. For example, you could use a servant locator that has a servant factory registry. For each new type, you register a new servant factory. This way, your servant locator doesn't have to change when you add new types. Instead, the servant locator would look up the database record, find out the type, and then use the correct factory for the type.

    You can avoid additional lookups by populating the servant with all the relevant data right away, i.e., you read type and data from the database in one single transaction. Then you create the correct servant using the factory, and populate the new servant with the relevant data for the given operation.

    If you populate the servant with all relevant data (instead of just the relevant data for the operation), then you can also employ an evictor queue, so that servants are not loaded from the database for every request. Instead, servants are loaded once only, and then put into an evictor queue. Subsequent calls consult this queue first. Only if the queue exceeds a certain size, you start to remove servants on a least recently used basis. This is the strategy that Freeze uses.

    In any case, the point is that there are many possible solutions, and in order to pick the best, I would need to know your application in detail.