Author: nash
Date: Thu Jan 17 16:35:48 2008
New Revision: 613024

URL: http://svn.apache.org/viewvc?rev=613024&view=rev
Log:
Fixed TUSCANY-1965

Modified:
    
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
    
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackReferenceImpl.java
    
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java

Modified: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java?rev=613024&r1=613023&r2=613024&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
 (original)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/RuntimeWireImpl.java
 Thu Jan 17 16:35:48 2008
@@ -64,6 +64,13 @@
     private transient ConversationManager conversationManager;
     private transient RuntimeWireInvoker invoker;
 
+    // the following is a very simple cache that avoids re-cloning a wire
+    // when consecutive callbacks to the same endpoint are made
+    private EndpointReference lastCallback;
+    private RuntimeWire cachedWire;
+    private boolean wireReserved;
+    private RuntimeWireImpl clonedFrom;
+
     private List<InvocationChain> chains;
 
     /**
@@ -274,5 +281,35 @@
      */
     public ConversationManager getConversationManager() {
         return conversationManager;
+    }
+
+    public synchronized RuntimeWire lookupCache(EndpointReference callback) {
+        if (lastCallback != null && 
callback.getURI().equals(lastCallback.getURI()) && !wireReserved) {
+            wireReserved = true;
+            return cachedWire;
+        } else {
+            return null;
+        }
+    }
+
+    public synchronized void addToCache(EndpointReference callback, 
RuntimeWire clonedWire) {
+        ((RuntimeWireImpl)clonedWire).setClonedFrom(this);
+        lastCallback = callback;
+        cachedWire = clonedWire;
+        wireReserved = true;
+    }
+
+    public synchronized void releaseClonedWire(RuntimeWire wire) {
+        if (cachedWire == wire) {
+            wireReserved = false;
+        }
+    }
+
+    public synchronized void releaseWire() {
+        clonedFrom.releaseClonedWire(this);
+    }
+
+    private void setClonedFrom(RuntimeWireImpl wire) {
+        clonedFrom = wire;
     }
 }

Modified: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackReferenceImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackReferenceImpl.java?rev=613024&r1=613023&r2=613024&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackReferenceImpl.java
 (original)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/CallbackReferenceImpl.java
 Thu Jan 17 16:35:48 2008
@@ -21,7 +21,9 @@
 import java.util.List;
 
 import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Contract;
 import org.apache.tuscany.sca.assembly.OptimizableBinding;
+import org.apache.tuscany.sca.core.assembly.RuntimeWireImpl;
 import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
 import org.apache.tuscany.sca.core.factory.ObjectCreationException;
 import org.apache.tuscany.sca.invocation.Message;
@@ -67,6 +69,7 @@
             return super.getProxy();
         } else {
             // wire not yet selected, so return a proxy that resolves the 
target dynamically
+            //FIXME: the following call creates a new instance of 
CallbackReferenceImpl
             return proxyFactory.createCallbackProxy(businessInterface, wires);
         }
     }
@@ -77,14 +80,17 @@
             return null;
         }
 
