public static boolean isUpToDate(RingGroup ringGroup, DomainGroup domainGroup) throws IOException { for (Ring ring : ringGroup.getRings()) { if (!Rings.isUpToDate(ring, domainGroup)) { return false; } } return true; }
public static int getNumHosts(RingGroup ringGroup) { int result = 0; for (Ring ring : ringGroup.getRings()) { result += ring.getHosts().size(); } return result; }
public static Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> computeFilesystemStatistics(RingGroup ringGroup) throws IOException { Map<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>> result = new HashMap<Ring, Map<Host, Map<String, FilesystemStatisticsAggregator>>>(); for (Ring ring : ringGroup.getRings()) { result.put(ring, Rings.computeFilesystemStatistics(ring)); } return result; }
private int getNextRingNum(RingGroup group) { return group.getRings() .stream() .map(ring -> ring.getRingNumber()) .max(Comparator.naturalOrder()) .orElse(-1) + 1; }
public static boolean isUpToDate(RingGroup ringGroup, DomainGroup domainGroup, Domain domain) throws IOException { for (Ring ring : ringGroup.getRings()) { if (!Rings.isUpToDate(ring, domainGroup, domain)) { return false; } } return true; }
public static Set<Host> getHostsInState(RingGroup ringGroup, HostState state) throws IOException { Set<Host> result = new TreeSet<Host>(); for (Ring ring : ringGroup.getRings()) { result.addAll(Rings.getHostsInState(ring, state)); } return result; }
public static Set<Host> getHosts(RingGroup ringGroup) { TreeSet<Host> result = new TreeSet<Host>(); for (Ring ring : ringGroup.getRings()) { result.addAll(ring.getHosts()); } return result; }
public static Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> computeRuntimeStatistics(Coordinator coordinator, RingGroup ringGroup) throws IOException { Map<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>> result = new HashMap<Ring, Map<Host, Map<Domain, RuntimeStatisticsAggregator>>>(); for (Ring ring : ringGroup.getRings()) { result.put(ring, Rings.computeRuntimeStatistics(coordinator, ring)); } return result; }
public static Set<Host> getHostsNotUpToDate(RingGroup ringGroup, Collection<DomainAndVersion> versions) throws IOException { Set<Host> outOfDateHosts = Sets.newHashSet(); for (Ring ring : ringGroup.getRings()) { for (Host host : ring.getHosts()) { if (!Hosts.isUpToDateOrMoreRecent(host, versions)) { outOfDateHosts.add(host); } } } return outOfDateHosts; } }
protected void removeEmptyRings(RingGroup ringGroup) throws IOException { // avoid concurrent modification exceptions Set<Integer> rings = ringGroup.getRings().stream().map(Ring::getRingNumber).collect(Collectors.toSet()); for (Integer ringNum : rings) { Ring ring = ringGroup.getRing(ringNum); if (ring.getHosts().isEmpty()) { ringGroup.removeRing(ringNum); } } }
protected Ring getUnderpopulatedRing(RingGroup group, String bucket) { for (Ring ring : group.getRings()) { Set<Host> hosts = ring.getHosts(); if (!hosts.isEmpty()) { // kinda iffy, but we don't assign multiple buckets within a ring String ringBucket = Accessors.first(hosts).getEnvironmentFlags().get(status.getAvailabilityBucketKey()); if ((ringBucket == null && bucket == null) || (ringBucket != null && ringBucket.equals(bucket))) { if (hosts.size() < targetHostsPerRing) { return ring; } } } } return null; }
public static boolean isServingOnlyUpToDateOrMoreRecent(RingGroup ringGroup, List<DomainAndVersion> domainVersions) throws IOException { for (Ring ring : ringGroup.getRings()) { for (Host host : ring.getHosts()) { if (host.getState() == HostState.SERVING && !Hosts.isUpToDateOrMoreRecent(host, domainVersions)) { return false; } } } return true; }
public static ServingStatusAggregator computeServingStatusAggregator(RingGroup ringGroup, DomainGroup domainGroup) throws IOException { ServingStatusAggregator servingStatusAggregator = new ServingStatusAggregator(); for (Ring ring : ringGroup.getRings()) { servingStatusAggregator.aggregate(Rings.computeServingStatusAggregator(ring, domainGroup)); } return servingStatusAggregator; }
public static UpdateProgressAggregator computeUpdateProgress(RingGroup ringGroup, DomainGroup domainGroup) throws IOException { UpdateProgressAggregator result = new UpdateProgressAggregator(); for (Ring ring : ringGroup.getRings()) { result.aggregate(Rings.computeUpdateProgress(ring, domainGroup)); } return result; }
protected void removeExcessHosts(RingGroup ringGroup) throws IOException { int totalRings = ringGroup.getRings().size(); DomainGroup domainGroup = ringGroup.getDomainGroup(); Map<Domain, Map<Integer, Set<Host>>> domainToPartitionToHostsFullyServing = PartitionUtils.domainToPartitionToHostsServing(ringGroup, status); ThreeNestedMap<Domain, Integer, String, Long> domainPartitionBucketHostCounts = PartitionUtils.domainToPartitionToHostsServingInBucket(domainToPartitionToHostsFullyServing, status); for (Ring ring : ringGroup.getRings()) { if (ring.getHosts().size() > targetHostsPerRing) { if (!ring.getHosts().isEmpty()) { for (Host host : ring.getHosts()) { if (removeHostIfReplicated(totalRings, domainGroup, domainToPartitionToHostsFullyServing, domainPartitionBucketHostCounts, ring, host)) { return; } } } } } }
private void doAddRing(HttpServletRequest req, HttpServletResponse resp) throws IOException { RingGroup ringGroup; String encodedRingGroupName = req.getParameter("g"); ringGroup = coordinator.getRingGroup(URLEnc.decode(encodedRingGroupName)); if (ringGroup == null) { throw new IOException("couldn't find any ring group called " + URLEnc.decode(encodedRingGroupName)); } // Find new ring ID (largest ID + 1) int newRingID = 0; for (Ring ring : ringGroup.getRings()) { if (ring.getRingNumber() >= newRingID) { newRingID = ring.getRingNumber() + 1; } } ringGroup.addRing(newRingID); resp.sendRedirect("/ring_group.jsp?name=" + encodedRingGroupName); }
public static boolean isServingOnlyUpToDate(RingGroup ringGroup) throws IOException { DomainGroup domainGroup = ringGroup.getDomainGroup(); for (Ring ring : ringGroup.getRings()) { for (Host host : ring.getHosts()) { if (host.getState() == HostState.SERVING && !Hosts.isUpToDate(host, domainGroup)) { return false; } } } return true; }
public RingGroupMonitor(RingGroup ringGroup, List<Notifier> notifiers) throws IOException { this.notifiers = notifiers; this.ringGroup = ringGroup; for (Ring ring : ringGroup.getRings()) { ringMonitors.add(new RingMonitor(ringGroup, ring, notifiers)); } this.ringGroupConductorStatusMonitor = new RingGroupConductorModeMonitor(); this.domainGroupMetadataMonitor = new DomainGroupMetadataMonitor(); ringGroup.addRingGroupConductorModeListener(ringGroupConductorStatusMonitor); ringGroup.getDomainGroup().addListener(domainGroupMetadataMonitor); }
@Test public void testAddRingGroup() throws Exception { DomainGroup dg = coord.addDomainGroup("myDomainGroup2"); Map<Domain, Integer> domainIdToVersion = new HashMap<>(); dg.setDomainVersions(domainIdToVersion); RingGroup rg = coord.addRingGroup("superDuperRingGroup", "myDomainGroup2"); assertEquals("superDuperRingGroup", rg.getName()); assertEquals(0, rg.getRings().size()); }
@Override public void manageTransitions(Coordinator coordinator, RingGroup ringGroup) throws IOException { for (Ring ring : ringGroup.getRings()) { for (Host host : ring.getHostsSorted()) { PartitionUtils.isFullyServing(host, true, status); } } // Reconfigure rings if we changed the target # of hosts per ring // if there is a ring with too many hosts, remove a host from the ring removeExcessHosts(ringGroup); // if there are multiple rings within a bucket without enough hosts in them, // choose one of them, remove a host from the one with the fewest hosts consolidateRings(ringGroup); // if either of the above operations left an empty ring, remove it removeEmptyRings(ringGroup); // if we can put together a full ring with unassigned hosts, do so assignUnassignedHostsToRings(ringGroup); // configure the domains synchronizeDomains(coordinator, ringGroup); // add domains to the ring group if possible addDomainsToRingGroup(coordinator, ringGroup); }