servicemix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r946973 - in /servicemix/components/shared-libraries/trunk/servicemix-common/src: main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java
Date Fri, 21 May 2010 11:37:27 GMT
Author: gertv
Date: Fri May 21 11:37:27 2010
New Revision: 946973

URL: http://svn.apache.org/viewvc?rev=946973&view=rev
Log:
SMXCOMP-749: Add a timeout to the prepareShutdown() method to avoid waiting forever

Added:
    servicemix/components/shared-libraries/trunk/servicemix-common/src/test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java
Modified:
    servicemix/components/shared-libraries/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java

Modified: servicemix/components/shared-libraries/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java
URL: http://svn.apache.org/viewvc/servicemix/components/shared-libraries/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java?rev=946973&r1=946972&r2=946973&view=diff
==============================================================================
--- servicemix/components/shared-libraries/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java
(original)
+++ servicemix/components/shared-libraries/trunk/servicemix-common/src/main/java/org/apache/servicemix/common/AsyncBaseLifeCycle.java
Fri May 21 11:37:27 2010
@@ -677,14 +677,34 @@ public class AsyncBaseLifeCycle implemen
         }
     }
 
+    /**
+     * Prepare an endpoint for shutdown by waiting until all its pending exchanges have been
finished.
+     *
+     * @param endpoint the endpoint that is about to be shut down
+     * @throws InterruptedException
+     */
     public void prepareShutdown(Endpoint endpoint) throws InterruptedException {
+        prepareShutdown(endpoint, 0);
+    }
+
+    /**
+     * Prepare an endpoint for shutdown by waiting until all its pending exchanges have been
finished.
+     * This method will wait no longer than the timeout specified (in milliseconds)
+     *
+     * @param endpoint the endpoint that is about to be shut down
+     * @param timeout the maximum amount of time (in milliseconds) to wait
+     * @throws InterruptedException
+     */
+    public void prepareShutdown(Endpoint endpoint, long timeout) throws InterruptedException
{
         Set<String> exchanges = getKnownExchanges(endpoint);
         synchronized (exchanges) {
             if (!exchanges.isEmpty()) {
                 for (String id : exchanges) {
                     logger.debug("Waiting for exchange " + id + " in " + endpoint);
                 }
-                exchanges.wait();
+                exchanges.wait(timeout);
+                logger.debug(String.format("Gave up waiting for %s exchanges in %s after
%s ms",
+                                           exchanges.size(), endpoint, timeout));
             }
         }
     }

Added: servicemix/components/shared-libraries/trunk/servicemix-common/src/test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java
URL: http://svn.apache.org/viewvc/servicemix/components/shared-libraries/trunk/servicemix-common/src/test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java?rev=946973&view=auto
==============================================================================
--- servicemix/components/shared-libraries/trunk/servicemix-common/src/test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java
(added)
+++ servicemix/components/shared-libraries/trunk/servicemix-common/src/test/java/org/apache/servicemix/common/AsyncBaseLifeCycleTest.java
Fri May 21 11:37:27 2010
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.common;
+
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+import org.apache.servicemix.common.endpoints.SimpleEndpoint;
+import org.apache.servicemix.tck.mock.MockMessageExchange;
+
+/**
+ * Test cases for {@link org.apache.servicemix.common.AsyncBaseLifeCycle}
+ */
+public class AsyncBaseLifeCycleTest extends TestCase {
+
+    private static final long TIMEOUT = 2000;
+
+    private AsyncBaseLifeCycle lifecycle;
+    private ExecutorService executor;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        lifecycle = new AsyncBaseLifeCycle();
+        lifecycle.setExecutorFactory(lifecycle.createExecutorFactory());
+        lifecycle.setComponent(new DefaultComponent());
+
+        executor = Executors.newSingleThreadExecutor();
+    }
+
+    public void testPrepareShutdown() throws InterruptedException {
+        final Endpoint endpoint = new MockEndpoint() ;
+
+        MockMessageExchange exchange = new MockMessageExchange();
+        exchange.setExchangeId(UUID.randomUUID().toString());
+
+        // adding a known exchange
+        lifecycle.handleExchange(endpoint, exchange, true);
+
+        final CountDownLatch done = new CountDownLatch(1);
+
+        executor.submit(new Callable() {
+
+            @Override
+            public Object call() throws Exception {
+                try {
+                    lifecycle.prepareShutdown(endpoint);
+                } finally {
+                    done.countDown();
+                }
+                return null;
+            }
+        });
+
+        assertFalse("Should be waiting for prepareShutdown to complete",
+                    done.await(1, TimeUnit.SECONDS));
+
+        lifecycle.handleExchange(endpoint, exchange, false);
+
+        assertTrue("prepareShutdown is now done", done.await(100, TimeUnit.SECONDS));
+    }
+
+    public void testPrepareShutdownWithTimeout() throws InterruptedException, ExecutionException,
TimeoutException {
+        final Endpoint endpoint = new MockEndpoint() ;
+
+        MockMessageExchange exchange = new MockMessageExchange();
+        exchange.setExchangeId(UUID.randomUUID().toString());
+
+        // adding a known exchange
+        lifecycle.handleExchange(endpoint, exchange, true);
+
+        final CountDownLatch done = new CountDownLatch(1);
+
+        Future<Long> time = executor.submit(new Callable<Long>() {
+
+            @Override
+            public Long call() throws Exception {
+                long start = System.currentTimeMillis();
+                lifecycle.prepareShutdown(endpoint, TIMEOUT);
+                return (System.currentTimeMillis() - start);
+            }
+        });
+
+        assertEquals("Should be waiting for prepareShutdown to complete",
+                     1, done.getCount());
+
+        Long shutdown = time.get(2 * TIMEOUT, TimeUnit.MILLISECONDS);
+
+        assertTrue("prepareShutdown should have timed out after " + TIMEOUT + "ms (was "
+ shutdown + "ms)",
+                   shutdown >= TIMEOUT);
+    }
+
+    public static class MockEndpoint extends SimpleEndpoint {
+
+        public MockEndpoint() {
+            super();
+            setService(new QName("urn:test", "service"));
+            setEndpoint("endpoint");
+        }
+
+        @Override
+        public MessageExchange.Role getRole() {
+            return null;
+        }
+
+        @Override
+        public void process(MessageExchange exchange) throws Exception {
+            // graciously do nothing
+        }
+    }
+}



Mime
View raw message