/** * If my peer is responsible, I'll issue a put if absent to make sure all replicas are stored. * * @param locationKey The location key * @param domainKey The domain key * @param dataMapConverted The data to store * @return The future of the put */ protected FutureDone<?> send(final Number160 locationKey) { int replicationFactor = replication.replicationFactor() - 1; List<PeerAddress> closePeers = new ArrayList<PeerAddress>(); SortedSet<PeerStatistic> sortedSet = peer.peerBean().peerMap().closePeers(locationKey, replicationFactor); int count = 0; List<FutureDone<?>> retVal = new ArrayList<FutureDone<?>>(replicationFactor); for (PeerStatistic peerStatistic : sortedSet) { if (replication.rejectReplication(peerStatistic.peerAddress())) { continue; } count++; closePeers.add(peerStatistic.peerAddress()); // this must be inside the loop as we need to retain the data for every peer Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); retVal.add(replicationSender.sendDirect(peerStatistic.peerAddress(), locationKey, dataMap)); if (count == replicationFactor) { break; } } LOG.debug( "[storage refresh] I ({}) restore {} to {}", peer.peerAddress(), locationKey, closePeers); return FutureDone.whenAll(retVal); }
@Override public FutureDone<?> meResponsible(final Number160 locationKey, PeerAddress newPeer) { LOG.debug("I ({}) sync {} to {}", peer.peerAddress(), locationKey, newPeer); Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); return replicationSender.sendDirect(newPeer, locationKey, dataMap); }
public IndirectReplication start() { if (intervalMillis == -1) { intervalMillis = 60 * 1000; } if (delayMillis == -1) { delayMillis = 30 * 1000; } if (blockSize == -1) { blockSize = 700; } if (autoReplication) { replicationFactor = new AutoReplication(peer.peer()); } else if (replicationFactor == null) { replicationFactor = new ReplicationFactor() { @Override public int replicationFactor() { return DEFAULT_REPLICATION_FACTOR; } }; } if (replicationFilters == null) { replicationFilters = new HashSet<ReplicationFilter>(0); } this.replication = new Replication( peer, replicationFactor.replicationFactor(), nRoot, keepData, replicationFilters); this.replication.addResponsibilityListener(this); if (responsibilityListeners != null) { for (ResponsibilityListener responsibilityListener : responsibilityListeners) { this.replication.addResponsibilityListener(responsibilityListener); } responsibilityListeners = null; } peer.storeRPC().replicationListener(replication); if (rsync) { replicationSender = new PeerSync(peer, replication, blockSize); } else if (replicationSender == null) { replicationSender = new DefaultReplicationSender(peer); } scheduledFuture = peer.peer() .connectionBean() .timer() .scheduleAtFixedRate(this, intervalMillis, intervalMillis, TimeUnit.MILLISECONDS); return this; }
@Override public FutureDone<?> otherResponsible(final Number160 locationKey, final PeerAddress other) { LOG.debug( "Other peer {} is responsible for {}. I'm {}", other, locationKey, peer.peerAddress()); Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); LOG.debug("transfer from {} to {} for key {}", peer.peerAddress(), other, locationKey); return replicationSender.sendDirect(other, locationKey, dataMap); }
private void printStats() { StringBuilder sb = new StringBuilder("*************************\n"); sb.append("Stats of peer ").append(peerDHT.peer().peerID()).append(": \n"); sb.append("PUT: count: ") .append(putStats.getCount()) .append(" | avgtime: ") .append(putStats.getAverageTime()) .append("ms | success: ") .append(putStats.getSuccessRate()) .append("\n"); sb.append("GET: count: ") .append(putStats.getCount()) .append(" | avgtime: ") .append(getStats.getAverageTime()) .append("ms | success: ") .append(getStats.getSuccessRate()) .append("\n"); sb.append("RMV: count: ") .append(putStats.getCount()) .append(" | avgtime: ") .append(rmvStats.getAverageTime()) .append("ms | success: ") .append(rmvStats.getSuccessRate()); System.out.println(sb.toString()); }
@Override public void run() { try { // we get called every x seconds for content we are responsible for. So // we need to make sure that there are enough copies. The easy way is to // publish it again... The good way is to do a diff Collection<Number160> locationKeys = peer.storageLayer().findContentForResponsiblePeerID(peer.peerID()); for (Number160 locationKey : locationKeys) { synchronizeData(locationKey); } // recalculate replication factor int replicationFactor = IndirectReplication.this.replicationFactor.replicationFactor(); replication.replicationFactor(replicationFactor); } catch (Throwable t) { t.printStackTrace(); } }
public IndirectReplication(PeerDHT peer) { this.peer = peer; peer.peer() .addShutdownListener( new Shutdown() { @Override public BaseFuture shutdown() { IndirectReplication.this.shutdown(); return new FutureDone<Void>().done(); } }); }
public boolean remove(Number640 key) { long startTime = System.currentTimeMillis(); FutureRemove remove = peerDHT .remove(key.locationKey()) .contentKey(key.contentKey()) .domainKey(key.domainKey()) .versionKey(key.versionKey()) .routingConfiguration(routingConfig) .requestP2PConfiguration(requestConfig) .start() .awaitUninterruptibly(); putStats.report(System.currentTimeMillis() - startTime, remove.isSuccess()); LOG.debug("Remove is success {}. Reason: {}", remove.isSuccess(), remove.failedReason()); return remove.isSuccess(); }
public Data get(Number640 key) { long startTime = System.currentTimeMillis(); FutureGet futureGet = peerDHT .get(key.locationKey()) .contentKey(key.contentKey()) .domainKey(key.domainKey()) .versionKey(key.versionKey()) .routingConfiguration(routingConfig) .requestP2PConfiguration(requestConfig) .start() .awaitUninterruptibly(); putStats.report(System.currentTimeMillis() - startTime, futureGet.isSuccess()); LOG.debug("Get is success {}. Reason: {}", futureGet.isSuccess(), futureGet.failedReason()); if (futureGet.data() != null) { return futureGet.data(); } else { return null; } }
public boolean put(Number640 key) { Data data = generateRandomData(); long startTime = System.currentTimeMillis(); FuturePut futurePut = peerDHT .put(key.locationKey()) .domainKey(key.domainKey()) .versionKey(key.versionKey()) .data(key.contentKey(), data) .routingConfiguration(routingConfig) .requestP2PConfiguration(requestConfig) .start() .awaitUninterruptibly(); putStats.report(System.currentTimeMillis() - startTime, futurePut.isSuccess()); LOG.debug( "Put of {} bytes is success = {}. Reason: {}", data.length(), futurePut.isSuccess(), futurePut.failedReason()); return futurePut.isSuccess(); }
/** * If an other peer is responsible, we send this peer our data, so that the other peer can take * care of this. * * @param other The other peer * @param locationKey The location key * @param domainKey The domain key * @param dataMapConvert The data to store */ public FutureDone<Void> sendDirect( final PeerAddress other, final Number160 locationKey, final NavigableMap<Number640, Data> dataMap) { final FutureDone<Void> futureDone = new FutureDone<Void>(); FutureChannelCreator futureChannelCreator = peer.peer().connectionBean().reservation().create(0, 1); Utils.addReleaseListener(futureChannelCreator, futureDone); futureChannelCreator.addListener( new BaseFutureAdapter<FutureChannelCreator>() { @Override public void operationComplete(final FutureChannelCreator future) throws Exception { if (future.isSuccess()) { PutBuilder putBuilder = new PutBuilder(peer, locationKey); putBuilder.dataMap(dataMap); FutureResponse futureResponse = storageRPC.putReplica(other, putBuilder, future.channelCreator()); futureResponse.addListener( new BaseFutureAdapter<FutureResponse>() { @Override public void operationComplete(FutureResponse future) throws Exception { if (future.isSuccess()) { futureDone.done(); } else { futureDone.failed(future); } } }); peer.peer().notifyAutomaticFutures(futureResponse); } else { futureDone.failed(future); LOG.error("otherResponsible failed {}", future.failedReason()); } } }); return futureDone; }
private DefaultReplicationSender(PeerDHT peer) { this.peer = peer; this.storageRPC = peer.storeRPC(); }
@Override public FutureDone<?> meResponsible(final Number160 locationKey) { LOG.debug("I ({}) now responsible for {}", peer.peerAddress(), locationKey); return synchronizeData(locationKey); }
@Override public String toString() { return "Query-Peer " + peerDHT.peerID(); }