Re: Object activation for GNOME.



miguel@nuclecu.unam.mx wrote:
> 
> Hello guys,
> 
>    Since ORBit has been an absolute success, I got all excited about
> the gnome components.  I have been working recently on the spreadsheet
> for the GNOME project, with the idea of making it the testbed for our
> components and our document model.
> 
>    I also have been catching up with Microsoft's way of doing things
> and their Common Object Model.  I do believe they have some very
> useful ideas that we should definetly get our hands on and make them
> part of our component model.

<PEDANT-MODE>
Actually COM stands for 'Component' Object Model. The 'common' bit was
an accident from Microsofts  Mark Ryland, for which he apologises
profusely (See Don Box's Essential COM for details)
</PEDANT-MODE>

> 
>    Here is a list of things I want to implement for the gnome
> components based on
> 
> * Component Activation.
> 
>    Microsoft's COM provides three API entry points for dealing with
>    objects:
> 
>         1. Get a pointer to a class factory (ie, a class whose only
>            purpose is to create instances of an object).
> 
>         2. Create an instance of a given object type (this is
>            basically (1) with an implicit call to create an instance).
> 
>         3. Load an object from a file, invoking any constructors
>            required for this (obviously, layered on top of (1) and (2)
>            and an extra routine or two).
> 
>    The interesting part is how do you get your hands on a class object
> in the first place?  Microsoft solves this with the Registry[1].  This
> just happens to be a database with useful values (For the sake of this
> discussion I am going to use a gnome-config like database format here):
> 
>    Lets imagine we want to get create a PlotObject.  Here is my
> suggested API for component_get_class_object:
> 
> You would write this fragment of code:
> 
>      CORBA_Object plot_class;
>      PlotObject plot;
> 
>      plot_class = component_get_class_object ("PlotObject");
>      plot = plot_class_create_instance (plot_class, &ev);
> 
>      plot_set_values (plot, ...., ev);
> 
> The database of our servers would include this:
> 
> [PlotObject]
> Type=SharedLibrary
> Filename=/opt/gnome/lib/servers/plotobject.so
> 
> [CalendarServer]
> Type=Standalone process
> Filename=/opt/gnome/bin/gnomecal --someoption
> 
>     At this point, our component wrapper routines will load the object
> from the shared library and would call a function in the shared
> library called get_class_object with the object name as a parameter),
> this could be implemented like this (note, this example shows a shared
> library that implements two different objects):
> 
> char *
> get_class_object (char *str)
> {
>         static int server_registered;
> 
>         if (!server_registered){
>                 component_register_server ("PlotObject");
>                 component_register_server ("SomeOtherObject");
>                 server_registered = 1;
>         }
>         if (strcmp (str, "PlotObject") == 0){
>            return (init_and_create_plot_object_class ());
>         }
> 
>         /* This is only needed if a shared file implements
>          * more than an object in the same shared library
>          */
>         if (strmp (str, "SomeOtherObject") == 0)
>            return (init_and_create_some_object_class ());
> }
> 
> 
> In the case we wanted to create an object of a class that is
> implemented as an external process, the component library would launch
> the process and wait for the process to register their servers with
> some sort of daemon that keeps track of the existing servers running
> on behalf of the user, like this:
> 
> main ()
> {
>         component_init ();
>         printf ("Calendar server starting up\n");
>         component_register_server ("CalendarObject");
>         component_register_server ("TodoObject");
>         component_register_server ("AlarmObject");
>         component_main_loop ();
> }
> 
> Now, this is how I would implement it today.  And I am mailing this
> list to get input from all of the people that known the CORBA
> specification up and down to guide me in the right direction.
> 
> Miguel.
> 
> [1] actually, the Registry happens to be a cache of the actual values
> that might reside on a remote server.


Corba and COM use subtly different semantics for 'activating' objects.
As you've observed, COM relies on a 'class' system - i.e. you always
'create' an instance of a class (with the COCreateInstance function).
There is no way of referring to an object with state explicitly in the
model, the only identifier you have is a CLSID (class id), so you must
always create an object. (Actually you can use monikers to refer
indirectly to objects, but thats a hack rather than an integral part of
the model).
If you want to implement a singleton object in COM (i.e. only one can
exist at a time), you must hard-code the class factory to always return
a pointer to the same object 


Corba on the other hand deals only with objects. The identifier you use
(IOR) refers to a specific object with state. If you want to create
objects, you must ask another object to do it for you. 

e.g.

COM:
'Create a 'word' object using this class'

CORBA:
'Desktop, could you create me a word object please?'


In actual fact these two paradigms are very similar in practice, since
COM implicitly uses a Class Factory (as you pointed out) to create the
instance for it. 


Registering implementations
---------------------------

As you pointed out, COM uses the registry explictly to 'register'
classes. This is (IMHO) one of the areas where COM is lacking
(explanation later). The corba approach is as follows:

You register the implementation of the object (i.e. the executable or
shared library) with an 'implementation repository'. The structure of
the implementation repository is not specified so we can implement this
how we like. 

When the client attempts to 'bind' to an object, the orb contacts the
implementation repository, which then starts the implementation (or
links the library to the process) and returns the actual object
reference to it. This is done invisibly - the orb doesn't know (or care)
if it is starting a new object or connecting to an existing one.
Semantically it is always connecting to an existing one.


Getting a reference to an object
--------------------------------

In COM, the registry is used for this purpose as well - the class
factory is looked up using the CLSID.
This is a bit restricted as it means you have to have the implementation
registered in your local registry when you want to obtain a reference to
an object, even if the object resides on another machine - i.e. you
cannot dynamically 'discover' objects at runtime.

Corba uses the naming and trading services for this. The naming service
maps object 'names' to object references, and the trading service maps
object properties to objects (e.g. give me a colour printer on the
second floor which supports postscipt). These services are corba objects
in their own right and are contacted by the orb. They allow you to
browse and choose an object at run-time without having prior knowledge
to it.  This is IMHO one of the powerful advantages of corba over COM


Thinking in CORBA
-----------------

In corba, objects just exist and you get connections to them. In COM
objects dont exist at all. You must create instances of classes.

In practice these two approaches offer the same mechanisms:

In com, when you cocreate an instance, you don't know if a new instance
is being created or not - that is down to the class factory to decide.

In corba, when you connect to an object you don't know whether it is
being created or not - that is down to the object adaptor and the object
implementation to decide. 



I'm not sure I've explained this all that well (I'm babbling a bit
because I'm meant to be working so I'm trying to write this fast). What
I'm basically saying is that all this component activation stuff is
specified in the spec so it's worth looking at that before implementing
a system for gnome.

Cheers,

Phil.

-- 
_______________________________________________________________________
 Phil Dawes                               |   My opinions are my own
 WWW:    err.. temporarily non-existant   |   and nothing to do with
 Email:  philipd@parallax.co.uk           |      my employer.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]