commit d51a245e7720627f790d22e7c8f85b3337ca09e4
Author: Radoslav Husar <radosoft@gmail.com>
Date:   Wed Feb 3 12:33:11 2016 +0100

    WFLY-6128 CommandDispatcher throws "TimeoutException: timeout sending message to A" when all responses are NoSuchService

diff --git a/clustering/api/src/main/java/org/wildfly/clustering/dispatcher/NoSuchServiceException.java b/clustering/api/src/main/java/org/wildfly/clustering/dispatcher/NoSuchServiceException.java
new file mode 100644
index 0000000..d738665
--- /dev/null
+++ b/clustering/api/src/main/java/org/wildfly/clustering/dispatcher/NoSuchServiceException.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2016, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.wildfly.clustering.dispatcher;
+
+/**
+ * Exception that indicates that no corresponding service is running on the target node.
+ * This could indicate that service has not been started yet.
+ *
+ * @author Radoslav Husar
+ * @version Feb 2016
+ */
+public class NoSuchServiceException extends Exception {
+}
diff --git a/clustering/server/src/main/java/org/wildfly/clustering/server/dispatcher/ChannelCommandDispatcher.java b/clustering/server/src/main/java/org/wildfly/clustering/server/dispatcher/ChannelCommandDispatcher.java
index 61ddf76..cb8cebe 100644
--- a/clustering/server/src/main/java/org/wildfly/clustering/server/dispatcher/ChannelCommandDispatcher.java
+++ b/clustering/server/src/main/java/org/wildfly/clustering/server/dispatcher/ChannelCommandDispatcher.java
@@ -38,11 +38,11 @@ import org.jgroups.Message;
 import org.jgroups.blocks.MessageDispatcher;
 import org.jgroups.blocks.RequestOptions;
 import org.jgroups.blocks.ResponseMode;
-import org.jgroups.blocks.RspFilter;
 import org.jgroups.util.Rsp;
 import org.wildfly.clustering.dispatcher.Command;
 import org.wildfly.clustering.dispatcher.CommandDispatcher;
 import org.wildfly.clustering.dispatcher.CommandResponse;
+import org.wildfly.clustering.dispatcher.NoSuchServiceException;
 import org.wildfly.clustering.group.Node;
 import org.wildfly.clustering.group.NodeFactory;
 import org.wildfly.clustering.server.Addressable;
@@ -55,18 +55,6 @@ import org.wildfly.clustering.server.Addressable;
  */
 public abstract class ChannelCommandDispatcher<C> implements CommandDispatcher<C> {
 
-    private static final RspFilter FILTER = new RspFilter() {
-        @Override
-        public boolean isAcceptable(Object response, Address sender) {
-            return !(response instanceof NoSuchService);
-        }
-
-        @Override
-        public boolean needMoreResponses() {
-            return true;
-        }
-    };
-
     private final MessageDispatcher dispatcher;
     private final CommandMarshaller<C> marshaller;
     private final NodeFactory<Address> factory;
@@ -148,7 +136,11 @@ public abstract class ChannelCommandDispatcher<C> implements CommandDispatcher<C
         // Use sendMessageWithFuture(...) instead of sendMessage(...) since we want to differentiate between sender exceptions and receiver exceptions
         Future<R> future = this.dispatcher.sendMessageWithFuture(this.createMessage(command, node), this.createRequestOptions());
         try {
-            return new SimpleCommandResponse<>(future.get());
+            R response = future.get();
+            if (response instanceof NoSuchService) {
+                return new SimpleCommandResponse<>(new NoSuchServiceException());
+            }
+            return new SimpleCommandResponse<>(response);
         } catch (InterruptedException e) {
             return new SimpleCommandResponse<>(e);
         } catch (ExecutionException e) {
@@ -198,11 +190,14 @@ public abstract class ChannelCommandDispatcher<C> implements CommandDispatcher<C
     }
 
     private RequestOptions createRequestOptions() {
-        return new RequestOptions(ResponseMode.GET_ALL, this.timeout, false, FILTER, Message.Flag.DONT_BUNDLE, Message.Flag.OOB);
+        return new RequestOptions(ResponseMode.GET_ALL, this.timeout, false, null, Message.Flag.DONT_BUNDLE, Message.Flag.OOB);
     }
 
     static <R> CommandResponse<R> createCommandResponse(Rsp<R> response) {
         Throwable exception = response.getException();
+        if (response.getValue() instanceof NoSuchService) {
+            exception = new NoSuchServiceException();
+        }
         return (exception != null) ? new SimpleCommandResponse<>(exception) : new SimpleCommandResponse<>(response.getValue());
     }
 
diff --git a/clustering/web/infinispan/src/main/java/org/wildfly/clustering/web/infinispan/session/InfinispanSessionManager.java b/clustering/web/infinispan/src/main/java/org/wildfly/clustering/web/infinispan/session/InfinispanSessionManager.java
index a292820..d5cee8f 100644
--- a/clustering/web/infinispan/src/main/java/org/wildfly/clustering/web/infinispan/session/InfinispanSessionManager.java
+++ b/clustering/web/infinispan/src/main/java/org/wildfly/clustering/web/infinispan/session/InfinispanSessionManager.java
@@ -54,6 +54,7 @@ import org.infinispan.remoting.transport.Address;
 import org.wildfly.clustering.dispatcher.Command;
 import org.wildfly.clustering.dispatcher.CommandDispatcher;
 import org.wildfly.clustering.dispatcher.CommandDispatcherFactory;
+import org.wildfly.clustering.dispatcher.NoSuchServiceException;
 import org.wildfly.clustering.ee.Batch;
 import org.wildfly.clustering.ee.Batcher;
 import org.wildfly.clustering.ee.Invoker;
@@ -192,11 +193,15 @@ public class InfinispanSessionManager<MV, AV, L> implements SessionManager<L, Tr
     }
 
     private void executeOnPrimaryOwner(final String sessionId, final Command<Void, Scheduler> command) throws Exception {
-        this.invoker.invoke(() -> {
-            // This should only go remote following a failover
-            Node node = this.locatePrimaryOwner(sessionId);
-            return this.dispatcher.executeOnNode(command, node);
-        }).get();
+        try {
+            this.invoker.invoke(() -> {
+                // This should only go remote following a failover
+                Node node = this.locatePrimaryOwner(sessionId);
+                return this.dispatcher.executeOnNode(command, node);
+            }).get();
+        } catch (NoSuchServiceException ignore) {
+            // Ignore, we will schedule on next access.
+        }
     }
 
     private Node locatePrimaryOwner(String sessionId) {
