com.gemstone.gemfire.internal.cache.SendQueueOperation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
/*
* 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.cache;
import java.util.*;
import java.io.*;
import com.gemstone.gemfire.*;
import com.gemstone.gemfire.cache.*;
import com.gemstone.gemfire.distributed.*;
import com.gemstone.gemfire.distributed.internal.*;
/**
* Sends a chunk of queued messages to everyone currently playing a role.
*
* @author Darrel Schneider
* @since 5.0
*
*/
public class SendQueueOperation {
//private ReplyProcessor21 processor = null;
private final DM dm;
private final DistributedRegion r;
private final List l;
private final Role role;
SendQueueOperation(DM dm, DistributedRegion r, List l, Role role) {
this.dm = dm;
this.r = r;
this.l = l;
this.role = role;
}
/**
* Returns true if distribution successful. Also modifies message list by
* removing messages sent to the required role.
*/
boolean distribute() {
CacheDistributionAdvisor advisor = this.r.getCacheDistributionAdvisor();
Set recipients = advisor.adviseCacheOpRole(this.role);
if (recipients.isEmpty()) {
return false;
}
ReplyProcessor21 processor = new ReplyProcessor21(this.dm, recipients);
// @todo darrel: make this a reliable one
SendQueueMessage msg = new SendQueueMessage();
msg.setRecipients(recipients);
msg.setRegionPath(this.r.getFullPath());
msg.setProcessorId(processor.getProcessorId());
msg.setOperations(this.l);
dm.putOutgoing(msg);
try {
processor.waitForReplies();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
// It's OK to keep going, no significant work below.
} catch (ReplyException ex) {
ex.handleAsUnexpected();
}
if (msg.getSuccessfulRecipients().isEmpty()) {
return false;
}
// @todo darrel: now remove sent items from the list
this.r.getCachePerfStats().incReliableQueuedOps(- l.size());
this.l.clear();
return true;
}
/**
* A batch of queued messages. Once they are processed on the other side
* an ack is sent.
*/
public static final class SendQueueMessage
extends SerialDistributionMessage
implements MessageWithReply
{
private int processorId;
private String regionPath;
/**
* List of QueuedOperation instances
*/
private List ops;
@Override
public int getProcessorId() {
return this.processorId;
}
public void setProcessorId(int id) {
this.processorId = id;
}
public String getRegionPath() {
return this.regionPath;
}
public void setRegionPath(String rp) {
this.regionPath = rp;
}
public void setOperations(List l) {
this.ops = l;
}
@Override
protected void process(DistributionManager dm) {
ReplyException rex = null;
boolean ignored = false;
try {
GemFireCacheImpl gfc = GemFireCacheImpl.getExisting();
final LocalRegion lclRgn = gfc.getRegionByPathForProcessing(this.regionPath);
if (lclRgn != null) {
lclRgn.waitOnInitialization();
final long lastMod = gfc.cacheTimeMillis();
Iterator it = this.ops.iterator();
while (it.hasNext()) {
QueuedOperation op = (QueuedOperation)it.next();
op.process(lclRgn, getSender(), lastMod);
}
} else {
ignored = true;
}
} catch (RegionDestroyedException e) {
ignored = true;
} catch (CancelException e) {
ignored = true;
} finally {
ReplyMessage.send(getSender(), this.processorId, rex, dm, ignored,
false, null, false);
}
}
public int getDSFID() {
return SEND_QUEUE_MESSAGE;
}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {
super.fromData(in);
this.regionPath = DataSerializer.readString(in);
this.processorId = in.readInt();
{
int opCount = in.readInt();
QueuedOperation[] ops = new QueuedOperation[opCount];
for (int i=0; i < opCount; i++) {
ops[i] = QueuedOperation.createFromData(in);
}
this.ops = Arrays.asList(ops);
}
}
@Override
public void toData(DataOutput out) throws IOException {
super.toData(out);
DataSerializer.writeString(this.regionPath, out);
out.writeInt(this.processorId);
{
int opCount = this.ops.size();
out.writeInt(opCount);
for (int i=0; i < opCount; i++) {
QueuedOperation op = (QueuedOperation)this.ops.get(i);
op.toData(out);
}
}
}
@Override
public String toString() {
StringBuffer buff = new StringBuffer();
buff.append(getClass().getName());
buff.append("(region path='"); // make sure this is the first one
buff.append(this.regionPath);
buff.append("'");
buff.append("; processorId=");
buff.append(this.processorId);
buff.append("; queuedOps=");
buff.append(this.ops.size());
buff.append(")");
return buff.toString();
}
}
}