Author: jmarino
Date: Thu Apr 13 17:18:23 2006
New Revision: 393986
URL: http://svn.apache.org/viewcvs?rev=393986&view=rev
Log:
refactor of scope contexts
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/ScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -64,7 +64,7 @@
/**
* Removes a context bound to the given name and scope key
- *
+ *
* @throws ScopeRuntimeException
*/
public void removeContextByKey(String name, Object key) throws
ScopeRuntimeException;
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/AbstractScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -22,7 +22,6 @@
import org.apache.tuscany.core.context.QualifiedName;
import org.apache.tuscany.core.context.ScopeContext;
import org.apache.tuscany.core.context.TargetException;
-import org.apache.tuscany.core.context.AtomicContext;
import org.apache.tuscany.core.context.impl.AbstractContext;
import java.util.List;
@@ -31,16 +30,13 @@
/**
* Implements functionality common to scope contexts.
- * <p>
- * <b>NB: </b>Minimal synchronization is performed, particularly for
initializing and destroying scopes, and it is
- * assumed the scope container will block requests until these operations have
completed.
- *
+ *
* @version $Rev$ $Date$
*/
public abstract class AbstractScopeContext extends AbstractContext implements
ScopeContext {
// The collection of runtime configurations for the scope
- protected Map<String, ContextFactory<Context>> contextFactorys = new
ConcurrentHashMap<String, ContextFactory<Context>>();
+ protected Map<String, ContextFactory<Context>> contextFactories = new
ConcurrentHashMap<String, ContextFactory<Context>>();
// The event context the scope container is associated with
protected EventContext eventContext;
@@ -52,7 +48,7 @@
public void registerFactories(List<ContextFactory<Context>>
configurations) {
for (ContextFactory<Context> configuration : configurations) {
- contextFactorys.put(configuration.getName(), configuration);
+ contextFactories.put(configuration.getName(), configuration);
}
}
@@ -66,52 +62,13 @@
return context.getInstance(qName);
}
- protected EventContext getEventContext() {
- return eventContext;
- }
-
- /**
- * Notfies instances that are associated with a context and configured to
receive callbacks that the context is
- * being destroyed in reverse order
- *
- * @param key the context key
- */
- protected void notifyInstanceShutdown(Object key) {
- Context[] contexts = getShutdownContexts(key);
- if ((contexts == null) || (contexts.length < 1)) {
- return;
- }
- // shutdown destroyable instances in reverse instantiation order
- for (int i = contexts.length - 1; i >= 0; i--) {
- Context context = contexts[i];
-
- if (context.getLifecycleState() == RUNNING) {
- synchronized (context) {
- removeContextByKey(context.getName(), key);
- try {
- if (context instanceof AtomicContext){
- ((AtomicContext)context).destroy();
- }
- context.stop();
- } catch (TargetException e) {
- // TODO send a monitoring event
- // log.error("Error releasing instance [" +
context.getName() + "]",e);
- }
- }
- }
- }
- }
-
protected void checkInit() {
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope not running [" +
lifecycleState + "]");
}
}
- /**
- * Returns an array of contexts that need to be notified of scope
shutdown. The array must be in the order in which
- * component contexts were created
- */
- protected abstract Context[] getShutdownContexts(Object key);
-
+ protected EventContext getEventContext() {
+ return eventContext;
+ }
}
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/CompositeScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -143,7 +143,6 @@
}
// propagate events to child contexts
for (CompositeContext context : contexts.values()) {
- System.out.println("context"+context);
context.publish(event);
}
}
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/ModuleScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -21,28 +21,29 @@
import org.apache.tuscany.core.context.Context;
import org.apache.tuscany.core.context.CoreRuntimeException;
import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
+import org.apache.tuscany.core.context.TargetException;
import org.apache.tuscany.core.context.event.ContextCreatedEvent;
+import org.apache.tuscany.core.context.event.Event;
import org.apache.tuscany.core.context.event.ModuleStartEvent;
import org.apache.tuscany.core.context.event.ModuleStopEvent;
-import org.apache.tuscany.core.context.event.Event;
import java.util.Map;
-import java.util.Queue;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Manages component contexts whose implementations are module scoped
*
* @version $Rev$ $Date$
*/
-public class ModuleScopeContext extends AbstractScopeContext implements
RuntimeEventListener {
+public class ModuleScopeContext extends AbstractScopeContext {
// Component contexts in this scope keyed by name
private Map<String, Context> componentContexts;
- private Queue<AtomicContext> destroyableContexts;
+ private List<Context> destroyableContexts;
public ModuleScopeContext(EventContext eventContext) {
super(eventContext);
@@ -54,7 +55,7 @@
lifecycleState = RUNNING;
initComponentContexts();
} else if (event instanceof ModuleStopEvent) {
- notifyInstanceShutdown(null);
+ notifyInstanceShutdown();
} else if (event instanceof ContextCreatedEvent) {
checkInit();
if (event.getSource() instanceof AtomicContext) {
@@ -73,8 +74,7 @@
}
}
- public synchronized void stop
- () {
+ public synchronized void stop() {
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope in wrong state [" +
lifecycleState + "]");
}
@@ -83,74 +83,83 @@
lifecycleState = STOPPED;
}
- public boolean isCacheable
- () {
+ public boolean isCacheable() {
return true;
}
public void registerFactory
(ContextFactory<Context> configuration) {
- contextFactorys.put(configuration.getName(), configuration);
+ contextFactories.put(configuration.getName(), configuration);
if (lifecycleState == RUNNING) {
componentContexts.put(configuration.getName(),
configuration.createContext());
}
}
- public Context getContext
- (String
- ctxName) {
+ public Context getContext(String ctxName) {
checkInit();
+ initComponentContexts();
return componentContexts.get(ctxName);
}
- public Context getContextByKey
- (String
- ctxName, Object
- key) {
+ public Context getContextByKey(String ctxName, Object key) {
checkInit();
+ initComponentContexts();
return componentContexts.get(ctxName);
}
- public void removeContext
- (String
- ctxName) {
+ public void removeContext(String ctxName) {
checkInit();
+ if (componentContexts == null){
+ return;
+ }
Context context = componentContexts.remove(ctxName);
if (context != null) {
destroyableContexts.remove(context);
}
}
- public void removeContextByKey
- (String
- ctxName, Object
- key) {
- checkInit();
+ public void removeContextByKey(String ctxName, Object key){
removeContext(ctxName);
}
+
/**
- * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing
components that need to be notified of scope shutdown.
+ * Notfies instances that are associated with a context and configured to
receive callbacks that the context is
+ * being destroyed in reverse order
*/
- protected Context[] getShutdownContexts
- (Object
- key) {
- if (destroyableContexts != null) {
- // create 0-length array since Queue.size() has O(n) traversal
- return destroyableContexts.toArray(new Context[0]);
- } else {
- return null;
+ private synchronized void notifyInstanceShutdown() {
+ if (destroyableContexts == null || destroyableContexts.size() == 0) {
+ return;
+ }
+ // shutdown destroyable instances in reverse instantiation order
+ ListIterator<Context> iter =
destroyableContexts.listIterator(destroyableContexts.size());
+ while(iter.hasPrevious()){
+ Context context = iter.previous();
+ if (context.getLifecycleState() == RUNNING) {
+ synchronized (context) {
+ //removeContextByKey(context.getName(), key);
+ try {
+ if (context instanceof AtomicContext){
+ ((AtomicContext)context).destroy();
+ }
+ context.stop();
+ } catch (TargetException e) {
+ // TODO send a monitoring event
+ // log.error("Error releasing instance [" +
context.getName() + "]",e);
+ }
+ }
+ }
}
- }
+ componentContexts = null;
+ destroyableContexts = null;
+ }
- private synchronized void initComponentContexts
- () throws CoreRuntimeException {
+ private synchronized void initComponentContexts() throws
CoreRuntimeException {
if (componentContexts == null) {
componentContexts = new ConcurrentHashMap<String, Context>();
- destroyableContexts = new ConcurrentLinkedQueue<AtomicContext>();
- for (ContextFactory<Context> config : contextFactorys.values()) {
+ destroyableContexts = new ArrayList<Context>();
+ for (ContextFactory<Context> config : contextFactories.values()) {
Context context = config.createContext();
- context.addListener(this);
context.start();
componentContexts.put(context.getName(), context);
}
@@ -163,10 +172,11 @@
// perform silent creation and manual shutdown
registration
atomic.init();
//if (atomic.isDestroyable()) {
- destroyableContexts.add(atomic);
//}
}
}
+ context.addListener(this);
+ destroyableContexts.add(context);
}
}
}
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/RequestScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -18,33 +18,33 @@
import org.apache.tuscany.core.builder.ContextFactory;
import org.apache.tuscany.core.context.Context;
+import org.apache.tuscany.core.context.CoreRuntimeException;
import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
import org.apache.tuscany.core.context.AtomicContext;
-import org.apache.tuscany.core.context.CoreRuntimeException;
-import org.apache.tuscany.core.context.event.RequestEndEvent;
+import org.apache.tuscany.core.context.TargetException;
import org.apache.tuscany.core.context.event.ContextCreatedEvent;
import org.apache.tuscany.core.context.event.Event;
-import org.apache.tuscany.core.context.event.HttpSessionEvent;
+import org.apache.tuscany.core.context.event.RequestEndEvent;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
-import java.util.Queue;
+import java.util.ListIterator;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
/**
* An implementation of a request-scoped component container.
*
* @version $Rev$ $Date$
*/
-public class RequestScopeContext extends AbstractScopeContext implements
RuntimeEventListener {
+public class RequestScopeContext extends AbstractScopeContext {
// A collection of service component contexts keyed by thread. Note this
could have been implemented with a ThreadLocal but
// using a Map allows finer-grained concurrency.
- private Map<Object, Map<String, Context>> contextMap;
+ private Map<Object, Map<String, Context>> contexts;
// stores ordered lists of contexts to shutdown for each thread.
- private Map<Object, Queue<AtomicContext>> destroyComponents;
+ private Map<Object, List<Context>> destroyQueues;
public RequestScopeContext(EventContext eventContext) {
super(eventContext);
@@ -54,40 +54,34 @@
public void onEvent(Event event){
/* clean up current context for pooled threads */
if (event instanceof RequestEndEvent){
- checkInit();
- getEventContext().clearIdentifiers();
- notifyInstanceShutdown(Thread.currentThread());
- destroyContext();
+ checkInit();
+ getEventContext().clearIdentifiers();
+ shutdownContexts();
+ cleanupRequestContexts();
}else if (event instanceof ContextCreatedEvent){
- checkInit();
- assert(event.getSource() instanceof Context): "Context must be
passed on created event";
- Context context = (Context)event.getSource();
- if (context instanceof AtomicContext) {
- AtomicContext atomic = (AtomicContext)context;
- // Queue the context to have its implementation instance
released if destroyable
- //if (atomic.isDestroyable()) {
- Queue<AtomicContext> collection =
destroyComponents.get(Thread.currentThread());
- collection.add(atomic);
- //}
- }
+ checkInit();
+ assert(event.getSource() instanceof Context): "Context must be
passed on created event";
+ Context context = (Context)event.getSource();
+ List<Context> collection =
destroyQueues.get(Thread.currentThread());
+ collection.add(context);
}
}
+
public synchronized void start() {
if (lifecycleState != UNINITIALIZED) {
throw new IllegalStateException("Scope must be in UNINITIALIZED
state [" + lifecycleState + "]");
}
- contextMap = new ConcurrentHashMap<Object, Map<String, Context>>();
- destroyComponents = new ConcurrentHashMap<Object,
Queue<AtomicContext>>();
+ contexts = new ConcurrentHashMap<Object, Map<String, Context>>();
+ destroyQueues = new ConcurrentHashMap<Object, List<Context>>();
lifecycleState = RUNNING;
-
}
public synchronized void stop() {
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope in wrong state [" +
lifecycleState + "]");
}
- contextMap = null;
- destroyComponents = null;
+ contexts = null;
+ destroyQueues = null;
lifecycleState = STOPPED;
}
@@ -96,19 +90,19 @@
}
public void registerFactory(ContextFactory<Context> configuration) {
- contextFactorys.put(configuration.getName(), configuration);
+ contextFactories.put(configuration.getName(), configuration);
}
public Context getContext(String ctxName) {
checkInit();
- Map<String, Context> contexts = getComponentContexts();
+ Map<String, Context> contexts = getContexts();
Context ctx = contexts.get(ctxName);
if (ctx == null){
// check to see if the configuration was added after the request
was started
- ContextFactory<Context> configuration =
contextFactorys.get(ctxName);
+ ContextFactory<Context> configuration =
contextFactories.get(ctxName);
if (configuration != null) {
ctx = configuration.createContext();
- ctx.addListener(this);
+ //ctx.addListener(this);
ctx.start();
contexts.put(ctx.getName(), ctx);
}
@@ -121,7 +115,7 @@
if (key == null) {
return null;
}
- Map<String, Context> components = contextMap.get(key);
+ Map<String, Context> components = contexts.get(key);
if (components == null) {
return null;
}
@@ -129,7 +123,6 @@
}
public void removeContext(String ctxName) {
- checkInit();
removeContextByKey(ctxName, Thread.currentThread());
}
@@ -138,37 +131,24 @@
if (key == null || ctxName == null) {
return;
}
- Map components = contextMap.get(key);
+ Map components = contexts.get(key);
if (components == null) {
return;
}
components.remove(ctxName);
- Map<String, Context> contexts = contextMap.get(key);
+ //Map<String, Context> contexts = contexts.get(key);
// no synchronization for the following two operations since the
request
// context will not be shutdown before the second call is processed
- Context context = contexts.get(ctxName);
- destroyComponents.get(key).remove(context);
+ //Context context = contexts.get(ctxName);
+ //destroyQueues.get(key).remove(context);
}
- /**
- * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing
components that need to be notified of scope shutdown.
- */
- protected Context[] getShutdownContexts(Object key) {
- checkInit();
- Queue<AtomicContext> queue =
destroyComponents.get(Thread.currentThread());
- if (queue != null) {
- // create 0-length array since Queue.size() has O(n) traversal
- return queue.toArray(new Context[0]);
- } else {
- return null;
- }
- }
- private void destroyContext() {
+ private void cleanupRequestContexts() {
// TODO uninitialize all request-scoped components
- contextMap.remove(Thread.currentThread());
- destroyComponents.remove(Thread.currentThread());
+ contexts.remove(Thread.currentThread());
+ destroyQueues.remove(Thread.currentThread());
}
/**
@@ -180,21 +160,47 @@
* TODO Eager initialization is not performed for request-scoped components
*/
- private Map<String, Context> getComponentContexts() throws
CoreRuntimeException {
- Map<String, Context> contexts =
contextMap.get(Thread.currentThread());
+ private Map<String, Context> getContexts() throws CoreRuntimeException {
+ Map<String, Context> contexts =
this.contexts.get(Thread.currentThread());
if (contexts == null) {
contexts = new ConcurrentHashMap<String, Context>();
- Queue<AtomicContext> shutdownQueue = new
ConcurrentLinkedQueue<AtomicContext>();
- for (ContextFactory<Context> config : contextFactorys.values()) {
+ List<Context> shutdownQueue = new ArrayList<Context>();
+ for (ContextFactory<Context> config : contextFactories.values()) {
Context context = config.createContext();
- context.addListener(this);
context.start();
contexts.put(context.getName(), context);
+ context.addListener(this);
}
- contextMap.put(Thread.currentThread(), contexts);
- destroyComponents.put(Thread.currentThread(), shutdownQueue);
+ this.contexts.put(Thread.currentThread(), contexts);
+ destroyQueues.put(Thread.currentThread(), shutdownQueue);
}
return contexts;
}
+
+ private synchronized void shutdownContexts() {
+ List<Context> contexts = destroyQueues.get(Thread.currentThread());
+ if (contexts == null || contexts.size() == 0) {
+ return;
+ }
+ // shutdown destroyable instances in reverse instantiation order
+ ListIterator<Context> iter = contexts.listIterator(contexts.size());
+ while(iter.hasPrevious()){
+ Context context = iter.previous();
+ if (context.getLifecycleState() == RUNNING) {
+ synchronized (context) {
+ //removeContextByKey(context.getName(), key);
+ try {
+ if (context instanceof AtomicContext){
+ ((AtomicContext)context).destroy();
+ }
+ context.stop();
+ } catch (TargetException e) {
+ // TODO send a monitoring event
+ // log.error("Error releasing instance [" +
context.getName() + "]",e);
+ }
+ }
+ }
+ }
+ }
}
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/SessionScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -21,17 +21,18 @@
import org.apache.tuscany.core.context.Context;
import org.apache.tuscany.core.context.CoreRuntimeException;
import org.apache.tuscany.core.context.EventContext;
-import org.apache.tuscany.core.context.RuntimeEventListener;
import org.apache.tuscany.core.context.ScopeRuntimeException;
+import org.apache.tuscany.core.context.TargetException;
import org.apache.tuscany.core.context.event.ContextCreatedEvent;
import org.apache.tuscany.core.context.event.Event;
import org.apache.tuscany.core.context.event.HttpSessionEvent;
import org.apache.tuscany.core.context.event.SessionEndEvent;
import java.util.Map;
-import java.util.Queue;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
/**
* An implementation of an session-scoped component container
@@ -40,13 +41,13 @@
*
* @version $Rev$ $Date$
*/
-public class SessionScopeContext extends AbstractScopeContext implements
RuntimeEventListener {
+public class SessionScopeContext extends AbstractScopeContext {
// The collection of service component contexts keyed by session
private Map<Object, Map<String, Context>> contexts;
// Stores ordered lists of contexts to shutdown keyed by session
- private Map<Object, Queue<AtomicContext>> destroyableContexts;
+ private Map<Object, List<Context>> destroyQueues;
public SessionScopeContext(EventContext eventContext) {
super(eventContext);
@@ -58,7 +59,7 @@
throw new IllegalStateException("Scope container must be in
UNINITIALIZED state");
}
contexts = new ConcurrentHashMap<Object, Map<String, Context>>();
- destroyableContexts = new ConcurrentHashMap<Object,
Queue<AtomicContext>>();
+ destroyQueues = new ConcurrentHashMap<Object, List<Context>>();
lifecycleState = RUNNING;
}
@@ -68,7 +69,7 @@
}
contexts = null;
contexts = null;
- destroyableContexts = null;
+ destroyQueues = null;
lifecycleState = STOPPED;
}
@@ -76,24 +77,27 @@
if (event instanceof SessionEndEvent){
checkInit();
Object key = ((SessionEndEvent)event).getId();
- notifyInstanceShutdown(key);
+ shutdownContexts(key);
destroyComponentContext(key);
}else if(event instanceof ContextCreatedEvent){
checkInit();
- if (event.getSource() instanceof AtomicContext) {
- AtomicContext simpleCtx = (AtomicContext)event.getSource();
- // if destroyable, queue the context to have its component
implementation instance released
- if (simpleCtx.isDestroyable()) {
- Object sessionKey =
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
- Queue<AtomicContext> comps =
destroyableContexts.get(sessionKey);
- if (comps == null) {
- ScopeRuntimeException e = new
ScopeRuntimeException("Shutdown queue not found for key");
- e.setIdentifier(sessionKey.toString());
- throw e;
- }
- comps.add(simpleCtx);
- }
- }
+ Object sessionKey =
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
+ List<Context> contexts = destroyQueues.get(sessionKey);
+ Context context = (Context)event.getSource();
+ assert(contexts != null): "Shutdown queue not found for key";
+
+// if (context instanceof AtomicContext) {
+// AtomicContext atomic = (AtomicContext)event.getSource();
+// // if destroyable, queue the context to have its component
implementation instance released
+// if (atomic.isDestroyable()) {
+// if (contexts == null) {
+// ScopeRuntimeException e = new
ScopeRuntimeException("Shutdown queue not found for key");
+// e.setIdentifier(sessionKey.toString());
+// throw e;
+// }
+// }
+// }
+ contexts.add(context);
}
}
@@ -102,43 +106,44 @@
}
public void registerFactory(ContextFactory<Context> configuration) {
- contextFactorys.put(configuration.getName(), configuration);
+ contextFactories.put(configuration.getName(), configuration);
}
public Context getContext(String ctxName) {
+ assert(ctxName != null): "No context name specified";
checkInit();
- if (ctxName == null) {
- return null;
- }
- // try{
- Map<String, Context> ctxs = getSessionContext();
- if (ctxs == null) {
- return null;
- }
- Context ctx = ctxs.get(ctxName);
- if (ctx == null) {
+ Map<String, Context> ctxs = getSessionContexts();
+ Context context = ctxs.get(ctxName);
+ if (context == null) {
// the configuration was added after the session had started, so
create a context now and start it
- ContextFactory<Context> configuration =
contextFactorys.get(ctxName);
+ ContextFactory<Context> configuration =
contextFactories.get(ctxName);
if (configuration != null) {
- ctx = configuration.createContext();
- ctx.addListener(this);
- ctx.start();
- ctxs.put(ctx.getName(), ctx);
+ context = configuration.createContext();
+ context.start();
+ if (context instanceof AtomicContext){
+ ((AtomicContext)context).init();
+ }
+
+ ctxs.put(context.getName(), context);
+ List<Context> shutdownQueue =
destroyQueues.get(getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER));
+ synchronized(shutdownQueue){
+ shutdownQueue.add(context);
+ }
+ context.addListener(this);
}
}
- return ctx;
+ return context;
}
public Context getContextByKey(String ctxName, Object key) {
checkInit();
- if (key == null && ctxName == null) {
- return null;
- }
- Map components = contexts.get(key);
- if (components == null) {
+ assert(ctxName != null): "No context name specified";
+ assert(key != null): "No key specified";
+ Map ctxs = contexts.get(key);
+ if (ctxs == null) {
return null;
}
- return (Context) components.get(ctxName);
+ return (Context) ctxs.get(ctxName);
}
public void removeContext(String ctxName) {
@@ -149,9 +154,8 @@
public void removeContextByKey(String ctxName, Object key) {
checkInit();
- if (key == null || ctxName == null) {
- return;
- }
+ assert(ctxName != null): "No context name specified";
+ assert(key != null): "No key specified";
Map components = contexts.get(key);
if (components == null) {
return;
@@ -160,33 +164,15 @@
Map<String, Context> definitions = contexts.get(key);
Context ctx = definitions.get(ctxName);
if (ctx != null){
- destroyableContexts.get(key).remove(ctx);
+ destroyQueues.get(key).remove(ctx);
}
definitions.remove(ctxName);
}
-
- /**
- * Returns an array of [EMAIL PROTECTED] AtomicContext}s representing
components that need to be notified of scope shutdown or
- * null if none found.
- */
- protected Context[] getShutdownContexts(Object key) {
- /*
- * This method will be called from the Listener which is associated
with a different thread than the request. So, just
- * grab the key directly
- */
- Queue<AtomicContext> queue = destroyableContexts.get(key);
- if (queue != null) {
- // create 0-length array since Queue.size() has O(n) traversal
- return queue.toArray(new AtomicContext[0]);
- }
- return null;
- }
-
/**
* Returns and, if necessary, creates a context for the current sesion
*/
- private Map<String, Context> getSessionContext() throws
CoreRuntimeException {
+ private Map<String, Context> getSessionContexts() throws
CoreRuntimeException {
Object key =
getEventContext().getIdentifier(HttpSessionEvent.HTTP_IDENTIFIER);
if (key == null) {
throw new ScopeRuntimeException("Session key not set in request
context");
@@ -195,29 +181,29 @@
if (m != null) {
return m; // already created, return
}
- Map<String, Context> sessionContext = new ConcurrentHashMap<String,
Context>(contextFactorys.size());
- for (ContextFactory<Context> config : contextFactorys.values()) {
+ Map<String, Context> sessionContext = new ConcurrentHashMap<String,
Context>(contextFactories.size());
+ for (ContextFactory<Context> config : contextFactories.values()) {
Context context = config.createContext();
- context.addListener(this);
context.start();
sessionContext.put(context.getName(), context);
}
- Queue<AtomicContext> shutdownQueue = new
ConcurrentLinkedQueue<AtomicContext>();
+ List<Context> shutdownQueue = new ArrayList<Context>();
contexts.put(key, sessionContext);
- destroyableContexts.put(key, shutdownQueue);
+ destroyQueues.put(key, shutdownQueue);
// initialize eager components. Note this cannot be done when we
initially create each context since a component may
// contain a forward reference to a component which has not been
instantiated
for (Context context : sessionContext.values()) {
if (context instanceof AtomicContext) {
AtomicContext atomic = (AtomicContext) context;
if (atomic.isEagerInit()) {
- context.notify(); // Notify the instance
- //if (atomic.isDestroyable()) {
- shutdownQueue.add(atomic);
- //}
+ atomic.init(); // Notify the instance
+ synchronized(shutdownQueue){
+ shutdownQueue.add(context);
+ }
}
}
+ context.addListener(this);
}
return sessionContext;
}
@@ -227,7 +213,33 @@
*/
private void destroyComponentContext(Object key) {
contexts.remove(key);
- destroyableContexts.remove(key);
+ destroyQueues.remove(key);
+ }
+
+
+ private synchronized void shutdownContexts(Object key) {
+ List<Context> contexts = destroyQueues.get(key);
+ if (contexts == null || contexts.size() == 0) {
+ return;
+ }
+ // shutdown destroyable instances in reverse instantiation order
+ ListIterator<Context> iter = contexts.listIterator(contexts.size());
+ while(iter.hasPrevious()){
+ Context context = iter.previous();
+ if (context.getLifecycleState() == RUNNING) {
+ //removeContextByKey(context.getName(), key);
+ try {
+ if (context instanceof AtomicContext){
+ System.out.println(":"+context.getName());
+ ((AtomicContext)context).destroy();
+ }
+ context.stop();
+ } catch (TargetException e) {
+ // TODO send a monitoring event
+ // log.error("Error releasing instance [" +
context.getName() + "]",e);
+ }
+ }
+ }
}
}
Modified:
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
URL:
http://svn.apache.org/viewcvs/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java?rev=393986&r1=393985&r2=393986&view=diff
==============================================================================
---
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
(original)
+++
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/context/scope/StatelessScopeContext.java
Thu Apr 13 17:18:23 2006
@@ -19,7 +19,6 @@
import org.apache.tuscany.core.builder.ContextFactory;
import org.apache.tuscany.core.context.EventContext;
import org.apache.tuscany.core.context.Context;
-import org.apache.tuscany.core.context.RuntimeEventListener;
import org.apache.tuscany.core.context.CoreRuntimeException;
import org.apache.tuscany.core.context.event.Event;
@@ -31,10 +30,10 @@
*
* @version $Rev$ $Date$
*/
-public class StatelessScopeContext extends AbstractScopeContext implements
RuntimeEventListener {
+public class StatelessScopeContext extends AbstractScopeContext {
// Component contexts keyed by name
- private Map<String, Context> contextMap;
+ private Map<String, Context> contexts;
public StatelessScopeContext(EventContext eventContext) {
super(eventContext);
@@ -46,23 +45,21 @@
throw new IllegalStateException("Scope must be in UNINITIALIZED
state [" + lifecycleState + "]");
}
lifecycleState = RUNNING;
- prepare();
}
public synchronized void stop() {
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope in wrong state [" +
lifecycleState + "]");
}
- contextMap = null;
+ contexts = null;
lifecycleState = STOPPED;
}
public void registerFactory(ContextFactory<Context> configuration) {
- contextFactorys.put(configuration.getName(), configuration);
- if (lifecycleState == RUNNING) {
- contextMap.put(configuration.getName(),
configuration.createContext());
+ contextFactories.put(configuration.getName(), configuration);
+ if (contexts != null) {
+ contexts.put(configuration.getName(),
configuration.createContext());
}
-
}
public void onEvent(Event event){
@@ -74,7 +71,8 @@
}
public Context getContext(String ctxName) {
- return contextMap.get(ctxName);
+ prepare();
+ return contexts.get(ctxName);
}
public Context getContextByKey(String ctxName, Object key) {
@@ -82,32 +80,27 @@
}
public void removeContext(String ctxName) {
- removeContextByKey(ctxName, null);
+ if (contexts == null){
+ return;
+ }
+ contexts.remove(ctxName);
}
public void removeContextByKey(String ctxName, Object key) {
- contextMap.remove(ctxName);
- }
-
- /**
- * Always returns null since stateless components cannot be shutdown
- */
- protected Context[] getShutdownContexts(Object key) {
- return null;
+ removeContext(ctxName);
}
private void prepare() throws CoreRuntimeException {
if (lifecycleState != RUNNING) {
throw new IllegalStateException("Scope not in INITIALIZED state ["
+ lifecycleState + "]");
}
- if (contextMap == null) {
- contextMap = new ConcurrentHashMap<String, Context> ();
- for (ContextFactory<Context> config : contextFactorys.values()) {
- for (int i = 0; i < contextFactorys.size(); i++) {
+ if (contexts == null) {
+ contexts = new ConcurrentHashMap<String, Context> ();
+ for (ContextFactory<Context> config : contextFactories.values()) {
+ for (int i = 0; i < contextFactories.size(); i++) {
Context context = config.createContext();
- context.addListener(this);
context.start();
- contextMap.put(context.getName(), context);
+ contexts.put(context.getName(), context);
}
}