From: oscar@cui.unige.ch (Oscar Nierstrasz)
Newsgroups: comp.object
Subject: Re: OO Concurrency Control
Date: 16 Oct 92 11:20:36 GMT
Article-I.D.: news.1992Oct16.112036.9960
Reply-To: oscar@cui.unige.ch
Organization: University of Geneva

In article 23768@dsg.cs.tcd.ie, cjmchale@dsg.cs.tcd.ie (Ciaran McHale) writes:
>In <1992Oct15.092419.1617@news.unige.ch> oscar@cui.unige.ch
>(Oscar Nierstrasz) writes:
>>what needs to be stated clearly is
>>the client/server contract that the object conforms to.  This may include
>>some liveness and safety properties wrt synchronization.  Beyond that,
>>the implementor should have complete freedom to choose any synchronization
>>strategy that satisfies the contract.  If the "contract" is nothing more
>>than a set of operations, that suggests that all requests will eventually be
>>serviced.  In the case of a "container" object, the contract should state
>>that the number of gets must be no more than the number of puts.
	...
>
>Interesting. I had not considered it in that light. The above suggests
>two categories of synchronisation contracts:
>
>	/1/ A set of operations, upon which all requests will eventually
>	    be serviced.
>	/2/ A "container" object which has restrictions on the ordering
>	    of requests.
>
>Oscar, were you offering these contract types purely as hypothetical
>examples, or do you see these as actual classifications?

Hm -- that's not exactly what I wanted to get at.  What I meant is that
the client should be aware of any synchronization constraints that may have
an impact upon servicing of requests (or, more specifically, when certain
requests may be indefinitely delayed).  Beyond that, the synchronization
*policy* adopted within the service provider should *not* be visible to
the client.  Any policy that satisfies the contract is ok.  In particular,
*scheduling* policies should be transparent to clients, particularly if
they guarantee that all requests will be eventually serviced.

The two "categories" are just examples.  In the unconstrained case, all
requests eventually get serviced.  In the constrained case (e.g., a container)
certain requests will be delayed (possibly indefinitely) until the object
is in an appropriate state (depending on other requests received).  These
constraints should be explicitly stated as a form of "contract", and should be
distinct from the actual sychronization/scheduling policy adopted in the
implementation of the service provider.

	<examples of various readers/writers policies deleted>

>This definition contains some redundancy but I don't think that is
>relevant. What _is_ relevant is that I've defined the Alternation
>policy as a sub-policy of Mutual_Exclusion. Let's draw the inheritance
>hierarchy:
>
>                            Readers_Writer
>                                /   \
>                               /     \
>                              /       \
>                             /         \
>                Mutual_Exclusion   Readers_Priority
>                      |
>                      |
>                      |
>                 Alternation

What this is, is an implementation hierarchy, and has nothing to do with the
client/server contract.  From the client's point of view, in all cases read
and write requests eventually get serviced.  So the "contract" is the same
for all of these.  [Actually, there are perhaps some subtle differences in
when certain requests can get starved out in the various policies, so perhaps
the contracts are not completely identical, but by and large, clients need
not be aware of which policy is adopted by the resource, so this should
*not* be visible.]

Svend Frolund has made the case (ECOOP 92) that synchronization policies
should only be strengthened in subclasses.  As he points out in his paper,
this may mean that subclass instances will not be substitutable where superclass
instances are expected.  My feeling is that the problem arises because the notion
of the contract is missing.  For subtypes, contracts should only be refined
in such a way that the original contract is still valid.  The way in which
the synchronization policy is refined may have no bearing on the refinement
of the contract.  (The inherited policy may have been too strong, so a subclass
may wish to *weaken* it in a way that still satisfies the contract.) 

The question then becomes, What is an appropriate formalism for expressing
the constraints?  (Temporal logic and path expressions are two obvious candidates.)
Obviously the notation used for expressing constraints and that used for
expressing the implementation of synchronization and scheduling policies
should be compatible, so that one may easily verify that the policies satisfy
the constraints.

Obviously some good examples would help to clarify things ...

Oscar

PS: I will be off the net for a week, but I am interested in pursing this idea.
I would like to hear if anyone has thought about this kind of approach ...


----------------------------------------------------------------------------
	Dr. O.M. Nierstrasz, Centre Universitaire d'Informatique
University of Geneva, 24, rue General-Dufour, CH-1211 Geneva 4, Switzerland
Tel: +41 22 705.7664 Fax: 320.2927 Home: 733.9568 E-mail: oscar@cui.unige.ch
----------------------------------------------------------------------------
Newsgroups: comp.object