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

com.hubspot.singularity.data.usage.ZkTaskUsageManager Maven / Gradle / Ivy

package com.hubspot.singularity.data.usage;

import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.singularity.InvalidSingularityTaskIdException;
import com.hubspot.singularity.SingularityDeleteResult;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.SingularityTaskUsage;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.CuratorAsyncManager;
import com.hubspot.singularity.data.transcoders.Transcoder;
import java.util.List;
import java.util.Optional;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class ZkTaskUsageManager extends CuratorAsyncManager implements TaskUsageManager {
  private static final Logger LOG = LoggerFactory.getLogger(ZkTaskUsageManager.class);

  private static final String ROOT_PATH = "/usage";

  private static final String TASK_PATH = ROOT_PATH + "/tasks";

  private static final String USAGE_HISTORY_PATH_KEY = "history";

  private final Transcoder taskUsageTranscoder;

  @Inject
  public ZkTaskUsageManager(
    CuratorFramework curator,
    SingularityConfiguration configuration,
    MetricRegistry metricRegistry,
    Transcoder taskUsageTranscoder
  ) {
    super(curator, configuration, metricRegistry);
    this.taskUsageTranscoder = taskUsageTranscoder;
  }

  private String getTaskUsagePath(SingularityTaskId taskId) {
    return ZKPaths.makePath(TASK_PATH, taskId.getRequestId(), taskId.getId());
  }

  private String getTaskUsageHistoryPath(SingularityTaskId taskId) {
    return ZKPaths.makePath(getTaskUsagePath(taskId), USAGE_HISTORY_PATH_KEY);
  }

  private String getSpecificTaskUsagePath(SingularityTaskId taskId, long timestamp) {
    return ZKPaths.makePath(getTaskUsageHistoryPath(taskId), Long.toString(timestamp));
  }

  public void deleteTaskUsage(SingularityTaskId taskId) {
    delete(getTaskUsagePath(taskId));
  }

  public void deleteSpecificTaskUsage(SingularityTaskId taskId, long timestamp) {
    delete(getSpecificTaskUsagePath(taskId, timestamp));
  }

  public void saveSpecificTaskUsage(
    SingularityTaskId taskId,
    SingularityTaskUsage usage
  ) {
    save(
      getSpecificTaskUsagePath(taskId, usage.getTimestamp()),
      usage,
      taskUsageTranscoder
    );
  }

  public List getTaskUsage(SingularityTaskId taskId) {
    List children = getAsyncChildren(
      getTaskUsageHistoryPath(taskId),
      taskUsageTranscoder
    );
    children.sort(TASK_USAGE_COMPARATOR_TIMESTAMP_ASC);
    return children;
  }

  @VisibleForTesting
  public int countTasksWithUsage() {
    return getChildren(TASK_PATH)
      .stream()
      .map(requestId -> checkExists(ZKPaths.makePath(TASK_PATH, requestId)))
      .filter(Optional::isPresent)
      .map(Optional::get)
      .mapToInt(Stat::getNumChildren)
      .sum();
  }

  public void cleanOldUsages(List activeTaskIds) {
    for (String requestId : getChildren(TASK_PATH)) {
      // clean for inactive tasks
      for (String taskIdString : getChildren(ZKPaths.makePath(TASK_PATH, requestId))) {
        SingularityTaskId taskId;
        try {
          taskId = SingularityTaskId.valueOf(taskIdString);
          if (activeTaskIds.contains(taskId)) {
            // prune old usages for active tasks
            getChildren(getTaskUsageHistoryPath(taskId))
              .stream()
              .map(Long::parseLong)
              .sorted((t1, t2) -> Long.compare(t2, t1))
              .skip(configuration.getNumUsageToKeep())
              .forEach(
                timestamp -> {
                  delete(getSpecificTaskUsagePath(taskId, timestamp));
                }
              );
            continue;
          }
        } catch (InvalidSingularityTaskIdException e) {
          LOG.warn(
            "{} is not a valid task id, will remove task usage from zookeeper",
            taskIdString
          );
        }
        SingularityDeleteResult result = delete(
          ZKPaths.makePath(TASK_PATH, requestId, taskIdString)
        ); // manually constructed in case SingularityTaskId.valueOf fails

        LOG.debug("Deleted obsolete task usage {} - {}", taskIdString, result);
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy