Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=46223
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 29 Dec 2008 00:30:00 +0000 (00:30 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 29 Dec 2008 00:30:00 +0000 (00:30 +0000)
Add a simple co-ordinator provided by Robert Newson

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@729815 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/tribes/group/interceptors/SimpleCoordinator.java [new file with mode: 0644]
webapps/docs/config/cluster-interceptor.xml

diff --git a/java/org/apache/catalina/tribes/group/interceptors/SimpleCoordinator.java b/java/org/apache/catalina/tribes/group/interceptors/SimpleCoordinator.java
new file mode 100644 (file)
index 0000000..69fdb5c
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ */\r
+package org.apache.catalina.tribes.group.interceptors;\r
+\r
+import static java.util.concurrent.TimeUnit.MILLISECONDS;\r
+\r
+import java.util.Arrays;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import org.apache.catalina.tribes.ChannelException;\r
+import org.apache.catalina.tribes.Member;\r
+import org.apache.catalina.tribes.group.AbsoluteOrder;\r
+import org.apache.catalina.tribes.group.ChannelInterceptorBase;\r
+\r
+/**\r
+ * A dinky coordinator, just uses a sorted version of the member array.\r
+ * \r
+ * @author rnewson\r
+ * \r
+ */\r
+public class SimpleCoordinator extends ChannelInterceptorBase {\r
+\r
+    private Member[] view;\r
+\r
+    private AtomicBoolean membershipChanged = new AtomicBoolean();\r
+\r
+    private void membershipChanged() {\r
+        membershipChanged.set(true);\r
+    }\r
+\r
+    @Override\r
+    public void memberAdded(final Member member) {\r
+        super.memberAdded(member);\r
+        membershipChanged();\r
+        installViewWhenStable();\r
+    }\r
+\r
+    @Override\r
+    public void memberDisappeared(final Member member) {\r
+        super.memberDisappeared(member);\r
+        membershipChanged();\r
+        installViewWhenStable();\r
+    }\r
+\r
+    /**\r
+     * Override to receive view changes.\r
+     * \r
+     * @param view\r
+     */\r
+    protected void viewChange(final Member[] view) {\r
+    }\r
+\r
+    @Override\r
+    public void start(int svc) throws ChannelException {\r
+        super.start(svc);\r
+        installViewWhenStable();\r
+    }\r
+\r
+    private void installViewWhenStable() {\r
+        int stableCount = 0;\r
+\r
+        while (stableCount < 10) {\r
+            if (membershipChanged.compareAndSet(true, false)) {\r
+                stableCount = 0;\r
+            } else {\r
+                stableCount++;\r
+            }\r
+            try {\r
+                MILLISECONDS.sleep(250);\r
+            } catch (final InterruptedException e) {\r
+                Thread.currentThread().interrupt();\r
+            }\r
+        }\r
+\r
+        final Member[] members = getMembers();\r
+        final Member[] view = Arrays.copyOf(members, members.length + 1);\r
+        view[members.length] = getLocalMember(false);\r
+        Arrays.sort(view, AbsoluteOrder.comp);\r
+        if (Arrays.equals(view, this.view)) {\r
+            return;\r
+        }\r
+        this.view = view;\r
+        viewChange(view);\r
+    }\r
+\r
+    @Override\r
+    public void stop(int svc) throws ChannelException {\r
+        super.stop(svc);\r
+    }\r
+\r
+    public Member[] getView() {\r
+        return view;\r
+    }\r
+\r
+    public Member getCoordinator() {\r
+        return view == null ? null : view[0];\r
+    }\r
+\r
+    public boolean isCoordinator() {\r
+        return view == null ? false : getLocalMember(false).equals(\r
+                getCoordinator());\r
+    }\r
+\r
+}\r
index 59e299a..b6db4a6 100644 (file)
@@ -46,6 +46,7 @@
     <li><code>org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor</code></li>
     <li><code>org.apache.catalina.tribes.group.interceptors.NonBlockingCoordinator</code></li>
     <li><code>org.apache.catalina.tribes.group.interceptors.OrderInterceptor</code></li>
+    <li><code>org.apache.catalina.tribes.group.interceptors.SimpleCoordinator</code></li>
     <li><code>org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor</code></li>
     <li><code>org.apache.catalina.tribes.group.interceptors.TwoPhaseCommitInterceptor</code></li>
     <li><code>org.apache.catalina.tribes.group.interceptors.DomainFilterInterceptor</code></li>