Simon Laws wrote:
On Tue, Apr 22, 2008 at 10:42 PM, Jean-Sebastien Delfino <
[EMAIL PROTECTED]> wrote:

Simon Laws wrote:

On Mon, Apr 21, 2008 at 4:49 PM, Simon Laws <[EMAIL PROTECTED]>
wrote:


On Tue, Apr 15, 2008 at 6:10 PM, Yang Lei <[EMAIL PROTECTED]> wrote:

 I agree with Simon's emphases on the point of view. I understand
Tuscany may prefer one solution over the other. However from
extensibility perspective, there need some extension points to
enable
Tuscany adapters to overwrite the default behavior. I think the
thread
discussion on reference target and the comparing of 1 and 2 showcase
one of the extensibility area :  how to resolve reference target for
different bindings.

I am actually looking beyond just reference target, I see the
extensibility in the following areas:

1. When/How to enable a binding to resolve the target endpoint .
This
include the case to support reference target, and beyond, such as
supporting wireByImpl or autoWire. This also include distributed
support in case adapters have different ways to support distributed
contributions for a given virtual domain.

I understand Tuscany has workspace discussions. It may potentially
be
a solution.I am still waiting to see how workspace is intending to
support distributed scenarios or how it can enable late binding on
resolving target endpoint. Regardless workspace is the solution or
not, we need the flexibility and extensibility to overwrite
Tuscany's
default behavior on binding end point resolving.

2. When/How the binding resolvable is in used,

Some part of the Tuscany code is using binding resolved or not to
have
different process  (see point 3). I think if certain logic outside
binding needs to understand if a binding is resolvable, we should
make
it clear which method achieve it so binding implementations know
what
to expect.

I can see Tuscany code uses binding's URI and targetComponentService
today, I think it should be limited to one method only, I am not
sure
overloading URI is  good .

3. When/How to make binding selections on the reference side.

I can see Tuscany is trying to remove the unresolvable bindings
first
from the reference side , then use some algorithm to either pick the
default binding if it exists or pick the first on the list.

I think we need some plug in point in Tuscany to enable different
algorithm from the above default behavior. And the plugin point need
to enable late binding so during reference's execution time we can
determine a binding is resolvable or not and then use some own
prioritizing rules to select the right bindings.


I would like to see these discussions concluded with a set of API
and
some form of API interaction diagrams in the end.

Thanks.

Yang



I can see a couple of scenarios:



I thinkand binding selection that we need to enable some extension
points for others using other algorism or other


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


 I've been thinking about this issue for a few days on and off and
it seems
to me that the key to this is in the way that we store bindings that
have
been read in from a composite file.

The assembly model starts out with each reference holding all the
bindings
it is configured with in the composite file.

During model build the set of bindings is matched with targets and the
resulting list represents the set of resolved bindings complete with
URIs
identifying target services. These bindings represent the runtime
configuration and are used to generate wires.

To do late binding we have to maintain the original set of bindings as
well as any bindings that have been fully resolved. In this way the
reference can resolve targets at runtime with all the information that
is
used to resolve them at build time.

During the first domain implementation I ran across this problem and
stored the original list of bindings on the dummy target service that
is
created for each target. However this is less than satisfactory as
this list
is not persisted by the processors should the composite be written out
again.

If we reorganize the bindings such that we have a notion of candidate
bindings and resolved bindings then candidate bindings can be used at
a
later point to create resolved bindings.

Much of the builder processing can be done early to associate policy
with
bindings etc. But the wiring processing needs a bit of thinking about.
Anyhow this is not a fully formed thought but I'm throwing this out
there as
I want to spend some time on this over the next few days and welcome
any
input.

Regards

Simon


I've given this some more thought. It's a long post, sorry about that,
but
just diving in and changing code is going to complicate matters on this
one.


Requirements
------------

A - late target service location
B - late binding selection
C - late autowire

A and B could be achieved at the time when a proxy is first called on
the
understanding that an empty proxy can be first generated to represent
these
unresolved wires.This is different from the case where no proxy is
provided
for an unwired reference.

C is more difficult as it involves the injection of one or more new
proxies
depending on what the autowire process discovers. I suggest
we defer this requirement.

Inputs and Outputs
------------------

Currently the list of bindings that remain on a reference after the
assembly
model is "built" is what is used to drive the creation of the runtime.
The
following is a little strange but what I'm trying to show is the general
configuration of a reference, e.g. "Target = set" means that the
reference
has one or more targets and "binding uri = set" means that the reference
has
bindings where the binding URI is set.

Input from .composite file:

Target = null, binding uri = null
Target = null, binding uri = set
Target = set,  binding uri = null
Target = set,  binding uri = set  - this is an error case

Output from build phase

