This is in regard to CosTransactions::Control and some of the
constraints it seems to place on implicit propagation implementations.
I'll describe the issue in the context of an example where process A
initiates a transaction and then makes a call to an object on process
B which registers a resource and does some work.
For example:
Process A:
current -> begin();
obj_on_B -> register_txn_resource_and_do_some_work();
...
[OTS-runtime attaches service context containing propagation
context to request]
Process B:
[OTS-runtime associates invocation thread with propagation context]
register_txn_resource_and_do_some_work()
{
ctrl = current -> get_control();
coord = ctrl -> get_coordinator();
coord -> register_resource(....)
....
}
This looks ok on the surface, but for an OTS implementation
get_control() is not without complications:
1. If Process B uses interposition, then it simply `recreates' the
transaction and returns the interposed control. But interposition is
not, and shouldn't be, a required method of implementation.
2. The ots implementation can pass the control it received when
originally creating the transaction around in the
implementation_specific_any of the propagation context.
But then multi-vendor interoperability goes out the window. Although
the mere existence of implementation_specific_any suggests that it
already has.
3. The ots runtime in Process B can create an in-process,
non-interposed, control to front for the coord/terminator and return
that. Although there is some appeal to this approach, it has some
drawbacks. In addition to now requiring process B to become a server,
there are lifecycle and scope concerns for this locally manufactured
`control'.
4. Completely proprietary method of obtaining a control.
None of these are attractive alternatives considering the propagation
context delivered to process B already has the desired coordinator and
terminator references. Unfortunately these can only be accessed
through an `artificial' control object.
I would suggest that Control might have been better off defined as a
struct:
struct transaction_control
{
Terminator term;
Coordinator coord;
}
;
If Current had an operation such as:
transaction_control get_txn_control_struct();
[actual signature may vary.....]
There would be no scope, or lifecycle issues with `control' and no
forced use of implementation_specific_any or interposition. (I also
realize there may be some resistance to introducing this type of
change in an rtf, so its only one of the possible solutions listed
below.)
In summary, I'm asking the rtf to consider:
1. Whether the Current methods that use control are unecessarily
forcing implementations to interpose, use implementation_specific_any,
create local, non-interposed controls or other proprietary solutions.
Some possible solutions:
A. Provide:
Current::getCoordinator(),
Current::getTerminator()
so that at least in many cases the ots runtime doesn't always
have to obtain a control object to provide what it already
knows. There are no versioning issues with Current since it is
locality constrained.
(When and if Current::get_control() is called, the ots can
obtain the control reference at that point. It may still have
to use interposition to do this, but it can now be avoided some
of the time.)
B. Provide a struct representation of Control, and corresponding
operations on Current.
The operations that would need `struct' equivalent are:
get_control()
suspend()
resume()
C. Pass the control explicitly in the propagation_context. (This would then
possibly make a remote call to get coordinator and terminator
references that are already known locally.)
Solution A is a workable solution for an rtf, Solution B addresses the
issue more completely, and C well, I wouldn't vote for it.
Comments, Opinions? Is Control as an object providing real value or is
it just a struct in disguise complicating implementations?