All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bazaarvoice.emodb.sor.compactioncontrol.DefaultCompactionControlSource Maven / Gradle / Ivy

There is a newer version: 6.5.190
Show newest version
package com.bazaarvoice.emodb.sor.compactioncontrol;

import com.bazaarvoice.emodb.common.zookeeper.store.MapStore;
import com.bazaarvoice.emodb.sor.api.CompactionControlSource;
import com.bazaarvoice.emodb.sor.api.StashRunTimeInfo;
import com.bazaarvoice.emodb.sor.api.StashTimeKey;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

/*
 * Default implementation which uses ZooKeeper to store stash times just in the local data center.
 *
 */
public class DefaultCompactionControlSource implements CompactionControlSource {

    private static final Logger _log = LoggerFactory.getLogger(DefaultCompactionControlSource.class);

    private final MapStore _stashStartTimestampInfo;

    @Inject
    public DefaultCompactionControlSource(@StashRunTimeMapStore final MapStore stashStartTimestampInfo, final MetricRegistry metricRegistry) {
        _stashStartTimestampInfo = requireNonNull(stashStartTimestampInfo, "stashStartTimestampInfo");
        requireNonNull(metricRegistry, "metricRegistry").register(MetricRegistry.name("bv.emodb.scan", "CompactionControlSource", "map-size"),
                (Gauge) () -> _stashStartTimestampInfo.keySet().size());
    }

    @Override
    public void updateStashTime(String id, long timestamp, List placements, long expiredTimestamp, String dataCenter) {
        requireNonNull(id, "id");
        requireNonNull(placements, "placements");
        requireNonNull(dataCenter, "dataCenter");
        checkState(timestamp > System.currentTimeMillis() + Duration.ofSeconds(10).toMillis(), "specified timestamp seems to be in the past");

        try {
            _stashStartTimestampInfo.set(zkKey(id, dataCenter), new StashRunTimeInfo(timestamp, placements, dataCenter, expiredTimestamp));
        } catch (Exception e) {
            _log.error("Failed to update stash timestamp info for id: {}, datacenter: {}", id, dataCenter, e);
            throw Throwables.propagate(e);
        }
    }

    @Override
    public void deleteStashTime(String id, String dataCenter) {
        requireNonNull(id, "id");
        requireNonNull(dataCenter, "dataCenter");

        try {
            _stashStartTimestampInfo.remove(zkKey(id, dataCenter));
        } catch (Exception e) {
            _log.error("Failed to delete stash timestamp info for id: {}, datacenter: {}", id, dataCenter, e);
            throw Throwables.propagate(e);
        }
    }

    @Override
    public StashRunTimeInfo getStashTime(String id, String dataCenter) {
        requireNonNull(id, "id");
        requireNonNull(dataCenter, "dataCenter");

        return _stashStartTimestampInfo.get(zkKey(id, dataCenter));
    }

    @Override
    public Map getAllStashTimes() {
        // Zookeeper entries have "ID@datacenter" as key names; example: daily-2018-05-26-00-00-00@eu-west-1-prod.
        // Separating the ID and datacenter in the key.
        return getStashTimesWithTupleKeys(_stashStartTimestampInfo.getAll());
    }

    @Override
    public Map getStashTimesForPlacement(String placement) {
        Map stashTimes = _stashStartTimestampInfo.getAll();
        return getStashTimesWithTupleKeys(stashTimes.size() > 0 ? stashTimes.entrySet().stream()
                .filter(stashTime -> stashTime.getValue().getPlacements().contains(placement))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
                : ImmutableMap.of());
    }

    @VisibleForTesting
    protected static String zkKey(String id, String dataCenter) {
        if (id.contains(StashTimeKey.ZK_STRING_DELIMITER)) {
          throw new IllegalArgumentException("Id cannot contain character: " + StashTimeKey.ZK_STRING_DELIMITER);
        }
        return id + StashTimeKey.ZK_STRING_DELIMITER + dataCenter;
    }

    @VisibleForTesting
    protected static Map getStashTimesWithTupleKeys(Map stashTimesFromZk) {
        Map allStashTimes = Maps.newHashMap();
        for (Map.Entry stashTimeFromZk : stashTimesFromZk.entrySet()) {
            allStashTimes.put(StashTimeKey.fromString(stashTimeFromZk.getKey()), stashTimeFromZk.getValue());
        }
        return allStashTimes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy