Invasive patterns reconcile architecture and implementation in distributed applications.
//----- excerpt of code in the invoke method of
//----- class DataGravitation
...
try
{
switch (m.getMethodId())
{
case MethodDeclarations.prepareMethod_id:
case MethodDeclarations.optimisticPrepareMethod_id:
Object o = super.invoke(m);
doPrepare(getInvocationContext().getGlobalTransaction());
return o;
case MethodDeclarations.rollbackMethod_id:
transactionMods.remove(
getInvocationContext().getGlobalTransaction());
return super.invoke(m);
case MethodDeclarations.commitMethod_id:
doCommit(getInvocationContext().getGlobalTransaction());
transactionMods.remove(
getInvocationContext().getGlobalTransaction());
return super.invoke(m);
}
}
...
This code shows a switch statement that implements the two phase commit protocol.
Note that such code is only called when data gravitation is active, and is found in the invoke method of the class DataGravitation (entangling). We can see in the code above (see highlighted code) that such implementation takes full control of the protocol replicating actual data by analyzing the doCommit method implementation:
//---- The docommit method in DataGravitation class
private void doCommit(GlobalTransaction gtx) throws Throwable
{
if (transactionMods.containsKey(gtx))
{
if (log.isTraceEnabled())
log.trace("Broadcasting commit for gtx " + gtx);
replicateCall(getMembersOutsideBuddyGroup(),
MethodCallFactory.create(
MethodDeclarations.commitMethod,
new Object[]{gtx}),
syncCommunications);
}
else
{
if (log.isTraceEnabled())
log.trace(
"Nothing to broadcast in commit phase for gtx " + gtx);
}
}
Here the doCommit method decides to which hosts the commit method is broad casted. In this case, to all members outside the "BuddyGroup"(see highlighted code).
P ::= patternSeq G1 A1 G2 A2 . . . Gn
G ::= H G |P G |ǫ
A ::= aspect { around((H, Id*)*): PCD SourceAdvice [sync] TargetAdvice }
PCD ::= call(MSig ) | target(Id) | args(Id+)
| PCD && PCD | PCD || PCD | !PCD
| Seq
patternSeq G1 A1 G2 A2 . . . GnGi Ai Gi+1 : pattern application triple of source group, distributed aspect, target group
gCaches = {h1, h2, h3}
pipe([h], // h is current host
Atransac,
farm(
gather(
farm([h], Aprepare, sync gCaches-[h]),
Apresp,
[h]),
Acommit,
gCaches-[h])
);