private DataNodeIdentifier pickReplacement( SegmentGroup affectedGroup, DataNodeIdentifier oldNode) { DataNodeIdentifier replacementNode = null; List<DataNodeStatusPair> removedPairs = new ArrayList<DataNodeStatusPair>(); while (replacementNode == null) { DataNodeStatusPair next = datanodeStatuses.poll(); removedPairs.add(next); DataNodeIdentifier nextId = next.getIdentifier(); if (!nextId.equals(oldNode) && !affectedGroup.isMember(nextId)) { replacementNode = nextId; } } for (DataNodeStatusPair each : removedPairs) { datanodeStatuses.add(each); } return replacementNode; }
protected void reconfigureSegmentGroup( SegmentGroup affectedGroup, DataNodeIdentifier oldNode, DataNodeIdentifier replacementNode, boolean oldNodeIsUp) { System.out.println("Reconfiguring"); /* what do we do? this is what we do... note: we do NOT worry about the status of the node here; we assume that is set by the coordinator for each segment in the segment group: if (oldNodeIsUp): send an unset-segment request perform a read on the segment group send a write request to the new node swap the new node into the segment group */ int volumeId = affectedGroup.getVolumeId(); long startingOffset = affectedGroup.getStartingBlock(); long stoppingOffset = affectedGroup.getStoppingBlock(); if (oldNodeIsUp) { List<DataNodeIdentifier> targets = new ArrayList<DataNodeIdentifier>(); targets.add(oldNode); int unsetId = coordinator .getServer() .issueUnsetSegmentRequest(targets, volumeId, startingOffset, stoppingOffset); boolean waiting = true; while (waiting) { List<UnsetSegmentRequestResult> results = coordinator.getServer().getUnsetSegmentRequestResults(unsetId); if (results.get(0).wasSuccessful()) { waiting = false; } } } List<DataNodeIdentifier> replacementMembers = new ArrayList<DataNodeIdentifier>(affectedGroup.getMembers()); int oldNodeIndex = replacementMembers.indexOf(oldNode); replacementMembers.set(oldNodeIndex, replacementNode); SegmentGroup replacementGroup = new SegmentGroup(replacementMembers, volumeId, startingOffset, stoppingOffset); for (long offset = startingOffset; offset <= stoppingOffset; ++offset) // TODO FIXME eventual improvement: make this whole loop asynchronous // that is, issue each read request, then as the results come in, issue the write requests { int readId = coordinator.read(volumeId, logicalOffset); while (!coordinator.requestFinished(readId)) { // spin!!! } ReadRequestResult readResult = coordinator.readResult(readId); byte[] block = readResult.getBlock(); int writeId = coordinator.writeWithTarget(replacementGroup, volumeId, offset, block); while (!coordinator.requestFinished(writeId)) { // spin!!! } // TODO FIXME check for success of the read (above) and the write (here) } affectedGroup.replace(oldNode, replacementNode); }