Raymond Feng wrote:
More comments inline.
Thanks,
Raymond
----- Original Message ----- From: "Scott Kurz" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Friday, October 05, 2007 1:57 PM
Subject: Re: Pass-by-value interceptor
Maybe it would help for me to point out that I'd opened 1678,79,80
before
the refactoring for
TUSCANY-1559 was performed.
As I have the time I'll try to understand to what degree if any 1559 may
have addressed the issues I mentioned.
But Raymond, on the surface it seems like you're suggesting going
back to
how it was pre-1559, though with
a per-implementation-type extension instead of just the old
PassByValueInvoker associated with the Java implementation.
Yes.
To me it seemed like one not-too-hard change to address 1678 would
be to
have a flag in the Message SPI
that says, "there's no need to do a copy". This would be off by
default but
a binding impl or databinding transform could switch it on.
We're trying hard to avoid additional fields on the Message unless
it's absolutely necessary.
I'm not sure if it's a good idea to rely on the pass-by-value
interceptor to deal with object marshaling/unmarshaling accross
classloaders. To handle the optimization for co-located components
(different classloader) in the same VM, we probably should add an
"marshaling interceptor" on the client side and "unmarshling
interceptor" on the service side.
On 10/5/07, Raymond Feng <[EMAIL PROTECTED]> wrote:
Hi,
I'm looking into JIRA TUSCANY-1678, TUSCANY-1679, TUCANY-1680. At this
moment, the pass-by-value interceptor is added by the
DataBindingRuntimeWireProcessor. I start to wonder if it's the right
approach. The pass-by-value semantics is somehow
implementation-specific
and
it also requires some metadata from the Implementation (for example,
@AllowsPassByReference in java components). It seems that the
implementation
type extension will have more knowledge to enforce the pass-by-value.
Does it make better sense to have implementation type extension be
responsible to set up the pass-by-value interceptor?
Thanks,
Raymond
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
A few thoughts... If I understand correctly, we're trying to guarantee
that business data flowing through a remote interface is guaranteed to
not be changed.
Looking at a number of scenarios, I'm making the following observations:
- Some bindings can guarantee it because they're just writing the data
to a network connection.
- Other bindings can't guarantee it because they're passing a pointer to
the data in memory to somebody else.
- Some component implementations can guarantee that, for example if I
remember correctly a BPEL process will not modify its input data, a
mediation component if we had one would probably not change its input
data either.
- Other component implementations will pass a pointer to the data in
memory to user code, and can't guarantee that the user code won't change it.
- Some component implementations (e.g. Java) have defined a way for the
application developer to declare that he'll be nice and won't modify the
data (see @AllowsPassByReference).
- In some cases, whatever the binding or component implementation say,
the Tuscany databinding machinery must convert the data from one
representation to another, indirectly protecting the original data
against any changes.
- The same extends to other types of interceptors, for example an
encryption or compression interceptor naturally protects the data
against changes as it passes an encrypted or compressed representation
of the data in place of the original data.
- Finally, all the above conditions must be evaluated on a business
operation basis.
Considering all this, I think bindings, implementations, and all
interceptors in an invocation chain should state if they are going to
protect data against changes or not, and we need that information on an
operation basis. I'd suggest to add a method to oat.sca.invocation.Invoker {
// I'm not sure about the best name for this method.
boolean allowsPassByReference();
or
boolean doesNotChangeInputData();
or
boolean protectsInputData();
}
The wire algorithm will have to call that method on the Invokers in an
invocation chain to decide if it's safe to pass the original data or if
a copy of the data should be passed instead. If an invoker claims to
protect the data then we can pass the original data, if no invoker in
the invocation chain claims to protect the data then we need to copy it.
Now the next question is: Who should perform the copy?
I don't think it's fair to require bindings and implementations to know
how to copy all the different data representations supported in Tuscany
:) I think it's better to have a generic CopyInterceptor to do that,
leveraging the databinding framework.
On the other hand, if a particular implementation recognizes a specific
data representation and wants to make the copy itself, it can still do
it simply by having its Invoker.allowsPassByReference() return true.
Thoughts?
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]