com.gemstone.gemfire.internal.admin.remote.AdminReplyProcessor Maven / Gradle / Ivy
Show all versions of gemfire-core Show documentation
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.internal.admin.remote;
import com.gemstone.gemfire.distributed.internal.*;
import com.gemstone.gemfire.distributed.internal.membership.*;
/**
* A ReplyProcessor
that is used by an {@link
* AdminRequest} to wait for an {@link AdminResponse}. If
* {@link com.gemstone.gemfire.distributed.internal.ReplyProcessor21#waitForReplies()}
* returns saying that we didn't time out and there
* is no response, it means that the member for which we were awaiting
* a response has left the distributed system. This helps us fix bug
* 31562.
*
*
*
* An AdminReplyProcessor
can be {@linkplain #cancel
* cancelled}.
*
* @author David Whitlock
* @since 4.0
*/
class AdminReplyProcessor extends ReplyProcessor21 {
/** The response to the AdminRequest
. */
private volatile AdminResponse response;
/** The thread that is waiting for replies. We need this thread so
* that we can interrupt it when this processor is cancelled. */
private volatile Thread thread;
/** Has this reply processor been cancelled? */
private volatile boolean isCancelled;
/** The member from whom we expect a response */
private final InternalDistributedMember responder;
////////////////////// Constructors //////////////////////
/**
* Creates a new AdminReplyProcessor
that waits for a
* reply from the given member of the distributed system. Note that
* AdminRequest
s are only sent to one member of the
* distributed system.
*/
AdminReplyProcessor(InternalDistributedSystem system,
InternalDistributedMember member) {
super(system, member);
this.isCancelled = false;
this.responder = member;
}
////////////////////// Instance Methods //////////////////////
/**
* Keep track of the AdminResponse
we received.
*/
@Override
public void process(DistributionMessage message) {
try {
this.response = (AdminResponse) message;
} finally {
super.process(message);
}
}
/**
* Since we can't override waitForReplies
, we have to
* get the thread that is waiting in preWait
.
*/
@Override
protected void preWait() {
this.thread = Thread.currentThread();
super.preWait();
}
/**
* "Cancels" this reply processor by instructing the thread that is
* waiting for replies that it shouldn't wait any more.
*/
public void cancel() {
this.isCancelled = true;
if (this.thread != null) {
this.thread.interrupt();
}
}
/**
* If we are interrupted after we are cancelled, return
* true
indicating that there is a "response". That
* way, we won't complain about timing out. However, the response
* is still null
.
*
*
*
* Otherwise, re-throw the InterruptedException
.
*/
protected boolean handleInterruption(InterruptedException ie,
long msecsRemaining)
throws InterruptedException, ReplyException {
if (Thread.interrupted()) throw new InterruptedException();
if (this.isCancelled) {
return true;
} else {
throw ie;
}
}
/**
* Returns the response that this processor has been waiting for.
* If this method returns null
and
* waitForReplies
return true
, it means
* that the request was cancelled. If this method returns
* null
and waitForReplies
return
* false
, it means that waitForReplies
* timed out.
*/
public AdminResponse getResponse() {
return this.response;
}
/**
* Returns the member who we are waiting to send us a response.
*/
public InternalDistributedMember getResponder() {
return this.responder;
}
}