<commit_before>package mesosphere.marathon.health

import mesosphere.marathon.api.v1.AppDefinition
import mesosphere.marathon.event._
import mesosphere.marathon.Protos.HealthCheckDefinition.Protocol

import com.google.common.eventbus.EventBus
import org.apache.mesos.Protos.TaskStatus

import scala.concurrent.Future
import javax.inject.{ Named, Inject }

class DelegatingHealthCheckManager @Inject() (
  @Named(EventModule.busName) eventBus: Option[EventBus])
    extends HealthCheckManager {

  protected[this] var taskHealth = Map[String, Health]()

  protected[this] var healthChecks = Map[String, Set[HealthCheck]]()

  override def list(appId: String): Set[HealthCheck] =
    healthChecks.getOrElse(appId, Set[HealthCheck]())

  override def add(appId: String, healthCheck: HealthCheck): Unit =
    healthChecks = healthChecks + (appId -> (list(appId) + healthCheck))

  override def addAllFor(app: AppDefinition): Unit =
    healthChecks = healthChecks + (app.id -> app.healthChecks)

  override def remove(appId: String, healthCheck: HealthCheck): Unit =
    healthChecks = healthChecks + (appId -> (list(appId) - healthCheck))

  override def removeAll(): Unit =
    healthChecks = Map[String, Set[HealthCheck]]()

  override def removeAllFor(appId: String): Unit =
    healthChecks = healthChecks - appId

  override def reconcileWith(app: AppDefinition): Unit = addAllFor(app)

  override def update(taskStatus: TaskStatus): Health = {
    val taskId = taskStatus.getTaskId.getValue
    val oldHealth: Health = taskHealth.getOrElse(taskId, Health(taskId))
    val newHealth =
      if (taskStatus.hasHealthy) {
        val healthy = taskStatus.getHealthy()
        log.info(s"Received status for [$taskId] with healthy=[$healthy]")
        log.debug(s"TaskStatus:\n$taskStatus")
        val healthResult = healthy match {
          case true  => Healthy(taskId = taskId)
          case false => Unhealthy(taskId = taskId, cause = "")
        }
        oldHealth update healthResult
      }
      else {
        log.info(s"Ignoring status for [$taskId] with no health information")
        log.debug(s"TaskStatus:\n$taskStatus")
        oldHealth
      }

    val appId = taskId take taskId.lastIndexOf('.')

    if (!newHealth.alive())
      firstCommandCheck(appId).foreach { healthCheck =>
        eventBus.foreach(_.post(FailedHealthCheck(appId, taskId, healthCheck)))
      }

    taskHealth = taskHealth + (taskId -> newHealth)
    newHealth
  }

  override def status(
    appId: String,
    taskId: String): Future[Seq[Option[Health]]] =
    Future.successful(Seq(taskHealth.get(taskId)))

  private[this] def firstCommandCheck(appId: String): Option[HealthCheck] =
    healthChecks.get(appId).flatMap {
      _.collectFirst { case hc if hc.protocol == Protocol.COMMAND => hc }
    }

}
<commit_msg>Send HealthStatusChanged in delegating HC manager<commit_after>package mesosphere.marathon.health

import mesosphere.marathon.api.v1.AppDefinition
import mesosphere.marathon.event._
import mesosphere.marathon.Protos.HealthCheckDefinition.Protocol

import com.google.common.eventbus.EventBus
import org.apache.mesos.Protos.TaskStatus

import scala.concurrent.Future
import javax.inject.{ Named, Inject }

class DelegatingHealthCheckManager @Inject() (
  @Named(EventModule.busName) eventBus: Option[EventBus])
    extends HealthCheckManager {

  protected[this] var taskHealth = Map[String, Health]()

  protected[this] var healthChecks = Map[String, Set[HealthCheck]]()

  override def list(appId: String): Set[HealthCheck] =
    healthChecks.getOrElse(appId, Set[HealthCheck]())

  override def add(appId: String, healthCheck: HealthCheck): Unit =
    healthChecks = healthChecks + (appId -> (list(appId) + healthCheck))

  override def addAllFor(app: AppDefinition): Unit =
    healthChecks = healthChecks + (app.id -> app.healthChecks)

  override def remove(appId: String, healthCheck: HealthCheck): Unit =
    healthChecks = healthChecks + (appId -> (list(appId) - healthCheck))

  override def removeAll(): Unit =
    healthChecks = Map[String, Set[HealthCheck]]()

  override def removeAllFor(appId: String): Unit =
    healthChecks = healthChecks - appId

  override def reconcileWith(app: AppDefinition): Unit = addAllFor(app)

  override def update(taskStatus: TaskStatus): Health = {
    val taskId = taskStatus.getTaskId.getValue
    val oldHealth: Health = taskHealth.getOrElse(taskId, Health(taskId))
    val newHealth =
      if (taskStatus.hasHealthy) {
        val healthy = taskStatus.getHealthy()
        log.info(s"Received status for [$taskId] with healthy=[$healthy]")
        log.debug(s"TaskStatus:\n$taskStatus")
        val healthResult = healthy match {
          case true  => Healthy(taskId = taskId)
          case false => Unhealthy(taskId = taskId, cause = "")
        }
        oldHealth update healthResult
      }
      else {
        log.info(s"Ignoring status for [$taskId] with no health information")
        log.debug(s"TaskStatus:\n$taskStatus")
        oldHealth
      }

    val appId = taskId take taskId.lastIndexOf('.')

    for (
      bus <- eventBus;
      healthCheck <- firstCommandCheck(appId)
    ) {
      if (!newHealth.alive)
        bus post FailedHealthCheck(appId, taskId, healthCheck)

      if (newHealth.alive != oldHealth.alive)
        bus post HealthStatusChanged(appId, taskId, newHealth.alive)
    }

    taskHealth = taskHealth + (taskId -> newHealth)
    newHealth
  }

  override def status(
    appId: String,
    taskId: String): Future[Seq[Option[Health]]] =
    Future.successful(Seq(taskHealth.get(taskId)))

  private[this] def firstCommandCheck(appId: String): Option[HealthCheck] =
    healthChecks.get(appId).flatMap {
      _.collectFirst { case hc if hc.protocol == Protocol.COMMAND => hc }
    }

}

{'fraction_non_alphanumeric': 0.11055536391859262, 'fraction_numerical': 0.00034494653328734045, 'mean_word_length': 3.7925619834710744, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3959203', 'n_tokens_mistral': 1783, 'n_tokens_neox': 1737, 'n_words': 398}