Commit eecfb779cf5ed8cf300f0739c9df04d08739f32f
1 parent
20f8fc73
Exists in
master
and in
1 other branch
Date: 26/05/2016
By: Paul Carensac Version: 0.5.3 Minor changes (see issue) (Attention: DB changed) Issue (closed): https://projects.irap.omp.eu/issues/3708 Major current version (0.5): https://projects.irap.omp.eu/versions/116
Showing
19 changed files
with
144 additions
and
144 deletions
Show diff stats
README.md
... | ... | @@ -63,44 +63,14 @@ PROJECT STRUCTURE: |
63 | 63 | |
64 | 64 | CURRENT VERSION |
65 | 65 | |
66 | -Date: 25/05/2016 | |
66 | +Date: 26/05/2016 | |
67 | 67 | By: Paul Carensac |
68 | -Version: 0.5.2 | |
69 | -Strategy change implementation | |
68 | +Version: 0.5.3 | |
69 | +Minor changes (see issue) | |
70 | 70 | (Attention: DB changed) |
71 | -Issue (closed): https://projects.irap.omp.eu/issues/3654 | |
71 | +Issue (closed): https://projects.irap.omp.eu/issues/3708 | |
72 | 72 | Major current version (0.5): https://projects.irap.omp.eu/versions/116 |
73 | 73 | |
74 | -Date: 20/05/2016 | |
75 | -By: Paul Carensac | |
76 | -Version: 0.5.1 | |
77 | -Added test for request builder in common.tests | |
78 | -Issue (closed): https://projects.irap.omp.eu/issues/3663 | |
79 | -Major current version (0.5): https://projects.irap.omp.eu/versions/116 | |
80 | - | |
81 | -Date: 20/05/2016 | |
82 | -By: Paul Carensac | |
83 | -Version: 0.4.2 | |
84 | -Ajout de la simulation aux tests du scheduler | |
85 | -Issue (closed): https://projects.irap.omp.eu/issues/3701 | |
86 | -Major current version (0.4): https://projects.irap.omp.eu/versions/90 | |
87 | - | |
88 | -Date: 19/05/2016 | |
89 | -By: Paul Carensac | |
90 | -Version: 0.4.1 | |
91 | -Scheduler update: ajout overhead et nouveau systeme d'historique + adaptation des modules lies | |
92 | -(Attention: DB changed) | |
93 | -Issue (closed): https://projects.irap.omp.eu/issues/3625 | |
94 | -Major current version (0.4): https://projects.irap.omp.eu/versions/90 | |
95 | - | |
96 | -Date: 13/05/2016 | |
97 | -By: Etienne Pallier | |
98 | -Version: 0.3.1 | |
99 | -Agent system implementation | |
100 | -(Attention: DB changed) | |
101 | -Issue (closed): https://projects.irap.omp.eu/issues/3485 | |
102 | -Major current version (0.3): https://projects.irap.omp.eu/versions/88 | |
103 | - | |
104 | 74 | ROADMAP: https://projects.irap.omp.eu/projects/cpipeline/roadmap |
105 | 75 | |
106 | 76 | -------------------------------------------------------------------------------------------- | ... | ... |
src/alert_manager/StrategyBuilder.py
... | ... | @@ -36,21 +36,21 @@ class StrategyBuilder(): |
36 | 36 | name = name + '_' + strategy_file[:-4] |
37 | 37 | self.rb = RequestBuilder() |
38 | 38 | self.rb.start_new_request(pyros_user, scientific_program, True, name) |
39 | - for sequence in request: | |
40 | - self.add_sequence(sequence, scientific_program.priority) | |
39 | + for index, sequence in enumerate(request): | |
40 | + self.add_sequence(sequence, scientific_program.priority, name + "_" + str(index)) | |
41 | 41 | self.rb.validate_request() |
42 | 42 | return self.rb.request |
43 | 43 | |
44 | - def add_sequence(self, sequence, priority): | |
45 | - sequence_id = self.rb.add_sequence(priority, JD1, JD2, -1, sequence.get('name')) | |
46 | - for album in sequence: | |
47 | - self.add_album(album, sequence_id) | |
44 | + def add_sequence(self, sequence, priority, name): | |
45 | + sequence_id = self.rb.add_sequence(priority, JD1, JD2, -1, name=name) | |
46 | + for index, album in enumerate(sequence): | |
47 | + self.add_album(album, sequence_id, name + str(index)) | |
48 | 48 | |
49 | - def add_album(self, album, sequence_id): | |
50 | - album_id = self.rb.add_album(sequence_id, album.get('detector')) | |
51 | - for plan in album: | |
52 | - self.add_plan(plan, album_id) | |
49 | + def add_album(self, album, sequence_id, name): | |
50 | + album_id = self.rb.add_album(sequence_id, album.get('detector'), name=name) | |
51 | + for index, plan in enumerate(album): | |
52 | + self.add_plan(plan, album_id, name + str(index)) | |
53 | 53 | |
54 | - def add_plan(self, plan, album_id): | |
54 | + def add_plan(self, plan, album_id, name): | |
55 | 55 | self.rb.add_plan(album_id, plan.get('filter'), plan.get('duration'), |
56 | - plan.get('nb_images')) | |
56 | + plan.get('nb_images'), name=name) | ... | ... |
src/alert_manager/strategies/strat1.xml
src/alert_manager/strategies/strat2.xml
src/alert_manager/tasks.py
... | ... | @@ -73,7 +73,6 @@ class alert_listener(Task): |
73 | 73 | with open(os.path.join(VOEVENTS_PATH, event), 'rb') as f: |
74 | 74 | voevent = voeventparse.load(f) |
75 | 75 | print(voevent.Who.AuthorIVORN) |
76 | - majordome.TaskManager.delete_pending_tasks(['execute_sequence', 'execute_plan']) | |
77 | 76 | request = self.create_related_request(voevent) |
78 | 77 | Alert.objects.create(request=request, voevent_xml=event) |
79 | 78 | |
... | ... | @@ -87,20 +86,22 @@ class alert_listener(Task): |
87 | 86 | |
88 | 87 | pyros_user = PyrosUser.objects.get(user__username="haribo") |
89 | 88 | scientific_program = ScientificProgram.objects.get(name="GRB") |
89 | + v_params = voeventparse.pull_params(voevent) | |
90 | + voevent_id = v_params[None]['TrigID']['value'] | |
90 | 91 | request_builder = RequestBuilder() |
91 | 92 | request_builder.start_new_request( |
92 | - pyros_user, scientific_program, True, name="req1") | |
93 | - seq1 = request_builder.add_sequence(1, 0, 10, name="seq1") | |
94 | - alb11 = request_builder.add_album(seq1, Device.NIR, name="alb11") | |
93 | + pyros_user, scientific_program, True, name=voevent_id) | |
94 | + seq1 = request_builder.add_sequence(1, 0, 10, name=voevent_id + "_1") | |
95 | + alb11 = request_builder.add_album(seq1, Device.NIR, name=voevent_id + "_11") | |
95 | 96 | request_builder.add_plan( |
96 | - alb11, Device.NIR_FILTER_1, 120, 5, name="plan111") | |
97 | - alb12 = request_builder.add_album(seq1, Device.VIS, name="alb12") | |
97 | + alb11, Device.NIR_FILTER_1, 120, 5, name=voevent_id + "_111") | |
98 | + alb12 = request_builder.add_album(seq1, Device.VIS, name=voevent_id + "_12") | |
98 | 99 | request_builder.add_plan( |
99 | - alb12, Device.VIS_FILTER_1, 180, 1, name="plan121") | |
100 | - seq2 = request_builder.add_sequence(1, 0, 10, name="seq2") | |
101 | - alb21 = request_builder.add_album(seq2, Device.NIR, name="alb21") | |
100 | + alb12, Device.VIS_FILTER_1, 180, 1, name=voevent_id + "_121") | |
101 | + seq2 = request_builder.add_sequence(1, 0, 10, name=voevent_id + "_2") | |
102 | + alb21 = request_builder.add_album(seq2, Device.NIR, name=voevent_id + "_21") | |
102 | 103 | request_builder.add_plan( |
103 | - alb21, Device.NIR_FILTER_2, 60, 3, name="plan211") | |
104 | + alb21, Device.NIR_FILTER_2, 60, 3, name=voevent_id + "_211") | |
104 | 105 | return request_builder.validate_request() |
105 | 106 | |
106 | 107 | def run_simulation(self): |
... | ... | @@ -154,7 +155,7 @@ class alert_listener(Task): |
154 | 155 | |
155 | 156 | sequences = [sequence.strip('\n') for sequence in sequences] |
156 | 157 | request_builder = RequestBuilder() |
157 | - request_builder.start_new_request(PyrosUser.objects.get(), ScientificProgram.objects.get(), True) | |
158 | + request_builder.start_new_request(PyrosUser.objects.get(), ScientificProgram.objects.get(), True, name="Simulation_request") | |
158 | 159 | for sequence in sequences: |
159 | 160 | sequence_array = sequence.split(" ") |
160 | 161 | id_seq = sequence_array[0] |
... | ... | @@ -164,7 +165,7 @@ class alert_listener(Task): |
164 | 165 | jd1 = Decimal("%.8f" % float(sequence_array[5])) |
165 | 166 | jd2 = Decimal("%.8f" % float(sequence_array[6])) |
166 | 167 | |
167 | - request_builder.add_sequence(priority, jd1, jd2, name=id_seq, duration=duration) | |
168 | + request_builder.add_sequence(priority, jd1, jd2, name="Simulation_" + id_seq, duration=duration) | |
168 | 169 | |
169 | 170 | request_builder.validate_request() |
170 | 171 | Alert.objects.create(request=request_builder.request, strategyobs=StrategyObs.objects.all()[0]) | ... | ... |
src/alert_manager/templates/alert_manager/alerts.html
... | ... | @@ -28,38 +28,43 @@ |
28 | 28 | </div> |
29 | 29 | </center> |
30 | 30 | |
31 | - <div class="row"> | |
32 | - <h3>Alerts list :</h3> | |
33 | - | |
34 | - <div class="table-responsive"> | |
35 | - <table class="table table-bordered table-hover table-striped tablesorter"> | |
36 | - <thead> | |
37 | - <tr> | |
38 | - <th>Name<i class="fa fa-sort"></i></th> | |
39 | - <th>Date of creation<i class="fa fa-sort"></i></th> | |
40 | - <th>Current observation strategy<i class="fa fa-sort"></i></th> | |
41 | - </tr> | |
42 | - </thead> | |
43 | - <tbody> | |
44 | - {% for alert in alerts %} | |
31 | + <div class="row"> | |
32 | + <h3>Alerts list :</h3> | |
33 | + | |
34 | + <div class="table-responsive"> | |
35 | + <table class="table table-bordered table-hover table-striped tablesorter"> | |
36 | + <thead> | |
45 | 37 | <tr> |
46 | - <td>{{ alert.request.name }}</td> | |
47 | - <td>{{ alert.request.created }}</td> | |
48 | - <td> | |
49 | - {{ alert.strategyobs.name }} | |
50 | - <a href="{% url "alert_manager.views.change_obs_strategy" alert.id %}" | |
51 | - class="btn btn-primary" type="a"> | |
52 | - Change | |
53 | - </a> | |
54 | - </td> | |
38 | + <th style="text-align:center">Name<i class="fa fa-sort"></i></th> | |
39 | + <th style="text-align:center">Date of creation<i class="fa fa-sort"></i></th> | |
40 | + <th style="text-align:center">Current observation strategy<i class="fa fa-sort"></i></th> | |
55 | 41 | </tr> |
56 | - {% endfor %} | |
57 | - </tbody> | |
58 | - </table> | |
59 | - </div> | |
60 | - | |
61 | - </div> | |
42 | + </thead> | |
43 | + <tbody> | |
44 | + {% for alert in alerts %} | |
45 | + <tr> | |
46 | + <td align="center">{{ alert.request.name }}</td> | |
47 | + <td align="center">{{ alert.request.created }}</td> | |
48 | + <td align="center"> | |
49 | + {{ alert.strategyobs.name }} | |
50 | +     | |
51 | + <a href="{% url "alert_manager.views.change_obs_strategy" alert.id %}" | |
52 | + class="btn btn-primary" type="a"> | |
53 | + Change | |
54 | + </a> | |
55 | + </td> | |
56 | + </tr> | |
57 | + {% endfor %} | |
58 | + </tbody> | |
59 | + </table> | |
60 | + </div> | |
61 | + | |
62 | + </div> | |
62 | 63 | |
64 | + <div class="row"> | |
65 | + <a href="{% url "dashboard.views.home" %}" class="btn btn-sm btn-primary" type="a">Back to dashboard homepage</a> | |
66 | + </div> | |
67 | + | |
63 | 68 | </div><!-- /#page-wrapper --> |
64 | 69 | |
65 | 70 | </body> | ... | ... |
src/alert_manager/templates/alert_manager/strategy_change.html
... | ... | @@ -27,21 +27,32 @@ |
27 | 27 | {{ message|safe }} |
28 | 28 | </div> |
29 | 29 | </center> |
30 | - | |
31 | 30 | <div class="row"> |
32 | 31 | <h3>Select a new observation strategy for alert {{ alert.request.name }}:</h3> |
33 | 32 | <form action="{% url 'alert_manager.views.change_obs_strategy_validate' alert.id %}" method="post"> |
34 | 33 | {% csrf_token %} |
35 | 34 | {% for strategy in strategies %} |
36 | - <input type="radio" name="strategy_choice" id="choice{{ forloop.counter }}" value="{{ strategy.id }}"/> | |
37 | - <label for="choice{{ forloop.counter }}">{{ strategy.name }}</label><br /> | |
35 | + <div class="row"> | |
36 | + <div class="col-lg-4"> | |
37 | + <div class="input-group"> | |
38 | + <span class="input-group-addon"> | |
39 | + <input type="radio" aria-label="..." name="strategy_choice" id="choice{{ forloop.counter }}" value="{{ strategy.id }}"/> | |
40 | + </span> | |
41 | + <input class="form-control" aria-label="..." value="{{ strategy.name }}" readonly> | |
42 | + </div> | |
43 | + </div> | |
44 | + </div> | |
38 | 45 | {% endfor %} |
39 | - | |
46 | + | |
47 | + <br/> | |
40 | 48 | <p>Submitting will create a new alert request.</p> |
41 | - <input type="submit" value="Submit"> | |
49 | + <input class="btn btn-primary" type="submit" value="Submit"> | |
42 | 50 | </form> |
43 | 51 | </div> |
44 | 52 | |
53 | + <div class="row"> | |
54 | + <a href="{% url "alert_manager.views.alerts_list" %}" class="btn btn-sm btn-primary" type="a">Back to alerts list</a> | |
55 | + </div> | |
45 | 56 | </div><!-- /#page-wrapper --> |
46 | 57 | |
47 | 58 | </body> | ... | ... |
src/alert_manager/views.py
... | ... | @@ -50,13 +50,13 @@ def change_obs_strategy_validate(request, alert_id): |
50 | 50 | message = "This alert doesn't exist" |
51 | 51 | return render(request, "alert_manager/strategy_change.html", locals()) |
52 | 52 | |
53 | + print(alert.strategyobs.id, strategy_id) | |
54 | + | |
53 | 55 | if alert.strategyobs.id == strategy_id: |
54 | 56 | error = True |
55 | 57 | message = "This is already the current strategy for this alert" |
56 | 58 | return render(request, "alert_manager/strategy_change.html", locals()) |
57 | 59 | |
58 | - majordome.TaskManager.delete_pending_tasks(['execute_sequence', 'execute_plan']) | |
59 | - | |
60 | 60 | sb = StrategyBuilder() |
61 | 61 | file = strategy.xml_file |
62 | 62 | pyros_user = alert.request.pyros_user | ... | ... |
src/common/RequestBuilder.py
... | ... | @@ -172,5 +172,5 @@ class RequestBuilder(): |
172 | 172 | max_duration = duration if duration > max_duration else max_duration |
173 | 173 | sequence.duration = max_duration |
174 | 174 | sequence.save() |
175 | - scheduler.tasks.scheduling.delay(True) | |
175 | + scheduler.tasks.scheduling.delay(first_schedule=True, alert=self.request.is_alert) | |
176 | 176 | return self.request | ... | ... |
src/common/tests.py
src/dashboard/views.py
... | ... | @@ -14,9 +14,7 @@ def users(request): |
14 | 14 | |
15 | 15 | |
16 | 16 | def alerts(request): |
17 | - url_ = urlresolvers.reverse('admin:pyrosapp_alert_changelist') | |
18 | - return redirect(url_) | |
19 | - | |
17 | + return redirect('/alert_manager/alerts') | |
20 | 18 | |
21 | 19 | def routines(request): |
22 | 20 | url_ = urlresolvers.reverse('admin:pyrosapp_request_changelist') | ... | ... |
src/majordome/tasks.py
... | ... | @@ -20,6 +20,8 @@ class execute_sequence(Task): |
20 | 20 | sequence = shs.sequence |
21 | 21 | |
22 | 22 | TaskId.objects.filter(task_id=self.request.id).delete() |
23 | + shs.status = Sequence.EXECUTING | |
24 | + sequence.status = Sequence.EXECUTING | |
23 | 25 | message = 'Start sequence ' + str(sequence.pk) + ' execution' |
24 | 26 | Log.objects.create(agent='Majordome', message=message) |
25 | 27 | print("execute_sequence : ", sequence.pk) |
... | ... | @@ -40,14 +42,16 @@ class execute_sequence(Task): |
40 | 42 | for plan_result in plans_results: |
41 | 43 | # attention, un revoke n'annule pas le countdown du get() (ร |
42 | 44 | # rรฉflรฉchir) |
45 | + # possible solution : je supprime je countdown et je mets un sleep dans le execute_plan, avant, de l'enlever des TaskID | |
43 | 46 | try: |
44 | 47 | plan_result.get() |
45 | 48 | except Exception: |
46 | - pass | |
47 | - # en cas d'alerte reรงue, on va aussi supprimer la sรฉquence en cours d'exรฉcution ; รงa permettra de virer ce problรจme du countdown. | |
48 | - # de toute faรงon, c'est le execute_plan qui se charge d'envoyer les images ร l'analyse, donc osef que รงa coupe ici | |
49 | - # l'unique but de ne pas couper ici dรจs la crรฉation des plans est | |
50 | - # d'attendre la fin d'une sรฉquence avant d'en lancer une autre. | |
49 | + shs.status = Sequence.CANCELLED | |
50 | + sequence.status = Sequence.CANCELLED | |
51 | + return | |
52 | + | |
53 | + shs.status = Sequence.EXECUTED | |
54 | + sequence.status = Sequence.EXECUTED | |
51 | 55 | message = 'Finished sequence ' + str(sequence.pk) + ' execution' |
52 | 56 | Log.objects.create(agent='Majordome', message=message) |
53 | 57 | ... | ... |
src/pyros/settings.py
src/pyrosapp/models.py
... | ... | @@ -364,8 +364,7 @@ class Sequence(models.Model): |
364 | 364 | TOBEPLANNED = "TBP" |
365 | 365 | OBSERVABLE = "OBS" |
366 | 366 | UNPLANNABLE = "UNPLN" |
367 | - PLANNED = "PLND" | |
368 | - PENDING = "PENDG" | |
367 | + PENDING = "PNDG" | |
369 | 368 | EXECUTED = "EXD" |
370 | 369 | EXECUTING = "EXING" |
371 | 370 | REJECTED = "RJTD" |
... | ... | @@ -375,7 +374,6 @@ class Sequence(models.Model): |
375 | 374 | (TOBEPLANNED, "To be planned"), |
376 | 375 | (OBSERVABLE, "Observable"), |
377 | 376 | (UNPLANNABLE, "Unplannable"), |
378 | - (PLANNED, "Planned"), | |
379 | 377 | (PENDING, "Pending"), |
380 | 378 | (EXECUTED, "Executed"), |
381 | 379 | (EXECUTING, "Executing"), |
... | ... | @@ -430,6 +428,7 @@ class ScheduleHasSequences(models.Model): |
430 | 428 | |
431 | 429 | status = models.CharField( |
432 | 430 | max_length=11, blank=True, null=True, choices=Sequence.STATUS_CHOICES) |
431 | + desc = models.CharField(max_length=45, blank=True, null=True) | |
433 | 432 | tsp = models.DecimalField(default=-1.0, max_digits=15, decimal_places=8) |
434 | 433 | tep = models.DecimalField(default=-1.0, max_digits=15, decimal_places=8) |
435 | 434 | deltaTL = models.DecimalField( | ... | ... |
src/scheduler/models.py
... | ... | @@ -15,6 +15,9 @@ SIMULATION = False |
15 | 15 | MAX_OVERHEAD = 25 |
16 | 16 | MAX_OVERHEAD_JD = Decimal(MAX_OVERHEAD / (24 * 60 * 60)) |
17 | 17 | |
18 | +REJECTED_QUOTA = "Insufficient quota" | |
19 | +REJECTED_ROOM = "Insufficient room for this sequence" | |
20 | + | |
18 | 21 | ''' |
19 | 22 | Note : the following functions are necessary due to a too-high precision of Decimal objects |
20 | 23 | ''' |
... | ... | @@ -103,9 +106,7 @@ class Scheduler(): |
103 | 106 | - calcul de la prioritรฉ |
104 | 107 | - calcul des quotas |
105 | 108 | - dรฉfinir l'attribut 'flag' de Schedule |
106 | - - gestion du re-scheduling (en cas de nouvelle requete) | |
107 | 109 | - remplissage des espaces libres |
108 | - - gestion de l'historique (je sais pas si c'est ce module qui va s'en charger au final mais bon ...) | |
109 | 110 | |
110 | 111 | """ |
111 | 112 | |
... | ... | @@ -138,7 +139,7 @@ class Scheduler(): |
138 | 139 | |
139 | 140 | Check all 'OBSERVABLE' sequences to create the most optimized planning for the following/current night |
140 | 141 | |
141 | - It is assumed that all sequences that MUST and CAN be analyse have the OBSERVABLE status (e.g. : there must not be any PLANNED sequence at this point) | |
142 | + It is assumed that all sequences that MUST and CAN be analyse have the OBSERVABLE status | |
142 | 143 | |
143 | 144 | shs means 'ScheduleHasSequences' |
144 | 145 | self.sequences is a list of tuples (sequence, shs) |
... | ... | @@ -300,7 +301,8 @@ class Scheduler(): |
300 | 301 | for sequence, shs in list(self.sequences): |
301 | 302 | quota = self.determine_quota(sequence) |
302 | 303 | if quota < sequence.duration: |
303 | - self.sequences.remove((sequence, shs)) | |
304 | + shs.status = Sequence.REJECTED | |
305 | + shs.desc = REJECTED_QUOTA | |
304 | 306 | continue |
305 | 307 | |
306 | 308 | matching_intervals = self.get_matching_intervals(sequence) |
... | ... | @@ -310,8 +312,11 @@ class Scheduler(): |
310 | 312 | else: |
311 | 313 | sequence_placed = self.try_shifting_sequences(sequence, shs) |
312 | 314 | if sequence_placed == True: |
313 | - shs.status = Sequence.PLANNED | |
315 | + shs.status = Sequence.PENDING | |
314 | 316 | self.update_quota(sequence) |
317 | + else: | |
318 | + shs.status = Sequence.REJECTED | |
319 | + shs.desc = REJECTED_ROOM | |
315 | 320 | |
316 | 321 | def determine_quota(self, sequence: Sequence) -> float: |
317 | 322 | ''' |
... | ... | @@ -491,7 +496,7 @@ class Scheduler(): |
491 | 496 | ''' |
492 | 497 | |
493 | 498 | for sequence_, shs_ in self.sequences: |
494 | - if shs_.status == Sequence.PLANNED: | |
499 | + if shs_.status == Sequence.PENDING: | |
495 | 500 | if is_nearby_equal(shs_.tep, interval.start): |
496 | 501 | sequence_before_interval, shs_b_i = sequence_, shs_ |
497 | 502 | elif is_nearby_equal(shs_.tsp - self.max_overhead, interval.end): |
... | ... | @@ -520,7 +525,7 @@ class Scheduler(): |
520 | 525 | for interval in potential_intervals: |
521 | 526 | ''' we get the adjacent sequences ''' |
522 | 527 | for sequence_, shs_ in self.sequences: |
523 | - if shs_.status == Sequence.PLANNED: | |
528 | + if shs_.status == Sequence.PENDING: | |
524 | 529 | if is_nearby_equal(shs_.tep, interval.start): |
525 | 530 | sequence_before_interval, shs_b_i = sequence_, shs_ |
526 | 531 | elif is_nearby_equal(shs_.tsp - self.max_overhead, interval.end): |
... | ... | @@ -667,7 +672,7 @@ class Scheduler(): |
667 | 672 | ''' |
668 | 673 | |
669 | 674 | sequences = Sequence.objects.filter( |
670 | - shs__status=Sequence.PLANNED).order_by('shs__tsp') | |
675 | + shs__status=Sequence.PENDING).order_by('shs__tsp') | |
671 | 676 | |
672 | 677 | print("---- There are %d sequence(s) planned ----" % len(sequences)) |
673 | 678 | ... | ... |
src/scheduler/simulator.py
... | ... | @@ -134,7 +134,7 @@ class Simulator(): |
134 | 134 | sequences.sort(key=lambda x: x[1].tsp) |
135 | 135 | |
136 | 136 | for index, (sequence, shs) in enumerate(sequences): |
137 | - if shs.status == Sequence.PLANNED: | |
137 | + if shs.status == Sequence.PENDING: | |
138 | 138 | if shs.tsp > shs.tep: |
139 | 139 | raise ValueError("tep < tsp ...") |
140 | 140 | if shs.tsp < schedule.plan_start or schedule.plan_end < shs.tep: | ... | ... |
src/scheduler/tasks.py
1 | 1 | from __future__ import absolute_import |
2 | 2 | |
3 | 3 | from celery.task import Task |
4 | -from majordome.tasks import execute_sequence | |
4 | +import majordome | |
5 | 5 | from scheduler.models import Scheduler |
6 | 6 | from pyrosapp.models import * |
7 | 7 | |
... | ... | @@ -9,10 +9,15 @@ from decimal import Decimal |
9 | 9 | import math |
10 | 10 | import itertools |
11 | 11 | |
12 | - | |
13 | 12 | class scheduling(Task): |
14 | 13 | |
15 | - def run(self, first_schedule=False): | |
14 | + def run(self, first_schedule=False, alert=False): | |
15 | + | |
16 | + ''' First, we delete scheduled sequences (and plans in case of alert) ''' | |
17 | + if alert is True: | |
18 | + majordome.TaskManager.delete_pending_tasks(['execute_sequence', 'execute_plan']) | |
19 | + else: | |
20 | + majordome.TaskManager.delete_pending_tasks(['execute_sequence']) | |
16 | 21 | Log.objects.create(agent='Scheduler', message='Start schedule') |
17 | 22 | self.scheduler = Scheduler() |
18 | 23 | if first_schedule is True: |
... | ... | @@ -21,11 +26,11 @@ class scheduling(Task): |
21 | 26 | print("nb schedules %d" % len(Schedule.objects.all())) |
22 | 27 | schedule = Schedule.objects.order_by("-created")[0] |
23 | 28 | print(schedule.created, len(schedule.sequences.all())) |
24 | - shs_list = schedule.shs.filter(status=Sequence.PLANNED) | |
29 | + shs_list = schedule.shs.filter(status=Sequence.PENDING) | |
25 | 30 | print("Nb of shs %d, planned %d" % (len(schedule.shs.all()), len(shs_list))) |
26 | 31 | Log.objects.create(agent='Scheduler', message='Scheduling finished') |
27 | 32 | for shs in shs_list: |
28 | - res = execute_sequence.delay(shs.pk) | |
33 | + res = majordome.tasks.execute_sequence.delay(shs.pk) | |
29 | 34 | print("add exseq : ", res.id) |
30 | 35 | TaskId.objects.create(task_id=res.id, task="execute_sequence") |
31 | 36 | ... | ... |
src/scheduler/tests.py
... | ... | @@ -66,7 +66,7 @@ class SchedulerTest(TestCase): |
66 | 66 | |
67 | 67 | sched = Schedule.objects.order_by('-created')[0] |
68 | 68 | shs_list = sched.shs.all() |
69 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
69 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
70 | 70 | |
71 | 71 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
72 | 72 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -122,7 +122,7 @@ class SchedulerTest(TestCase): |
122 | 122 | |
123 | 123 | sched = Schedule.objects.order_by('-created')[0] |
124 | 124 | shs_list = sched.shs.all() |
125 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
125 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
126 | 126 | |
127 | 127 | seq1 = Sequence.objects.get(name="seq1") |
128 | 128 | seq2 = Sequence.objects.get(name="seq2") |
... | ... | @@ -169,7 +169,7 @@ class SchedulerTest(TestCase): |
169 | 169 | |
170 | 170 | sched = Schedule.objects.order_by('-created')[0] |
171 | 171 | shs_list = sched.shs.all() |
172 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
172 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
173 | 173 | |
174 | 174 | seq1 = Sequence.objects.get(name="seq1") |
175 | 175 | seq2 = Sequence.objects.get(name="seq2") |
... | ... | @@ -208,7 +208,7 @@ class SchedulerTest(TestCase): |
208 | 208 | |
209 | 209 | sched = Schedule.objects.order_by('-created')[0] |
210 | 210 | shs_list = sched.shs.all() |
211 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
211 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
212 | 212 | |
213 | 213 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
214 | 214 | |
... | ... | @@ -216,7 +216,7 @@ class SchedulerTest(TestCase): |
216 | 216 | |
217 | 217 | self.assertEqual(nbPlanned, 1) |
218 | 218 | |
219 | - self.assertEqual(shs2.status, Sequence.PLANNED) | |
219 | + self.assertEqual(shs2.status, Sequence.PENDING) | |
220 | 220 | |
221 | 221 | def test_3_seq_priority_overlap(self): |
222 | 222 | ''' |
... | ... | @@ -242,7 +242,7 @@ class SchedulerTest(TestCase): |
242 | 242 | |
243 | 243 | sched = Schedule.objects.order_by('-created')[0] |
244 | 244 | shs_list = sched.shs.all() |
245 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
245 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
246 | 246 | |
247 | 247 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
248 | 248 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -291,7 +291,7 @@ class SchedulerTest(TestCase): |
291 | 291 | |
292 | 292 | sched = Schedule.objects.order_by('-created')[0] |
293 | 293 | shs_list = sched.shs.all() |
294 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
294 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
295 | 295 | |
296 | 296 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
297 | 297 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -340,7 +340,7 @@ class SchedulerTest(TestCase): |
340 | 340 | |
341 | 341 | sched = Schedule.objects.order_by('-created')[0] |
342 | 342 | shs_list = sched.shs.all() |
343 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
343 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
344 | 344 | |
345 | 345 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
346 | 346 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -389,7 +389,7 @@ class SchedulerTest(TestCase): |
389 | 389 | |
390 | 390 | sched = Schedule.objects.order_by('-created')[0] |
391 | 391 | shs_list = sched.shs.all() |
392 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
392 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
393 | 393 | |
394 | 394 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
395 | 395 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -438,7 +438,7 @@ class SchedulerTest(TestCase): |
438 | 438 | |
439 | 439 | sched = Schedule.objects.order_by('-created')[0] |
440 | 440 | shs_list = sched.shs.all() |
441 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
441 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
442 | 442 | |
443 | 443 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
444 | 444 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -487,7 +487,7 @@ class SchedulerTest(TestCase): |
487 | 487 | |
488 | 488 | sched = Schedule.objects.order_by('-created')[0] |
489 | 489 | shs_list = sched.shs.all() |
490 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
490 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
491 | 491 | |
492 | 492 | shs1 = next(shs for shs in shs_list if shs.sequence == seq1) |
493 | 493 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
... | ... | @@ -540,7 +540,7 @@ class SchedulerTest(TestCase): |
540 | 540 | |
541 | 541 | sched = Schedule.objects.order_by('-created')[0] |
542 | 542 | shs_list = sched.shs.all() |
543 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
543 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
544 | 544 | |
545 | 545 | shs2 = next(shs for shs in shs_list if shs.sequence == seq2) |
546 | 546 | |
... | ... | @@ -555,7 +555,7 @@ class SchedulerTest(TestCase): |
555 | 555 | self.assertEqual(nbPlanned, 1) |
556 | 556 | |
557 | 557 | self.assertEqual(seq1.status, Sequence.TOBEPLANNED) |
558 | - self.assertEqual(shs2.status, Sequence.PLANNED) | |
558 | + self.assertEqual(shs2.status, Sequence.PENDING) | |
559 | 559 | self.assertEqual(seq3.status, Sequence.EXECUTED) |
560 | 560 | self.assertEqual(seq4.status, Sequence.REJECTED) |
561 | 561 | self.assertEqual(seq5.status, Sequence.UNPLANNABLE) |
... | ... | @@ -586,7 +586,7 @@ class SchedulerTest(TestCase): |
586 | 586 | |
587 | 587 | sched = Schedule.objects.order_by('-created')[0] |
588 | 588 | shs_list = sched.shs.all() |
589 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
589 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
590 | 590 | |
591 | 591 | seq1 = Sequence.objects.get(name="seq1") |
592 | 592 | seq2 = Sequence.objects.get(name="seq2") |
... | ... | @@ -627,7 +627,7 @@ class SchedulerTest(TestCase): |
627 | 627 | |
628 | 628 | sched = Schedule.objects.order_by('-created')[0] |
629 | 629 | shs_list = sched.shs.all() |
630 | - nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PLANNED]) | |
630 | + nbPlanned = len([shs for shs in shs_list if shs.status == Sequence.PENDING]) | |
631 | 631 | |
632 | 632 | seq1 = Sequence.objects.get(name="seq1") |
633 | 633 | seq2 = Sequence.objects.get(name="seq2") | ... | ... |
src/scripts/delete_all_requests.sh
1 | -# This mini-script deletes all your alerts, requests, alerts, albums and plans in db | |
1 | +# This mini-script deletes all your alerts, requests, alerts, albums, plans, shs and schedules in db | |
2 | 2 | # You need to have a root user with no password on your DB |
3 | 3 | |
4 | 4 | SCRIPT_PATH=$0 |
... | ... | @@ -10,8 +10,10 @@ MYSQL=`grep "MYSQL = " pyros/settings.py` |
10 | 10 | MYSQL=${MYSQL##* } |
11 | 11 | MYSQL=${MYSQL%?} |
12 | 12 | |
13 | +REQUEST="delete from alert ; delete from plan ; delete from album ; delete from sequence ; delete from alert ; delete from request ; delete from schedule_has_sequences ; delete from schedule" | |
14 | + | |
13 | 15 | if [ "$MYSQL" == "True" ]; then |
14 | - mysql -u root -e "delete from alert ; delete from plan ; delete from album ; delete from sequence ; delete from alert ; delete from request ; delete from schedule_has_sequences" pyros | |
16 | + mysql -u root -e "$REQUEST" pyros | |
15 | 17 | else |
16 | - sqlite3 db.sqlite3 "delete from alert ; delete from plan ; delete from album ; delete from sequence ; delete from alert ; delete from request ; delete from schedule_has_sequences" | |
18 | + sqlite3 db.sqlite3 "$REQUEST" | |
17 | 19 | fi | ... | ... |