Hi Gilbert,
Thanks for the patch. I tried to apply it but the version is not matching
the current svn tree.
Please update the code and creat the patch.
-Jaliya
----- Original Message -----
From: "Gilbert Pilz" <[EMAIL PROTECTED]>
To: "Jaliya Ekanayake" <[EMAIL PROTECTED]>; <[email protected]>
Sent: Tuesday, October 03, 2006 3:49 PM
Subject: RE: Sandesha 1.0; fix for clients hanging in
SandeshaContext.endSequence()
There is a race condition for outbound sequences between the
SenderWorker thread transmitting the TerminateSequence message and the
endSequence() call stopping that thread. It's difficult to figure out
what a good wait value might be because, depending upon how many
messages are queued up, the length of time you might need to wait for
the TerminateSequence to be sent could be arbitrarily long.
I've changed the code to log an INFO-level message when an incomplete
sequence is ignored. If ignoring incomplete sequences causes people
problems then they shouldn't do that.
- gp
-----Original Message-----
From: Jaliya Ekanayake [mailto:[EMAIL PROTECTED]
Sent: Friday, September 29, 2006 8:06 PM
To: Gilbert Pilz; [email protected]
Subject: Re: Sandesha 1.0; fix for clients hanging in
SandeshaContext.endSequence()
Sure, I have one clarification.
What not allow some time-out before we cleanup. The reason
for this is as follows; In the one-way messaging case
SandeshaContext.endSequence() is called just after the
service requests so if someone use END_SEQUENCE_IGNORE_ACTIVE
then the sequences will immediately be terminated. It is
better to set some timestamp to wait.
In addition can you please send the patch as an attachment?
Thanks,
-Jaliya
----- Original Message -----
From: "Gilbert Pilz" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Friday, September 29, 2006 7:14 PM
Subject: Sandesha 1.0; fix for clients hanging in
SandeshaContext.endSequence()
The story so far: the SandeshaContext.endSequence() method
waits for all the sequences related to a SandeshaContext to
"complete" before it returns. Because some implementations of
WS-RM (200502) do not automatically terminate their offered
sequence when the sequence that carried that offer is
terminated (did you get that?), this may cause a Sandesha
client to hang until the sequence's inactivity timeout expires.
At this point the client will see an AxisFault that they may
or may not understand to be benign.
My plan was to fix this by adding a property to the
SandeshaContext called "EndSeqBehavior". The default value
for this behavior, "END_SEQUENCE_BLOCK_ON_ACTIVE", causes
endSequence() to behave exactly as it does today (block on
any active sequences until they either complete or time out
due to inactivity). Another value for this behavior,
"END_SEQUENCE_IGNORE_ACTIVE", causes endSequence() to simply
ignore any active sequences and clean up. This behavior is ok
if all you are interested in doing is cleaning up quickly,
but it could make things difficult for the peers of the
sequences that are more or less orphaned.
If they tried to send messages using those sequences they
would retry and retry and retry until they reached some
internal limit that told them to stop. This seems rather
wasteful given the fact that Sandesha knew it was going to
abandon the sequence, so I thought there should be one more
value for the EndSeqBehavior property called
"END_SEQUENCE_FAULT_ACTIVE". This value would cause
endSequence() to send an unsolicited wsrm:SequenceTerminated
fault to the sequence peer of any active sequences.
Unfortunately the last value has proven much harder to
implement than I expected so I thought it would be a good
idea to at least get the changes for
END_SEQUENCE_IGNORE_ACTIVE into the tree. Below are two patch
files; one for org/apache/sandesha/Constants.java and one for
org/apache/sandesha/SandeshaContext.java.
Jaliya, if you could look these over and get them into the
tree, I would appreciate that very much. Note that clients
that are unaware of the EndSeqBehavior property will continue
to work as they do today w/out recompilation etc. Clients
that wish to avoid the hanging problem described above simply
have to call the new
SandeshaContext.setEndSeqBehavior() method with the
appropriate value (as defined in Constants).
- gp
Index: src/org/apache/sandesha/Constants.java
===================================================================
--- src/org/apache/sandesha/Constants.java (revision 451449)
+++ src/org/apache/sandesha/Constants.java (working copy)
@@ -72,6 +72,10 @@
int SYNCHRONOUS = 0;
+ // Flags for controlling the behavior of endSequence()
in the face
of active sequences.
+ int END_SEQUENCE_BLOCK_ON_ACTIVE = 0; // default
+ int END_SEQUENCE_IGNORE_ACTIVE = 1; // ignore any active
seqs
+
public interface WSA {
String NS_ADDRESSING_ANONYMOUS =
AddressingUtils.getAnonymousRoleURI();
}
----------------------------------------
Index: src/org/apache/sandesha/SandeshaContext.java
===================================================================
--- src/org/apache/sandesha/SandeshaContext.java (revision
451449)
+++ src/org/apache/sandesha/SandeshaContext.java (working copy)
@@ -76,6 +76,7 @@
private boolean sendOffer;
private long messageNumber;
private boolean sync;
+ private int endSeqActiveBehavior;
static int clientListnerPort = -1;
public final int MIN_PORT = 0;
@@ -155,6 +156,14 @@
this.toURL = toURL;
}
+ public int getEndSeqBehavior() {
+ return endSeqActiveBehavior;
+ }
+
+ public void setEndSeqBehavior(int flag) {
+ this.endSeqActiveBehavior = flag;
+ }
+
public SandeshaContext() throws AxisFault {
initSandeshaAsync();
}
@@ -331,33 +340,38 @@
public final RMReport endSequence() throws AxisFault {
IStorageManager storageManager = new ClientStorageManager();
- long startingTime = System.currentTimeMillis();
- long inactivityTimeOut =
PolicyLoader.getInstance().getInactivityTimeout();
- Iterator ite = callMap.keySet().iterator();
+ if (endSeqActiveBehavior !=
Constants.END_SEQUENCE_IGNORE_ACTIVE)
+ {
+ long startingTime = System.currentTimeMillis();
+ long inactivityTimeOut =
PolicyLoader.getInstance().getInactivityTimeout();
- while (ite.hasNext()) {
- String key = (String) ite.next();
- Call tempCall = (Call) callMap.get(key);
- String seqId = (String)
tempCall.getProperty(Constants.ClientProperties.CALL_KEY);
- while (!storageManager.isSequenceComplete(seqId)) {
- try {
- if (log.isDebugEnabled()) {
-
log.debug(Constants.InfomationMessage.WAITING_TO_STOP_CLIENT);
+ Iterator ite = callMap.keySet().iterator();
+
+ while (ite.hasNext()) {
+ String key = (String) ite.next();
+ Call tempCall = (Call) callMap.get(key);
+ String seqId = (String)
tempCall.getProperty(Constants.ClientProperties.CALL_KEY);
+ while (!storageManager.isSequenceComplete(seqId)) {
+ try {
+ if (log.isDebugEnabled()) {
+
log.debug(Constants.InfomationMessage.WAITING_TO_STOP_CLIENT);
+ }
+
Thread.sleep(Constants.CLIENT_WAIT_PERIOD_FOR_COMPLETE);
+ if ((System.currentTimeMillis() -
startingTime)
>= inactivityTimeOut) {
+ stopClientByForce();
+ this.report.setError("Inactivity Time Out
Reached. Sequence not complete");
+ }
+ } catch (InterruptedException e) {
+ log.error("",e);
}
-
Thread.sleep(Constants.CLIENT_WAIT_PERIOD_FOR_COMPLETE);
- if ((System.currentTimeMillis() -
startingTime) >=
inactivityTimeOut) {
- stopClientByForce();
- this.report.setError("Inactivity Time Out
Reached. Sequence not complete");
- }
- } catch (InterruptedException e) {
- log.error("",e);
}
}
}
+ // else - ignore any sequence that are still active
if (this.report.getError() == null) {
- this.report.setAllAcked(true);
+ this.report.setAllAcked(true);
}
seqMap.remove(key);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]