Target = null, binding uri = null - unwired reference, i.e. autowire
hasn't
matched up the reference
Target = null, binding uri = set  - the binding is used to generate a
provider and a wire
Target = set,  binding uri = null - A candidate for late binding (this
is
currently represented by storing bindings on the dummy target service)
Target = set,  binding uri = set  - this is an error case but
interestingly
our workspace will generate these now

Current Binding Lifecycle
-------------------------

Binding lifecycles depending on input. Note. These stages are not
represented explicitly in the binding model.

Wired Reference (Target = set,  binding uri = null)
 Unresolved - not associated with service and a candidate for resolution
against a service binding
    (All candiate/unresolved bindings are removed from the
reference.bindings list after the build phase)
 Resolved - associated with service  - make better use of the resolved
flag
on binding
 Activated - binding provider created
 Started - wire created and provider started

Unwired reference (Target = null, binding uri = set)
 Resolved - assumed resolved due to user input
 Activated - binding provider created
 Started - wire created and provider started

Unwired reference (Target = null, binding uri = null)
 Unresolved - no proxy should be injected unless autowire matches them
 Resolved - autowire has matched the reference
 Activated - binding provider created
 Started - wire created and provider started

Once past the resolved point point the final set of bindings are known
(the
reference.bindings list) and the runtime is constructed from this list.

Suggested Changes
-----------------

Tidy the binding model

A) remove the concept of Optimizable binding
    Bindings will not have access directly to the target service that
they
refer to through this route

B) add a direct reference between a binding and the target service model
that the binding is configured to represent
    We can tell which binding is related to which target
    we can tell which bindings are candidate bindings as they are not
already associated with a target model

C) make clear use of the binding.unresolved flag to indicate true = not
pointing at a service in the domain

Maintain candidate bindings

D) retain the allocation of all bindings to unresolved services
    These bindings should all be fully configured in terms of available
policy
    There is potentially a gap here if we don't feel the full policy set
is
available in the domain when these bindings are configured

OR (not sure which one is best without doing the code but the first is
there
already)

E) retain all candidate bindings on the bindings list but with URI=null
and
marked as unresolved

OR

F) create two lists, candidate and resolved

Propogate unresolved targets to later processing stages

G) Allow wires to be created for unresolved services (this is different
from
unwired references)
    This will allow proxies to be generated in this case
    Proxies must have access to the unresolved binding list through the
dummy target service (or whatever storage is chosen for this)
    Not clear how this will work but will have to allow it to happen
without selecting a binding

Late resolution

H)  When the proxy is called.
   If the wire target is unresolved then call out to a binding resolver,
which could be pluggable, in order to:
      Find target service by look up in some registry, for example
      Find a binding in common with the target service - as in builder
      Configure the binding with the target URI and copy it into the
reference
      Create a provide for the binding - as in activate
      Create a wire for the binding - as in start
      Start the binding provider

   If successful send the message down the wire

   If not successful throw a service not found exception


Any comments gratefully accepted

Simon


So if I understand correctly:

- You want your binding invoker code to resolve a target and pick a
suitable binding at invoke time, as for example that target was not
resolvable at build time.

- The composite builder currently keeps unresolved targets as Service
proxies in the reference.target list, with each proxy holding a list of the
candidate bindings initially specified on the reference

- But unresolved targets are not properly kept in the reference.bindings
list used by the composite activator and the binding providers at runtime,
making difficult to work with these unresolved targets then.

I'd like suggest the following, a simple non-breaking change:

- For each unresolved target, store an instance of SCABinding in the
reference.bindings list with targetComponentService pointing to the target.

- In your SCABinding invoker implementation, access the
targetComponentService, resolve its location using whatever smart resolution
mechanism you want to use, pick the candidate binding that suits it, create
that binding's invoker and dispatch to it.

Or with a twist, if you don't want to do that in SCABinding, create a new
SuperSmartBindingThatResolvesThingsAtInvocationTime to handle that smart
last-second resolution logic

Makes sense? Simple enough?
--
Jean-Sebastien


Hi Sebastien

Thanks for the thought. Sounds good to me. Simpler than my suggestion. The
basis of this is actually what the code used to do in the old domain
implementation :-) So not difficult to move back to that. I like your twist
that binding.sca has make use of the candidate binding list for binding
matching. Nice one. I'll give it a go and report back.

Thanks for the input.

Simon


Simon, your changes under SVN r651490 to represent unresolved targets with bindings worked - almost - perfectly :) I only ran into a minor issue with tutorial/store-merger where the reference to the VegetablesCatalog was overriden by the default SCA binding that was created for that reference (as its target was remote).

Unrelated to your changes but contributing to cause that bug - we were missing a little bit of code to deal with URIs on SCA bindings. I checked in a small fix to BaseWireBuilderImpl in SVN r652631.

All the wiring works now, I'll add some tests to tutorial/domain to make sure it continues to work :)

Thanks!
--
Jean-Sebastien

Reply via email to