Issue 4250: Proposal to support interposition (Active Service spec orbos/2000-06-19)
Issue 4252: Is support for registering an Action with multiple SignalSets needed?
Issue 4253: get_completion_signal_set should never return nil
Issue 4254: Activity service Issue: Behaviour of get_coordinator()
Issue 4256: The need for a default system SignalSet for failure scenarios.
Issue 4257: PropertyGroup propagation strategy on intermediate servers with no Property
Issue 4258: Predefined SignalSets require predefined Outcomes
Issue 4278: Activity service issue: Add CompletionStatus to complete_activity
Issue 4301: failure assumption
Issue 4302: destroy failures
Issue 4303: child lifetime
Issue 4304: interposition
Issue 4305: unknown context issue
Issue 4312: SignalSet::get_outcome behaviour
Issue 4318: Remote SignalSets
Issue 4345: ActivityPolicyValues and how they relate to Activity service object
Issue 4346: Order of processing during Activity completion.
Issue 4347: The childComplete signal needs to carry final Outcome of completed child
Issue 4348: Interoperability of childLifetime
Issue 4397: Another interoperability clarification
Issue 4410: Current restrictions
Issue 4411: SignalSet and participants
Issue 4416: Additional predefined PropertyGroupAttributes
Issue 4556: Clarification of set_response behaviour
Issue 4588: IDL problem with the current CosActivity module:
Issue 4590: CosActivity IDL errata
Issue 4711: ChildBegin on a subordinate node
Issue 4712: exception processing during completion in subordinates
Issue 5326: context propagation
Issue 5431: asynchronous responses
Issue 5432: asynchronous responses
Issue 5451: Actions and removal
Issue 5452: Failure recovery in Additional Structuring Mechanisms for OTS
Issue 5934: Forcing child activities of completed parents to fail is too restrictive
Issue 8954: formal/05-01-01 - Additional Structuring for OTS - incorrect figures
Issue 4250: Proposal to support interposition (Active Service spec orbos/2000-06-19) (ots-structs-ftf)
Click here for this issue's archive.
Source: International Business Machines (Dr. Ian Robinson, ian_robinson(at)uk.ibm.com)
Nature: Uncategorized Issue
Severity:
Summary:
The problem is that, in domain 2 where there is no SignalSet, how are the Outcomes from Action1 and Action2 supposed to be combined and sent back as a single Outcome to the superior ActivityCoordinator? Further, even if the appropriate SignalSet did exist in domain 2, how could the subordinate ActivityCoordinator get it involved in the request from the superior - the interposed ActivityCoordinator is merely acting as a global Action registered with its superior. I propose the following in order to support interposition: 1. Any signal received by a subordinate ActivityCoordinator be delegated to a SignalSet (assumed to be local since we're using interposition). If the SignalSet is not available, then return a standard Outcome (that also needs to be specified) that indicates that the subordinate ActivityCoordinator is not interested in any further signals from this particular broadcast. 2. Extend the CosActivity::SignalSet interface to provide a set_signal(signal) method to enable a subordinate ActivityCoordinator to indicate to the SignalSet that it will be used only to process the specified Signal (and the Outcomes that are subsequently produced by Actions that receive the Signal) and not to actually produce any Signals. Only the root SignalSet should be producing Signals. An alternative would be to split the SignalSet into 2 objects - the function of 1 object being to produce Signals and the other to combine Outcomes. The down-side of this is the additional complexity it introduces in terms of additional flows between the 2 parts of the SignalSet in the root. Another alternative would be to specialize the SignalSet with a SubordinateSignalSet.
P23: "An Action may register interest in more than one SignalSet and an Activity may use more than one SignalSet during its lifetime." P50: "An Action is implicitly associated with a single Activity and should only be with that Activity. An Action may receive many different Signals from different SignalSets." The interface to register an Action with an Activity is add_action, on either the ActivityCoordinator or Current interfaces. It is defined: void add_action(in Action act, in string signal_set_name, in long priority) raises(SignalSetUnknown); If an Action is to be registered with an interest in more than one SignalSet, then it must be passed as a parameter on multiple add_action calls. Given that the specification implies that calling ActivityCoordinator.add_action(TheAction, "someSS", priority) multiple times is OK, the behaviour needs to be defined for the case where TheAction is added multiple times to the same SignalSet. In particular, what if the priority is different on multiple add_action calls? At the very least I believe a new exception - ActionAlreadyRegistered? - needs to be thrown in the case where an Action is registered multiple times with the same SignalSet. I question the need to support registering an Action with multiple SignalSets at all. I propose that this be illegal as I believe there is no need for it. The new exception is still required.
Resolution: Clarify the text to show that an Action can be associated with more than one SignalSet. In addition, change IDL for remove_action that threw an inappropriate exception.
The following section is taken from the Activity srevice specification orbos/2000-06-19. P63: "string get_completion_signal_set(): Returns the SignalSet currently associated with the target Activity that will be used when it completes. This will be the last valid SignalSet given to set_completion_signal_set, or nil if one has not been provided." Returning nil for a string if there is no completion_signal_set is inconsistent with other methods in both the Activity and transactions services which typically return empty strings in similar situations. For example Current::get_activity_name(). I propose the description for get_completion_signal_set() be changed to: Returns the SignalSet currently associated with the target Activity that will be used when it completes. This will be the last valid SignalSet given to set_completion_signal_set, or an empty string if one has not been provided.
The following section is taken from the Activity srevice specification orbos/2000-06-19. P51: "It is not strictly necessary for an implementation of the Activity Service to create an ActivityCoordinator prior to distributing a context between execution environments in which it was begun. Each Activity may be managed by at most one ActivityCoordinator." The description of Current::get_coordinator() is as follows: "Returns a reference to the current Activity?s ActivityCoordinator. This may be nil if a coordinator has yet to be created." I believe that the act of trying to obtain the ActivityCoordinator should cause it to be created if it doesn't exist already. For example, it should be reasonable (on a server at least) to code: CosActivity::Current_ptr cur; CosActivity::ActivityCooridinator_ptr coord1, coord2; ... curt->begin(); coord1 = cur->get_coordinator(); cur->begin(); coord2 = cur->get_coordinator(); coord2->is_same_activity(coord1); // This better be false! It shouldn't blow up, either. cur->complete(); cur->complete(); Thus, I believe get_coordinator() should never return nil. As a second part of this issue some execution environments, for example a lightweight client, may wish to restrict access to the Activity service through the Current interface only. Further, some environments may wish to limit restrict access to the Activity service to a subset of the Current function, providing little more than the ability to begin and end an Activity context and explicitly preventing the ability to register Actions from the environment. For example, a client environment may not have the capability to service inbound signals for Actions and so may not want to allow local Action implementations to be registered. Another example is a where recoverability of the Activity is required but a particular client environment cannot provide this quality of service. So, I suggest that at least the Current::get_coordinator() and add_action()/add_actions() methods should provide an exception that can be thrown by an implementation in an environment where use of the ActivityCoordinator or Action interfaces is not intended. In no case would it be desirable for these methods simply to return nil.
Resolution: Modify the text to allow a service implementation to restrict the availability of the coordination in certain execution environments
The need for a default system SignalSet for failure scenarios. Malik originally requested this function so I'm raising it as an issue on his behalf. The following section is taken from the Activity srevice specification orbos/2000-06-19. P47: "If a SignalSet fails to produce Signals (e.g., it is physically remote from the ActivityCoordinator and fails to respond to invocations), then the completion status of the Activity is set to CompletionStatusFailOnly, and the ActivityCoordinator should act accordingly." What does it mean by "should act accordingly", and what should be sent to registered Actions if the (remote) SignalSet cannot be reached to produce Signals? Malik proposes a default SignalSet such as org.omg.SignallingFailure with the signal "Failure", which should be sent to any Actions involved with the unavailable SignalSet. This would require all Actions that cared about such failure scenarios to be able to react to such a Signal. All Actions would at least need to tolerate receiving such a Signal. We could go further and define system Outcomes that Actions could return to the SignallingFailure SignalSet and which could be percolated back up to Current::complete or just define a new exception that could be thrown back up to Current::complete. The important behaviour to provide is the ability for the Actions in the failing Activity to be given the chance to register or drive compensations or whatever recovery is necessary.
Resolution: Although the earlier discussion of this issue suggested that it was never intended for SignalSets to be physically remote from the ActivityCoordinator with which they are registered, the specification should not introduce such a restriction.
PropertyGroup propagation strategy on intermediate servers with no PropertyGroupManger. The following section is taken from the Activity srevice specification orbos/2000-06-19. P58 "A PropertyGroupManager must be registered with each client and server that wishes to use the type of PropertyGroup it represents." Consider a configuration where objectA on serverA creates an Activity and sets PropertyGroup data for PropertyGroup1 and then calls objectB on serverB which calls objectC on serverC. The Activity service is configured on all 3 servers. ObjectB and objectC can both access the PropertyGroup data so long as a PropertyGroupManager for PropertyGroup1 is registered with the Activity services on serverB and serverC. This is necessary because a PropertyGroupManager is required to unmarshal the PropertyGroup context received with the request arriving at each server. What the specification does not define is whether or not all received PropertyGroup contexts at serverB are propagated on downstream to serverC if, for example, the PropertyGroupManager for PropertyGroup1 is not registered with the Activity service on serverB. If the PropertyGroup1 context is never to be used on serverB then it would simplify deployment if it were not necessary to configure a PropertyGroup1 PropertyGroupManager on that server just to ensure that the PropertyGroupIdentity part of the received context PGContext is propagated on downstream. It would also improve performance as the PropertyGroup context would not need to be unmarshalled, so long as the Activity service copied the marshalled PGContext from the inbound request to the outbound downstream request. This issue proposes that, in the case where an intermediate server has the Activity service configured but not a particular PropertyGroupManager, all PropertyGroupIdentities received with an inbound ActivityContext are propagated on downstream in any outbound ActivityContexts.
The following section is taken from the Activity srevice specification orbos/2000-06-19. P48 "The Synchronization SignalSet has a similar role to that of Synchronization objects within the OTS, i.e., it is invoked before and after completion of the Activity. Likewise, the completion status of an Activity may be changed by the Actions registered with this SignalSet, such that the Activity?s outcome when postCompletion is called may be different to that when preCompletion was invoked. If an Action error occurs during preCompletion (e.g., the ActionError exception is thrown) then the Activity completion status will be set to CompletionStatusFailOnly." In order for an Action itself to influence the completion status of an Activity during signal processing, it must cause the SignalSet responsible for the Signal being processed to set the appropriate completion status. This is achieved through the Outcome the Action returns from the process_signal call. In the case of the predefined SignalSets, no predefined Outcomes are specified so there is no opportunity for an Action processing the preCompletion signal to influence the completion status. The object model for the Activity service does not encourage an Action to invoke methods directly on a SignalSet (such as SignalSet::set_completion_status) and Current::set_completion_status may not be called after the completion SignalSet has started producing signals. Therefore predefined Outcomes, that may be generated by Actions, are required for the predefined SignalSets and the behaviour of these predefined SignalSets, in terms of how they react to the predefined Outcomes, needs to be specified. Per the specification, there is no need for the predefined SignalSets themselves to produce an Outcome. I propose the following predefined Outcomes: "org.omg.preCompletionSuccess" and "org.omg.preCompletionFailed" that may be generated by Actions and passed to the Synchronization SignalSet via the ActivityCoordinator calling set_response. On receipt of the org.omg.preCompletionFailed Outcome during preCompletion, the Synchronization SignalSet should set its completion status to CompletionStatusFailOnly.
Resolution: Part of the proposed resolution to Issue 4250 is to define a SubordinateSignalSet interface that is used by a subordinate ActivityCoordinator on a downstream node in a distributed activity. A subordinate node may have many Actions registered with the pre-defined Synchronization SubordinateSignalSet; if one of these Actions encounters a situation during preCompletion where it needs to cause the Activity completion status to be set to CompletionStatusFailOnly in the root, then it needs to get an indication of the failure back to the root Synchronization SignalSet via its interposed ActivityCoordinator-Action. This simplest way to do this is via a pre-defined Outcome.
In a distributed system consisting of:
client---------->server1
a client may perform:
CosActivity::Current_ptr cur;
cur->set_completion_status(CompletionStatusFail);
cur->set_completion_signal_set("CSS");
do some work - all is well
cur->complete_with_status(CompletionStatusSuccess);
The Activity service implementation of Current::complete_with_status needs
to propagate both CompletionSignalSet name and CompletionStatus to the
ActivityCoordinator. The means by which the Current object calls the
ActivityCoordinator is via the latter;s complete_activity method.
The signature for complete_activity allows the SignalSet name to be passed
but not the CompletionStatus.
I think at some point we had a set_completion_status method on the
ActivityCoordinator but it is no longer there.
There is currently no way for this information to be passed to the
ActivityCoordinator.
I believe the complete_activity method should take the CompletionStatus as
an additional parameter.
The current draft of the Activity Service implicitly assumes a "presumed abort" type protocol, but doesn't mention it explicitly. The only reference an Action has to the activity it is involved with is the ActivityCoordinator it registered with. Now, if that coordinator is defunct (e.g., it failed before termination or simply decided to "abort" and couldn't get through to the Action because it had failed) when the Action calls get_status it will presumably get an OBJECT_NOT_EXIST exception. The Action should use this as an indication of a roll back, and act accordingly.
If the destroy call on an Action fails then this should have no affect on the activity. This is simply used as a hint that the activity has completed, but an Action may decide to purge itself early if it wants to (the effect on the activity will obviously depend upon where in its life this occurs).
In order to implement the ChildLifetime SignalSet correctly we actually need two separate SignalSets (ChildLifetimeBegin, ChildLifetimeComplete), one for each of the two Signals. In addition, it is necessary that the activity is still active on the thread when childComplete is generated, in order that the actual activity identity can be encoded in the Signal. So, we need to reverse the order of the Synchronization and ChildLifetime SignalSets.
Resolution: Remove the ChildLifetimeComplete Signal. If an Action wants to determine the conclusion of an activity, it can enlist with the Synchronization SignalSet. The activity must still be active on the thread when the Synchronization SignalSet is used.
There has been a bit of discussion about the problems with implementing efficient interposition using global actions. The notion of global actions came about because it was originally thought that a downstream node would not need to have access to the same SignalSets that an upstream node had. However, although global actions make this possible, they make implementing efficient interposition very difficult. It also turns out that it makes more sense to require downstream nodes to have the same knowledge of the activity SignalSets as upstream. So, what we're proposing is: (i) whenever an Action is registered with a SignalSet at a downstream node (A), that node must register a SubordinateSignalSet (see below) with the parent node (B). This need only be done once per SignalSet. It means that a downstream node is only informed about Signals that mean anything in it's context. Obviously B may be a downstream node to, say, Z, and as a result of having A register with it may then need to register an Action with A. (ii) add a SubordinateSignalSet that derives from SignalSet and add the single method set_signal, which takes a Signal. A SignalSet is a finite-statemachine, and usually starts from point 0. set_signal lets it start (or re-start) from any point in the FSM. Whenever an interposed coordinator receives a Signal it passes it to the interposed signalset for that Signal using set_signal, and then uses the SignalSet as it would normally, i.e., calls get_signal, set_response etc. The interposed SignalSet can then collate the responses and send a single Outcome back. However, it can also do the local optimisations mentioned in an earlier email. So, for example, if a local Action responds with an outcome that can only mean the activity will rollback, rather than send that response back to B, A could do the local rollback on all registered participants first, saving B the time to send the next message.
Currently the text states that an importing domain that does not understand activity_specific_information encoded within the context (typically determined by looking at the type field) should simply null them out (or replace them with its own). I'd like to suggest that we change this so that the importing domain throws an exception, and does no work on behalf of that invocation. This is because typically this data will be dependant upon the specific extended transaction model in use, and an importing domain could corrupt data if it doesn't use the entire context correctly.
If there are no Actions registered with a SignalSet when ActivityCoordinator::process_signal_set() is called, then the ActivityCoordinator will not ask the SignalSet for any Signals. However, the SignalSet still needs to produce an Outcome. The description of the get_outcome method suggests that the SignalSetActive exception could be thrown if get_outcome is called before any Signals have been requested. The description of this method should state that a SignalSet should return a valid Outcome or nil if called before any Signals are produced.
Section 2.2.1 says: > If a SignalSet fails to produce Signals (e.g., it is physically remote from > the > ActivityCoordinator and fails to respond to invocations), then the > completion status of the > Activity is set to CompletionStatusFailOnly, and the ActivityCoordinator > should act > accordingly. We never actually intended SignalSets to be used remotely. I'd like to recommend (on behalf of ourselves and IBM) that we use the local idl keyword to make this explicit.
The current specification defines ActivityPolicyValues that were based on the OTSPolicyValues at a time of flux for the OTS specification. These are currently: const ActivityPolicyValue IGNORES = 0; // This is the default const ActivityPolicyValue SUPPORTS = 1; const ActivityPolicyValue REQUIRES = 2; const ActivityPolicyValue REQUIRES_NONE = 3; Since OTS 1.2 is now finalised, I believe we should follow the pattern established by that specification and replace these policies with the following: const ActivityPolicyValue REQUIRES = 1; const ActivityPolicyValue FORBIDS = 2; const ActivityPolicyValue ADAPTS = 3; I'm not sure which policy should be used as a default in the absence of an explicit ActivityPolicy; I propose ADAPTS since FORBIDS seems a little harsh. The definitions for these policies should follow the equivalent OTSPolicy definitions. I don't believe we need any equivalent of the NonTxTargetPolicyValue (required only for interoperation with OTS 1.1). We need to define the policy that the Activity service objects themselves should use to determine whether or not context is expected to flow on operations on these objects. I believe this should be ADAPTS for all Activity service objects.
In order to write a portable application or application framework that uses the Activity service, and in order for Activity service implementations to fully interoperate, the ordering and semantics of completion processing need to be more explictly defined than is presently the case. I describe below what is intended and implied by the current specification, but which I believe needs to be more explictly stated to avoid implementations applying different interpretations. 1. Current::complete_with_status(cs) is called 2. This drives ActivityCoordinator::complete_activity(completion_ss_name, cs). This may be a remote call and there is a separate issue as to whether context is propagated on this; it depends on the ActivityPolicyValue of the ActivityCoordinator. 3. The preComplete synchronization signal is distributed. Activity context must be available on the thread when the Actions process this signal. 4. The completion signals are distributed to registered Actions. The presence or not of Activity context with these flows is not defined. I don't think the presence of Activity context hurts and is consistent with the behaviour during synchronization preComplete. OTS is a little different because Synchronization is a TO (OTSPolicy=ADAPTS) whereas Resource is not (OTSPolicy=FORBIDS). One advantage of keeping the context available during completion processing is that the PropertyGroups are available. 5. The childComplete processing occurs in any parent Activity. Logically, the parent coordinator process_signal_set method is called and the SignalSet implementation gets the information it needs from the current Activity (which is the completing activity, still active on the thread) to build the ActivityInformation structure. 6. The context is logically suspended. Any PropertyGroups are called with suspended() and then with completed(). 7. The postComplete synchronization signal is sent. 8. Any remaining Activity service objects for the completing Activity are cleaned up. 9. The call returns to the client. In some respects, it would be better if (5) and (6) could be reversed but this cannot be the case if the child activity context needs to be on the thread for the parent to perform the childComplete processing.
The childComplete signal carries an ActivityInformation structure in its application_specific_data field. The ActivityInformation structure contains the GlobalId and final CompletionStatus of the completed activity. This structure also needs to contain the completed Activity's final Outcome in order to be properly useful to application frameworks that need to know about how a child activity completes.
This issue should be closed off as already resolved by Issue 4303, which removed the ChildComplete signal.
When a child Activity completes, its parent's ActivityCoordinator must
drive the childComplete/childLifetime SignalSet to produce the
childComplete signal for distribution to any Actions with an interest in
this signal. This Signal contains an ActivityInformation structure that
indicates the GlobalId and final CompletionStatus of the completing
Activity. (A separate issues proposes that the final Outcome of the child
Activity also be included in the ActivityInformation). The specification
leaves it to an Activity service implementation to determine how a parent
Activity is notified of its child's completion and how the
ActivityInformation is obtained by the parent's childComplete/childLifetime
SignalSet. A practical approach is for the child ActivityCoordinator to
call its parent ActivityCoordinator's
process_signal_set("org.omg.childComplete") method. If the child Activity
is active on the thread when childCompletion processing occurs, then the
SignalSet in the parent can determine the child's GlobalId and
CompletionStatus via the Current interface. (Note: the completionStatus of
the child may be modified by the completion SignalSet during completion
processing; it is the *final* completionStatus that should be reported
during childComplete processing).
An interoperation issue arises if a child Activity is rooted on a node that
is downstream from the parent's root. In this case, childComplete signals
need to originate from the parent's root ActivityCoordinator/SignalSet.
Mechanically, the completing child should inform its (local) parent
ActivityCoordinator by whichever implementation-specific means it uses and
then the local (subordinate) parent ActivityCoordinator has to push this
back up to its ultimate superior for distribution throughout the tree. The
means by which this happens need to be defined to ensure interoperation
across different vendors' implementations. One approach would be for the
subordinate ActivityCoordinator to drive its superior's
process_signal_set() method, ensuring that the ActivityContext is
propagated on this flow (in order that the superior can obtain the child's
GlobalId). A similar consideration holds for childBegin. There are issues
with this approach; one is that any child Activity, begun at any node
downstream to its parent, will always have its context imported (as a
subordinate) to all upstream nodes on which its parent is active.
A different solution to the problem might be to introduce a new method on
the ActivityCoordinator interface that can be used during child-completion
to pass the ActivityInformation object. This would mean that no service
context would need to flowed and all the information required to deliver
the childComplete signal would be available to the parent. This could be
something like:
void ActivityCoordinator::set_child_completed(in ActivityInformation ai)
It would still be implementation-specific how that ActivityInformation got
added to the signal, but that is not an interoperation issue.Resolution: This issue is mostly closed by 4303. Only a minor clarification remains. The description of the ChildLifetime SignalSet in section 2.2.1 needs the following additional statement.
Should an Activity service implementation be required to marshal a service context when it sends a reply? To put it another way, should a client Activity service interceptor expect to receive context on a reply if it sent one on a request? I would expect that absence of a context on a reply is fine but this needs to be stated in the specification to ensure interoperability between different vendors' implementations.
Resolution: An implementation should not be required to marshal the context on replies. However, the text needs updating.
There is an implicit assumption in the current text that all Current objects are available in all environments. This may not be the case, and we should allow for the fact that some environments may wish to restrict the Currents that are available.
Resolution: It should be possible to restrict the availability of the various Currents used by the service.
There has always been an implicit assumption "something" knows when (and if) to make references to Actions persistent during SignalSet processing. For example, if we consider the case of a two-phase commit SignalSet, then once prepare Signals have been sent and acknowledged successfully by Actions, the service needs to make those references persistent (c.f. the transaction service intentions list). However, currently there is no way for this to happen. Only the Activity Coordinator has the list of the Actions, but it doesn't (and shouldn't) understand the semantics of the Signals it sends. The SignalSet understands the semantics, but doesn't have a handle on the Actions. Somehow the SignalSet must get hold of the Actions in order to do this. What I propose is the addition of a set_coordinator method to SignalSet such that when it is registered with the Activity Coordinator (or more likely when it is about to be used) the coordinator can pass a reference to itself through. Then the SignalSet can have access to the Action list. This is also important if the SignalSet wants to make a one-phase optimisation (when there is only a single Action, for example) as it needs to know the number of Actions, not necessarily who they are.
Resolution: Add the set_activity_coordinator method to the SignalSet interface, and update the text appropriately
In Section 2.2.5 of the specification, a number of pre-defined PropertyGroupAttribute names and their associated values are described. The following are also of value to better define the contract between Activity service and PropertyGroup provider. "marshal_response_update" Indicates whether or not the PropertyGroupManager should be called when an outbound response is marshalled. A value of "true" indicates that the context for the managed PropertyGroup should be updated on a response. A value of "false" indicates that the context for the managed PropertyGroup is not updated on a response so the PropertyGroupManager is not called for marshalResponse. The default value is "false" It may be preferable for either a security or a performance point of view not to transmit server context back to a client with a response. "unmarshal_response_update" Indicates whether or not the PropertyGroupManager should be called when an inbound response is unmarshalled. A value of "true" indicates that the context for the managed PropertyGroup should be updated by the response. A value of "false" indicates that the context for the managed PropertyGroup is not updated by the response so the PropertyGroupManager is not called for unmarshalResponse. The default value is "false" It may be preferable for either a security or a performance point of view not to allow the local context to be updated by changes made in a downstream
The Activity service specification states, in the description of the SignalSet::set_response method: "The SignalSet returns a boolean to indicate whether or not the Action that returned the response should be informed of any further signals from this signal set; if the value is true then the Action continues to receive Signals." This suggests that, if the SignalSet is used to broadcast signals (rather than simply produce completion signals), an Action that indicated it required no further signals during the first broadcast within a particular Activity may well expect to receive signals if the SignalSet was requested to broadcast a second time within the same activity or indeed was subsequently asked to produce completion signals. In a subordinate node, there is no knowledge from one process_signal(Signal) to the next as to which particular broadcast the signal comes from. Therefore, the subordinate has no way of knowing whether a registered Action that indicated no-further-signals on a previous set_response should receive signals on subsequent process_signal calls from the superior.
Resolution: It was always the intention that the Action would be removed from the SignalSet. Therefore, update the text to clarify this
There are a couple of IDL issues with the current CosActivity module: (i) InvalidState is multiply defined. (ii) The ActivityInformation struct should go after the Outcome struct, since it now uses Outcome.
The broadcast method of CosActivityCoordination::Current in the CosActivity IDL should return an Outcome.
The final adopted specification of the Activity Service specification
states, in section 2.2.1:
"If the parent of a sub-Activity is not a root Activity (i.e., it is an
interposed subordinate)
then the distribution of the ChildLifetime signals is delegated upstream to
the superior
ActivityCoordinator."
Since no service context would flow on a delegated process_signal_set
request to an
upstream ActivityCoordinator, then any Action registered in the upstream
node with an
interest in the ChildLifetime SignalSet would not be able to determine the
identity
of the child activity begun.
Any solution to this problem needs to interoperable rather than dependent
on implementation
since the upstream ActivityCoordinator could be part of a foreign domain.
2 potential solutions are:
1. New methods on the ActivityCoordinator and and SignalSet interfaces:
ActivityCoordinator::process_signal_set_with_data(in string ssName,
in CompletionStatus cs, in any signalData);
and
SignalSet::get_signal_with_data(inout boolean lastSignal, in any signalData);
The subordinate Coordinator-Action could build the ActivityInformation any
required by the ChildLifetime SignalSet and pass this in the signalData on
the upstream process_signal_set_with_data.
2. Change the specification to state that ChildLifetime signals are distributed
from the node in which the child Activity begins. In the case where there are
Actions registered with the parent in an upstream node on which the child does
not execute, then these Actions are not informed of the event.
(2) is simpler but compromises the ideal of location transparency.
Resolution: Change the specification to state that ChildLifetime signals are distributed from the node in which the child Activity begins. In the case where there are Actions registered with the parent in an upstream node on which the child does not execute, then these Actions are not informed of the event.
The ActivityCoordinator complete_activity operation may raise ActivityPending and ChildContextPending exceptions. The conditions under which these exceptions are raised should be independent of whether they occur in the root or a subordinate node. For example, if the a subordinate node had earlier spawned an asynchronous thread that was not complete when the subordinate was signaled for preCompletion, then the application originator (on the root) should receive an ActivityPending exception that does not cause the Activity to complete or mark is as failed only. Yet, at the subordinate, the only response that the subordinate Synchronization Action can give during preCompletion is an Outcome of preCompletionSuccess or preCompletionFailed or an ActionError exception, none of which result in the desired behaviour. Possible solutions are: 1. New exceptions on the Action::process_signal exception that the root ActivityCoordinator converts to ActivityPending or ChildContextPending. CORBA::TRANSIENT could be used if the minor codes were architected. This is ugly because its specific to the processing of the Synchronization SignalSet. 2. New predefined Outcomes for the Synchronization SignalSet that the root ActivityCoordinator can recognize and convert accordingly. Still a little ugly in that the ActivityCoordinator needs to understand the meaning of an Outcome. In either case, the Synchronization SignalSet needs to be capable of being redriven after returning such an Outcome/Exception.
Resolution: Add new predefined Outcomes for the Synchronization SignalSet that a root ActivityCoordinator can recognize in order to return appropriate ActivityPending or ChildContextPending exceptions.
The current specification implicitly assumes that, as with the OTS, contexts do not get propagated on system messages such as processSignal. However, this needs to be explicitly stated.
Close this issue as it is addressed by Section 2.3.1 in the specification
Currently the core of the Additional Structuring Mechanisms for the OTS (aka Activity Service) assumes synchronous responses from participants (Actions) at the instigation of the coordinator messages (generated by the SignalSet). As we have found in several recent studies and other work on extended transactions (e.g., the OASIS BTP) there are good reasons why participants may want to asynchronously send "responses" to messages the coordinator hasn't yet generated. For example, in a two-phase protocol, a participant may be able to spontaneously prepare and send the coordinator the relevant Outcome. In the current spec. this isn't possible directly. Obviously there are tricks that could be played with another-level-of-indirection (e.g., enlist a "cacheing" participant with the coordinator that the real Action enlists with and this receives [and stores] any spontaneous responses). However, even this doesn't really address the entire problem since the response the Action sent (the Outcome) is made with respect to a presumed specific Signal that the coordinator sent. So, what if the coordinator doesn't send that Signal? Having this as part of the core will help us to continue to support a wide range of coordination/extended transaction protocols.
Not enough time to discuss in this RTF ..deferred
Currently the core of the Additional Structuring Mechanisms for the OTS (aka Activity Service) assumes synchronous responses from participants (Actions) at the instigation of the coordinator messages (generated by the SignalSet). As we have found in several recent studies and other work on extended transactions (e.g., the OASIS BTP) there are good reasons why participants may want to asynchronously send "responses" to messages the coordinator hasn't yet generated. For example, in a two-phase protocol, a participant may be able to spontaneously prepare and send the coordinator the relevant Outcome. In the current spec. this isn't possible directly. Obviously there are tricks that could be played with another-level-of-indirection (e.g., enlist a "cacheing" participant with the coordinator that the real Action enlists with and this receives [and stores] any spontaneous responses). However, even this doesn't really address the entire problem since the response the Action sent (the Outcome) is made with respect to a presumed specific Signal that the coordinator sent. So, what if the coordinator doesn't send that Signal? Having this as part of the core will help us to continue to support a wide range of coordination/extended transaction protocols.
In the Additional Structuring Mechanisms for the OTS, an Action can register interest in more than one SignalSet, i.e., it can be passed to add_action more than once, with a different SignalSet parameter. However, remove_action is not parameterised on the SignalSet, so currently it must remove the Action from all registered SignalSets. We can either add the SignalSet as a parameter to remove_action or add another method, leaving the semantics of remove_action as they are
Close this issue as it is addressed by the solution to issue 4252.
The current specification has the necessary hooks for recreating the distributed activity tree in the event of failures, but the text does not give an implementers view of what to do. For example, when using interposition, it is somehow necessary for a SubordinateSignalSet to remember who (ActivityCoordinator) it was enlisted with so that, upon failure and recovery, it could enquire as to the status of the activity. Now, since a SubordinateSignalSet is also a SignalSet, there is a set_activity_coordinator method that the enroller of the SubordinateSignalSet could use to pass the reference to it. The SubordinateSignalSet can then persist this information when (and if) it is necessary during the protocol. When it recovers, because all IORs are required to be persistent, it will be able to contact the coordinator and find out the status. Some text like the above would be very useful in the spec.
Not enough time to discuss in this RTF.
Section 2.2.9 of the specification, in the description of the compete method, includes the following text: "If the completion status is CompletionStatusFail, or CompletionStatusFailOnly, any encompassed active or suspended Activities will then have their completion status set to CompletionStatusFailOnly and transactions will be marked rollback_only." This behaviour is too restrictive for extended transaction models that may wish to allow child activities to complete successfully despite the fact that a parent activity is failed. I suggest that this restriction be removed.
the activity depicted in figure 1.2 does exhibit a failure whereas the figure depicted in figure 1.3 does not exhibit a failure the titles of these figures are correct but the contents should be interchanged