# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

from experiments.models import Experiment, ExperimentJob, ExperimentJobStatus
from spawner.utils.constants import JobLifeCycle, ExperimentLifeCycle

from experiments.tasks import check_experiment_status, build_experiment, stop_experiment


@receiver(post_save, sender=Experiment, dispatch_uid="experiment_saved")
def new_experiment(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # Check if the experiment is newly created and that we can start it independently
    if not created:
        return

    instance.set_status(ExperimentLifeCycle.CREATED)
    if instance.is_independent:
        # Start building the experiment and then Schedule it to be picked by the spawner
        build_experiment.delay(experiment_id=instance.id)


@receiver(post_delete, sender=Experiment, dispatch_uid="experiment_deleted")
def experiment_deleted(sender, **kwargs):
    instance = kwargs['instance']
    stop_experiment.delay(experiment_id=instance.id)


@receiver(post_save, sender=ExperimentJob, dispatch_uid="experiment_job_saved")
def new_experiment_job(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # Check if the experiment job
    if not created:
        return

    instance.set_status(status=JobLifeCycle.CREATED)


@receiver(post_save, sender=ExperimentJobStatus, dispatch_uid="experiment_job_status_saved")
def new_experiment_job_status(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # check if the new status is done to remove the containers from the monitors
    job = instance.job
    if job.is_done:
        from libs.redis_db import RedisJobContainers

        RedisJobContainers.remove_job(job.uuid.hex)

    # Check if the experiment job status
    if not created:
        return

    # Check if we need to change the experiment status
    experiment = instance.job.experiment
    if experiment.is_done:
        return

    check_experiment_status.delay(experiment_uuid=experiment.uuid.hex)

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

from django.db.models.signals import post_save, post_delete, pre_delete
from django.dispatch import receiver

from experiments.models import Experiment, ExperimentJob, ExperimentJobStatus
from projects.models import ExperimentGroup
from spawner.scheduling import schedule_stop_experiment
from spawner.utils.constants import JobLifeCycle, ExperimentLifeCycle

from experiments.tasks import check_experiment_status, build_experiment


@receiver(post_save, sender=Experiment, dispatch_uid="experiment_saved")
def new_experiment(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # Check if the experiment is newly created and that we can start it independently
    if not created:
        return

    instance.set_status(ExperimentLifeCycle.CREATED)
    if instance.is_independent:
        # Start building the experiment and then Schedule it to be picked by the spawner
        build_experiment.delay(experiment_id=instance.id)


@receiver(pre_delete, sender=Experiment, dispatch_uid="experiment_deleted")
def experiment_deleted(sender, **kwargs):
    instance = kwargs['instance']
    try:
        _ = instance.experiment_group
        schedule_stop_experiment(instance, is_delete=True)
    except ExperimentGroup.DoesNotExist:
        # The experiment was already stopped when the group was deleted
        pass

@receiver(post_save, sender=ExperimentJob, dispatch_uid="experiment_job_saved")
def new_experiment_job(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # Check if the experiment job
    if not created:
        return

    instance.set_status(status=JobLifeCycle.CREATED)


@receiver(post_save, sender=ExperimentJobStatus, dispatch_uid="experiment_job_status_saved")
def new_experiment_job_status(sender, **kwargs):
    instance = kwargs['instance']
    created = kwargs.get('created', False)

    # check if the new status is done to remove the containers from the monitors
    job = instance.job
    if job.is_done:
        from libs.redis_db import RedisJobContainers

        RedisJobContainers.remove_job(job.uuid.hex)

    # Check if the experiment job status
    if not created:
        return

    # Check if we need to change the experiment status
    experiment = instance.job.experiment
    if experiment.is_done:
        return

    check_experiment_status.delay(experiment_uuid=experiment.uuid.hex)

Change experiment signal to pre delete for stopping jobs