-        //FIXME: need a cache for better performance.  This requires making 
this
-        // method non-static, which means changing the signature of 
createCallbackProxy().
-
         // first choice is wire with matching destination endpoint
         for (RuntimeWire wire : wires) {
             if (callbackEPR.getURI().equals(wire.getTarget().getURI())) {
+                RuntimeWire clonedWire = 
((RuntimeWireImpl)wire).lookupCache(callbackEPR);
+                if (clonedWire != null) {
+                    return clonedWire;
+                }
                 try {
-                    return (RuntimeWire)wire.clone();
+                    clonedWire = (RuntimeWire)wire.clone();
+                    ((RuntimeWireImpl)wire).addToCache(callbackEPR, 
clonedWire);
+                    return clonedWire;
                 } catch (CloneNotSupportedException e) {
                     throw new ServiceRuntimeException(e);
                 }
@@ -135,29 +141,37 @@
         return from.getReferenceParameters().getCallbackReference();
     }
 
-    private static RuntimeWire cloneAndBind(Message msgContext, RuntimeWire 
wire) {
+    private RuntimeWire cloneAndBind(Message msgContext, RuntimeWire wire) {
         EndpointReference callback = getCallbackEndpoint(msgContext);
-        if (callback != null && callback.getContract() != null) {
+        RuntimeWire boundWire = null;
+        if (callback != null) {
+            boundWire = ((RuntimeWireImpl)wire).lookupCache(callback);
+            if (boundWire != null) {
+                return boundWire;
+            }
             try {
+                Contract contract = callback.getContract();
                 RuntimeComponentReference ref = null;
-                if (callback.getContract() instanceof 
RuntimeComponentReference) {
-                    ref = (RuntimeComponentReference)callback.getContract();
-                    return ref.getRuntimeWire(callback.getBinding());
-                } else {
-                    ref =
-                        
bind((RuntimeComponentReference)wire.getSource().getContract(),
-                             callback.getComponent(),
-                             (RuntimeComponentService)callback.getContract());
+                if (contract == null) {
+                    boundWire = (RuntimeWire)wire.clone();
 
-                    return ref.getRuntimeWires().get(0);
+                } else if (contract instanceof RuntimeComponentReference) {
+                    ref = (RuntimeComponentReference)contract;
+                    boundWire = ref.getRuntimeWire(callback.getBinding());
+
+                } else {  // contract instanceof RuntimeComponentService
+                    ref = 
bind((RuntimeComponentReference)wire.getSource().getContract(),
+                               callback.getComponent(),
+                               (RuntimeComponentService)contract);
+                    boundWire = ref.getRuntimeWires().get(0);
                 }
+                configureWire(boundWire, msgContext);
+                ((RuntimeWireImpl)wire).addToCache(callback, boundWire);
             } catch (CloneNotSupportedException e) {
                 // will not happen
-                return null;
             }
-        } else {
-            return wire;
         }
+        return boundWire;
     }
 
     private static RuntimeComponentReference bind(RuntimeComponentReference 
reference,
@@ -180,4 +194,20 @@
         return ref;
     }
 
+    private void configureWire(RuntimeWire wire, Message msgContext) {
+        // need to set the endpoint on the binding also so that when the 
chains are created next
+        // the sca binding can decide whether to provide local or remote 
invokers. 
+        // TODO - there is a problem here though in that I'm setting a target 
on a 
+        //        binding that may possibly be trying to point at two things 
in the multi threaded 
+        //        case. Need to confirm the general model here and how the 
clone and bind part
+        //        is intended to work
+        EndpointReference epr = 
msgContext.getFrom().getReferenceParameters().getCallbackReference();
+        wire.getSource().getBinding().setURI(epr.getURI());
+
+        // also need to set the target contract as it varies for the sca 
binding depending on 
+        // whether it is local or remote
+        RuntimeComponentReference ref = 
(RuntimeComponentReference)wire.getSource().getContract();
+        Binding binding = wire.getSource().getBinding();
+        
wire.getTarget().setInterfaceContract(ref.getBindingProvider(binding).getBindingInterfaceContract());
+    }
 }

Modified: 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java?rev=613024&r1=613023&r2=613024&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
 (original)
+++ 
incubator/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/JDKCallbackInvocationHandler.java
 Thu Jan 17 16:35:48 2008
@@ -97,19 +97,7 @@
         EndpointReference epr = 
msgContext.getFrom().getReferenceParameters().getCallbackReference();
         setEndpoint(epr);
 
-        // need to set the endpoint on the binding also so that when the 
chains are created next
-        // the sca binding can decide whether to provide local or remote 
invokers. 
-        // TODO - there is a problem here though in that I'm setting a target 
on a 
-        //        binding that may possibly be trying to point at two things 
in the multi threaded 
-        //        case. Need to confirm the general model here and how the 
clone and bind part
-        //        is intended to work
-        wire.getSource().getBinding().setURI(epr.getURI());
-
-        // also need to set the target contract as it varies for the sca 
binding depending on 
-        // whether it is local or remote
-        RuntimeComponentReference ref = 
(RuntimeComponentReference)wire.getSource().getContract();
-        Binding binding = wire.getSource().getBinding();
-        
wire.getTarget().setInterfaceContract(ref.getBindingProvider(binding).getBindingInterfaceContract());
+        // code that was previously here has been moved to 
CallbackReferenceImpl.configureWire()
 
         //FIXME: can we use the same code as JDKInvocationHandler to select 
the chain? 
         InvocationChain chain = getInvocationChain(method, wire);
@@ -125,6 +113,9 @@
                 throw t;
             }
             throw e;
+        } finally {
+            // allow the cloned wire to be reused by subsequent callbacks
+            ((RuntimeWireImpl)wire).releaseWire();
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to