Author: david.lloyd(a)jboss.com
Date: 2008-04-18 11:52:26 -0400 (Fri, 18 Apr 2008)
New Revision: 4010
Modified:
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/protocol/ProtocolContext.java
remoting3/trunk/core/src/main/java/org/jboss/cx/remoting/core/CoreSession.java
Log:
Opening a client within a service should be idempotent - make it so. JBREM-963
Modified:
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/protocol/ProtocolContext.java
===================================================================
---
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/protocol/ProtocolContext.java 2008-04-18
15:16:59 UTC (rev 4009)
+++
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/protocol/ProtocolContext.java 2008-04-18
15:52:26 UTC (rev 4010)
@@ -9,32 +9,104 @@
import org.jboss.cx.remoting.spi.ObjectMessageOutput;
/**
+ * The receiver interface for protocol sessions. Methods on this interface are invoked
as a result of
+ * the corresponding methods in {@link
org.jboss.cx.remoting.spi.protocol.ProtocolHandler} being called on the
+ * remote side.
*
+ * These methods generally do not throw exceptions, in order to simplify protocol
implementation.
*/
public interface ProtocolContext {
/* CLIENT methods */
+ /**
+ * Receive a reply to a request.
+ *
+ * @param clientIdentifier the client identifier
+ * @param requestIdentifier the identifier of the request that was finished
+ * @param reply the reply
+ */
void receiveReply(ClientIdentifier clientIdentifier, RequestIdentifier
requestIdentifier, Object reply);
+ /**
+ * Receive an exception response to a request.
+ *
+ * @param clientIdentifier the client identifier
+ * @param requestIdentifier the identifier of the request which failed
+ * @param exception the exception
+ */
void receiveException(ClientIdentifier clientIdentifier, RequestIdentifier
requestIdentifier, RemoteExecutionException exception);
+ /**
+ * Receive a cancel acknowledgement to a request.
+ *
+ * @param clientIdentifier the client identifier
+ * @param requestIdentifier the identifier of the request which was cancelled
+ */
void receiveCancelAcknowledge(ClientIdentifier clientIdentifier, RequestIdentifier
requestIdentifier);
+ /**
+ * Receive a notification that the given service is closing - that is, no more
clients can be opened from it.
+ *
+ * @param serviceIdentifier the identifier of the closing service
+ */
void receiveServiceClosing(ServiceIdentifier serviceIdentifier);
+ /**
+ * Receive a notification that the given client is closing - that is, no more
requests may be sent on it.
+ *
+ * @param clientIdentifier the identifier of the closing client
+ * @param done {@code true} if the client is fully closed
+ */
void receiveClientClosing(ClientIdentifier clientIdentifier, boolean done);
/* SERVER methods */
+ /**
+ * Receive a notification that the given service was closed. The close may have been
caused by a call to the
+ * {@link org.jboss.cx.remoting.ClientSource#close()} method.
+ *
+ * @param remoteServiceIdentifier the service identifier
+ */
void receiveServiceClose(ServiceIdentifier remoteServiceIdentifier);
+ /**
+ * Receive a notification that the given client was closed. The close may have been
caused by a call to the
+ * {@link org.jboss.cx.remoting.Client#close()} or {@link
org.jboss.cx.remoting.Client#closeImmediate()} methods.
+ *
+ * @param remoteClientIdentifier the client identifier
+ * @param immediate {@code true} if the client should be closed immediately
+ * @param cancel {@code true} if outstanding requests should be cancelled
+ * @param interrupt {@code true} if outstanding requests should be interrupted
+ */
void receiveClientClose(ClientIdentifier remoteClientIdentifier, boolean immediate,
boolean cancel, boolean interrupt);
+ /**
+ * Receive a notification that a context was opened within a service. Subsequent
requests for this client will
+ * be associated with the service. This method is idempotent, meaning that multiple
calls with the same parameters
+ * are treated as one call.
+ *
+ * @param remoteServiceIdentifier the service identifier
+ * @param remoteClientIdentifier the client identifier
+ */
void receiveOpenedContext(ServiceIdentifier remoteServiceIdentifier, ClientIdentifier
remoteClientIdentifier);
+ /**
+ * Receive a request from the remote side.
+ *
+ * @param remoteClientIdentifier the client identifier
+ * @param requestIdentifier the request identifier
+ * @param request the request
+ */
void receiveRequest(ClientIdentifier remoteClientIdentifier, RequestIdentifier
requestIdentifier, Object request);
+ /**
+ * Receive a request to cancel an outstanding request.
+ *
+ * @param remoteClientIdentifier the client identifier
+ * @param requestIdentifier the request identifier
+ * @param mayInterrupt {@code true} if the request may be interrupted
+ */
void receiveCancelRequest(ClientIdentifier remoteClientIdentifier, RequestIdentifier
requestIdentifier, boolean mayInterrupt);
/* SESSION methods */
Modified: remoting3/trunk/core/src/main/java/org/jboss/cx/remoting/core/CoreSession.java
===================================================================
---
remoting3/trunk/core/src/main/java/org/jboss/cx/remoting/core/CoreSession.java 2008-04-18
15:16:59 UTC (rev 4009)
+++
remoting3/trunk/core/src/main/java/org/jboss/cx/remoting/core/CoreSession.java 2008-04-18
15:52:26 UTC (rev 4010)
@@ -361,11 +361,15 @@
throw new NullPointerException("remoteClientIdentifier is
null");
}
try {
- final ServerServicePair servicePair =
serverServices.get(remoteServiceIdentifier);
- final ProtocolClientInitiatorImpl contextClient = new
ProtocolClientInitiatorImpl(remoteClientIdentifier);
- final ClientResponder clientResponder =
servicePair.serviceResponder.createNewClient(contextClient);
- // todo - who puts it in the map?
- serverContexts.put(remoteClientIdentifier, new
ServerContextPair(contextClient, clientResponder));
+ // This operation needs to be idempotent
+ if (! serverContexts.containsKey(remoteClientIdentifier)) {
+ final ServerServicePair servicePair =
serverServices.get(remoteServiceIdentifier);
+ final ProtocolClientInitiatorImpl contextClient = new
ProtocolClientInitiatorImpl(remoteClientIdentifier);
+ final ClientResponder clientResponder =
servicePair.serviceResponder.createNewClient(contextClient);
+ if (serverContexts.putIfAbsent(remoteClientIdentifier, new
ServerContextPair(contextClient, clientResponder)) != null) {
+ clientResponder.handleClose(true, true);
+ }
+ }
} catch (RemotingException e) {
log.trace(e, "Failed to add a context to a service");
}
Show replies by date