summaryrefslogtreecommitdiff
path: root/blocks/simulationAPI/models.py
blob: 1f639c5a2b180d52bb163cfea13d375a5c2a48a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from django.db import models
from django.core.exceptions import ValidationError
from django.core.files.storage import FileSystemStorage
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
import uuid
from celery.result import AsyncResult


TASK_TYPE_CHOICES = [
    ("XCOS", "Xcos"),
    ("SCRIPT", "Scilab Script"),
]

TASK_STATUS_CHOICES = [
    ("PENDING", "Pending"),
    ("STARTED", "Started"),
    ("STREAMING", "Streaming"),
    ("SUCCESS", "Success"),
    ("FAILURE", "Failure"),
    ("RETRY", "Retry"),
    ("CANCELED", "Canceled"),
]


def get_expire_at():
    return timezone.now() + timedelta(days=1)


class Session(models.Model):
    session_id = models.CharField(primary_key=True, max_length=40, null=False, editable=False)
    app_name = models.CharField(max_length=40, blank=False, null=False, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    expire_at = models.DateTimeField(default=get_expire_at)
    count = models.IntegerField(null=False, default=0)

    def save(self, *args, **kwargs):
        if self.pk is None:  # New entry
            self.count = 1
            super().save(*args, **kwargs)
            return

        old_instances = Session.objects.filter(pk=self.pk)
        if not old_instances.exists():  # New entry
            self.count = 1
            super().save(*args, **kwargs)
            return

        old_instance = old_instances.first()
        if old_instance.app_name == self.app_name and old_instance.expire_at > timezone.now():
            self.count += 1
            kwargs['update_fields'] = {'count'}
            super().save(*args, **kwargs)
            return

        if old_instance.app_name != self.app_name:
            raise ValidationError(f"mismatch: Cannot update app name {old_instance.app_name} != {self.app_name}.")

        if old_instance.expire_at <= timezone.now():
            raise ValidationError(f"mismatch: Cannot update expired session {old_instance.expire_at} <= {timezone.now()}.")

        raise ValidationError("mismatch: Cannot update.")

    def __str__(self):
        """String for representing the Model object."""
        return self.session_id


class Task(models.Model):
    task_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    file = models.FileField(storage=FileSystemStorage(location=settings.MEDIA_ROOT))
    type = models.CharField(max_length=20, choices=TASK_TYPE_CHOICES, null=False, default="XCOS")
    status = models.CharField(max_length=20, choices=TASK_STATUS_CHOICES, null=False, default="PENDING")
    parameters = models.TextField(blank=True, null=True)
    upload_time = models.DateTimeField(auto_now=True)
    log_name = models.CharField(max_length=500, blank=True, null=True)
    script_task_id = models.CharField(max_length=40, blank=True, null=True)
    workspace_file = models.CharField(max_length=500, blank=True, null=True)
    returncode = models.IntegerField(blank=True, null=True)
    session = models.ForeignKey(Session, on_delete=models.CASCADE, related_name='task', null=True)
    start_time = models.DateTimeField(null=True)
    end_time = models.DateTimeField(null=True)

    def save(self, *args, **kwargs):
        super(Task, self).save(*args, **kwargs)

    def __str__(self):
        """String for representing the Model object."""
        return f"{self.task_id.hex} - {self.status}"