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

com.hubspot.singularity.scheduler.SingularityMailPoller Maven / Gradle / Ivy

package com.hubspot.singularity.scheduler;

import com.google.inject.Inject;
import com.hubspot.mesos.JavaUtils;
import com.hubspot.singularity.SingularityDeleteResult;
import com.hubspot.singularity.SingularityRequestWithState;
import com.hubspot.singularity.SingularityTaskHistory;
import com.hubspot.singularity.SingularityTaskHistoryUpdate;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.SingularityTaskMetadata;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.config.SingularityTaskMetadataConfiguration;
import com.hubspot.singularity.data.RequestManager;
import com.hubspot.singularity.data.TaskManager;
import com.hubspot.singularity.data.history.HistoryManager;
import com.hubspot.singularity.smtp.SingularityMailer;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class SingularityMailPoller extends SingularityLeaderOnlyPoller {
  private static final Logger LOG = LoggerFactory.getLogger(SingularityMailPoller.class);

  private final SingularityConfiguration configuration;
  private final TaskManager taskManager;
  private final RequestManager requestManager;
  private final HistoryManager historyManager;
  private final SingularityMailer mailer;
  private final SingularityTaskMetadataConfiguration taskMetadataConfiguration;

  @Inject
  SingularityMailPoller(
    SingularityConfiguration configuration,
    SingularityTaskMetadataConfiguration taskMetadataConfiguration,
    TaskManager taskManager,
    RequestManager requestManager,
    HistoryManager historyManager,
    SingularityMailer mailer
  ) {
    super(configuration.getCheckQueuedMailsEveryMillis(), TimeUnit.MILLISECONDS);
    this.configuration = configuration;
    this.taskMetadataConfiguration = taskMetadataConfiguration;
    this.taskManager = taskManager;
    this.requestManager = requestManager;
    this.historyManager = historyManager;
    this.mailer = mailer;
  }

  @Override
  protected boolean isEnabled() {
    return configuration.getSmtpConfigurationOptional().isPresent();
  }

  private enum ShouldSendMailState {
    SEND,
    WAIT,
    ERROR
  }

  private void checkToSendTaskFinishedMail(SingularityTaskId taskId) {
    Optional requestWithState = requestManager.getRequest(
      taskId.getRequestId()
    );
    Optional taskHistory = taskManager.getTaskHistory(taskId);
    if (!taskHistory.isPresent()) {
      taskHistory = historyManager.getTaskHistory(taskId.getId());
    }

    ShouldSendMailState shouldSendState = shouldSendTaskFinishedMail(
      taskId,
      requestWithState,
      taskHistory
    );

    if (shouldSendState == ShouldSendMailState.WAIT) {
      return;
    }

    try {
      mailer.sendTaskCompletedMail(
        taskHistory.get(),
        requestWithState.get().getRequest()
      );
    } catch (Throwable t) {
      LOG.error("While trying to send task completed mail for {}", taskId, t);
    } finally {
      SingularityDeleteResult result = taskManager.deleteFinishedTaskMailQueue(taskId);
      LOG.debug(
        "Task {} mail sent with status {} (delete result {})",
        taskId,
        shouldSendState,
        result
      );
    }
  }

  private ShouldSendMailState shouldSendTaskFinishedMail(
    SingularityTaskId taskId,
    Optional requestWithState,
    Optional taskHistory
  ) {
    if (!requestWithState.isPresent()) {
      LOG.warn("No request found for {}, can't send task finished email", taskId);
      return ShouldSendMailState.ERROR;
    }

    if (!taskHistory.isPresent()) {
      taskHistory = historyManager.getTaskHistory(taskId.getId());
    }

    if (!taskHistory.isPresent()) {
      LOG.warn("No task history found for {}, can't send task finished email", taskId);
      return ShouldSendMailState.ERROR;
    }

    if (
      taskMetadataConfiguration
        .getSendTaskCompletedMailOnceMetadataTypeIsAvailable()
        .isPresent()
    ) {
      for (SingularityTaskMetadata taskMetadata : taskHistory.get().getTaskMetadata()) {
        if (
          taskMetadata
            .getType()
            .equals(
              taskMetadataConfiguration
                .getSendTaskCompletedMailOnceMetadataTypeIsAvailable()
                .get()
            )
        ) {
          LOG.debug(
            "Sending task finished email for {} because metadata type {} is present",
            taskId,
            taskMetadataConfiguration
              .getSendTaskCompletedMailOnceMetadataTypeIsAvailable()
              .get()
          );
          return ShouldSendMailState.SEND;
        }
      }
    }

    // check to see if it's too soon.
    if (taskMetadataConfiguration.getWaitToSendTaskCompletedMailBufferMillis() > 0) {
      Optional lastUpdate = taskHistory
        .get()
        .getLastTaskUpdate();

      if (!lastUpdate.isPresent()) {
        LOG.warn("Missing last update for {}, can't send task finished email", taskId);
        return ShouldSendMailState.ERROR;
      }

      final long timeSinceLastUpdate =
        System.currentTimeMillis() - lastUpdate.get().getTimestamp();

      if (
        timeSinceLastUpdate <
        taskMetadataConfiguration.getWaitToSendTaskCompletedMailBufferMillis()
      ) {
        LOG.debug(
          "Not sending task finished email for {} because last update was {} ago, buffer is {}",
          taskId,
          JavaUtils.durationFromMillis(timeSinceLastUpdate),
          JavaUtils.durationFromMillis(
            taskMetadataConfiguration.getWaitToSendTaskCompletedMailBufferMillis()
          )
        );
        return ShouldSendMailState.WAIT;
      }
    }

    return ShouldSendMailState.SEND;
  }

  @Override
  public void runActionOnPoll() {
    for (SingularityTaskId finishedTaskId : taskManager.getTaskFinishedMailQueue()) {
      checkToSendTaskFinishedMail(finishedTaskId);
    }
  }

  @Override
  protected boolean abortsOnError() {
    return false;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy