Commit 64fc9a893e76108106d0fde505d9a40e7e075156
1 parent
47c4dbef
Exists in
master
and in
1 other branch
- un peu de refactoring sur le Scheduler
- quelques nouveaux activity diagrams pour le Scheduler
Showing
20 changed files
with
192 additions
and
23 deletions
Show diff stats
33.2 KB
doc/uml/activities/alert_manager/retrieve_alert_act.txt
doc/uml/activities/monitoring/init_system_act.txt
1 | +TODO: | |
2 | +- start Monitoring | |
3 | +- start a scheduling (en faisant un "start Majordome" et non pas un "start Monitoring", car c'est le majordome qui doit lancer le premier scheduling) | |
4 | +- tester si la nuit a déjà commencé !! (ça sera le cas si on redémarre le système pendant la nuit) | |
5 | + | |
1 | 6 | @startuml |
2 | 7 | |
3 | 8 | title Initialize system | ... | ... |
27.3 KB
doc/uml/activities/routine_manager/see_sequences_result_act.txt
1 | 1 | @startuml |
2 | 2 | |
3 | 3 | (*) --> if "Sequence is finished" |
4 | - --> [Yes] "Get images and analyses files names" | |
4 | + --> [Yes] "Get images [and analyses files names]" | |
5 | 5 | if "Files exist" |
6 | - --> [Yes] "Display images and analyses" | |
6 | + --> [Yes] "Display images [and analyses]" | |
7 | 7 | --> (*) |
8 | 8 | else |
9 | 9 | --> [No] "Display error message" | ... | ... |
doc/uml/activities/scheduler/compute_schedule_act.txt deleted
... | ... | @@ -0,0 +1,47 @@ |
1 | +@startuml | |
2 | + | |
3 | +legend right | |
4 | + Short | |
5 | + legend | |
6 | +endlegend | |
7 | + | |
8 | +title **Scheduler.compute_schedule()** | |
9 | + | |
10 | +skinparam activity { | |
11 | + 'StartColor red | |
12 | + 'BarColor SaddleBrown | |
13 | + 'EndColor Silver | |
14 | + 'BackgroundColor Peru | |
15 | + BackgroundColor<<MODULE>> Peru | |
16 | + 'BorderColor Peru | |
17 | + 'FontName Impact | |
18 | +} | |
19 | + | |
20 | +(*) --> "//# Order schedule sequences according to efficiency criteria (priority, set time, ...)//" <<MODULE>> | |
21 | + | |
22 | + --> "//# Create a unique big empty available interval that takes all the night duration [plan_start,plan_end]// \n | |
23 | + intervals = Interval(schedule.plan_start, schedule.plan_end)" | |
24 | + | |
25 | + --> "//# Remove invalid sequences from schedule, and mark them INVALID// \n | |
26 | + A sequence is invalid if: | |
27 | + - sequence.jd1 < 0 | |
28 | + - OR sequence.jd2 < 0 | |
29 | + - OR sequence.duration <= 0 | |
30 | + - OR sequence.jd2 - sequence.jd1 < sequence.duration \n\n | |
31 | + **remove_invalid_sequences()**\l" <<MODULE>> | |
32 | + | |
33 | + --> "//# **TODO:** Determine priorities according to SP, user, ...// | |
34 | + **determine_priorities()**\l" as B1 <<MODULE>> | |
35 | + | |
36 | + --> "//# Remove non eligible sequences from schedule// | |
37 | + **remove_non_eligible_sequences()**\l" <<MODULE>> | |
38 | + | |
39 | + --> "//# Sort sequences according to highest priority and soonest JD2// | |
40 | + **sort_by_jd2_and_priorities()**\l" <<MODULE>> | |
41 | + | |
42 | + --> "//# Try to place sorted sequences in schedule one by one in available intervals (shift placed sequences if necessary)// | |
43 | + **place_sequences()**\l" <<MODULE>> | |
44 | + | |
45 | + --> (*) | |
46 | + | |
47 | +@enduml | |
0 | 48 | \ No newline at end of file | ... | ... |
doc/uml/activities/scheduler/copy_from_previous_schedule_act.txt
0 → 100644
... | ... | @@ -0,0 +1,34 @@ |
1 | +@startuml | |
2 | + | |
3 | +legend right | |
4 | + Short | |
5 | + legend | |
6 | +endlegend | |
7 | + | |
8 | +title **Scheduler.copy_from_previous_schedule()** | |
9 | + | |
10 | +skinparam activity { | |
11 | + 'StartColor red | |
12 | + 'BarColor SaddleBrown | |
13 | + 'EndColor Silver | |
14 | + 'BackgroundColor Peru | |
15 | + BackgroundColor<<START>> Peru | |
16 | + 'BorderColor Peru | |
17 | + 'FontName Impact | |
18 | +} | |
19 | + | |
20 | +(*) --> "//Copy needed data from previous schedule : EXECUTED sequences, plan_night_start, plan_end//" <<START>> | |
21 | + | |
22 | + --> previous_sched = get last schedule from DB | |
23 | + | |
24 | + --> "previous_exc_seq = get all EXECUTED sequences from previous_sched\n | |
25 | + Associate each EXECUTED sequence to the new schedule (in DB)\l" | |
26 | + | |
27 | + --> "schedule.plan_night_start = previous_sched.plan_night_start\n | |
28 | + schedule.plan_end = previous_sched.plan_end\n | |
29 | + //Schedule must start in MAX_OVERHEAD seconds://\n | |
30 | + schedule.plan_start = now + MAX_OVERHEAD\l" | |
31 | + | |
32 | + --> (*) | |
33 | + | |
34 | +@enduml | |
0 | 35 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,40 @@ |
1 | +@startuml | |
2 | + | |
3 | +'skinparam backgroundColor #AAFFFF | |
4 | + | |
5 | +skinparam activity { | |
6 | + 'StartColor red | |
7 | + 'BarColor SaddleBrown | |
8 | + 'EndColor Silver | |
9 | + 'BackgroundColor Peru | |
10 | + BackgroundColor<<MODULE>> Peru | |
11 | + 'BorderColor Peru | |
12 | + 'FontName Impact | |
13 | +} | |
14 | + | |
15 | + | |
16 | + | |
17 | + | |
18 | +title **Scheduler.make_schedule()** (//Make Schedule//) | |
19 | + | |
20 | +(*) --> "//Schedule Creation// \n//see specification document 'Module PLANNING'//" <<MODULE>> | |
21 | + | |
22 | + --> if "First Schedule" then | |
23 | + --> [True] "schedule.plan_night_start = schedule.plan_start" | |
24 | + --> "sequences = {all OBSERVABLE sequences}" as A2 | |
25 | + else | |
26 | + --> [False] "//Copy needed data from previous schedule : EXECUTED sequences, plan_night_start, plan_end// | |
27 | + copy_from_previous_schedule()\l" <<MODULE>> | |
28 | + endif | |
29 | + --> A2 | |
30 | + --> "//Add to each sequence its schedule id:// | |
31 | + sequences = [(sequence, shs) for sequence in sequences]" | |
32 | + | |
33 | + --> "//Order schedule sequences according to efficiency criteria (priority, set time, ...)// | |
34 | + compute_schedule()\l" <<MODULE>> | |
35 | + | |
36 | + --> Save schedule | |
37 | + | |
38 | + --> (*) | |
39 | + | |
40 | +@enduml | |
0 | 41 | \ No newline at end of file | ... | ... |
34 KB
11.2 KB
28.5 KB
doc/uml/usecases/majordome_usc.txt
52.5 KB
doc/uml/usecases/monitoring_usc.txt
1 | +TODO: | |
2 | +Le Monitor fait bcp trop de choses qui dépassent sa responsabilité. | |
3 | +Il faut passer quelques unes de ces fonctions au Majordome: | |
4 | +- démarrer le AlertManager | |
5 | +- initialize instruments | |
6 | +- config instruments | |
7 | +- update soft versions | |
8 | +- compute night start&end | |
9 | + | |
1 | 10 | @startuml |
2 | 11 | |
3 | 12 | title Monitoring | ... | ... |
13.2 KB
33.9 KB
20.3 KB
30.3 KB
src/scheduler/Scheduler.py
... | ... | @@ -153,16 +153,24 @@ class Scheduler(): |
153 | 153 | global SIMULATION |
154 | 154 | SIMULATION = False |
155 | 155 | |
156 | - if first_schedule is False: | |
157 | - self.copy_from_previous_schedule() | |
158 | - else: | |
156 | + #if first_schedule is False: | |
157 | + if first_schedule: | |
159 | 158 | self.schedule.plan_night_start = self.schedule.plan_start |
159 | + else: | |
160 | + self.copy_from_previous_schedule() | |
160 | 161 | |
161 | 162 | self.sequences = list(Sequence.objects.filter(status=Sequence.OBSERVABLE)) |
163 | + # Add to each sequence its schedule id | |
162 | 164 | shs_list = [] |
165 | + | |
166 | + #EP improved: | |
167 | + ''' | |
163 | 168 | for sequence in self.sequences: |
164 | 169 | shs_list.append(ScheduleHasSequences(sequence=sequence, schedule=self.schedule)) |
165 | 170 | self.sequences = [(sequence, shs_list[index]) for index, sequence in enumerate(self.sequences)] |
171 | + ''' | |
172 | + self.sequences = [(sequence, ScheduleHasSequences(sequence=sequence, schedule=self.schedule)) for sequence in self.sequences] | |
173 | + | |
166 | 174 | self.compute_schedule() |
167 | 175 | self.save_schedule() |
168 | 176 | return self.schedule |
... | ... | @@ -171,14 +179,20 @@ class Scheduler(): |
171 | 179 | ''' |
172 | 180 | Copy needed information from the previous schedule : |
173 | 181 | - gets the executed sequences from the previous schedule and copy them into the new schedule |
174 | - - gets plan_start and plan_end | |
175 | - - computes new plan_restart | |
182 | + - gets plan_night_start and plan_end | |
183 | + - computes new plan_restart (plan_start) | |
176 | 184 | |
177 | 185 | shs means 'ScheduleHasSequences' |
186 | + | |
187 | + Side effects: | |
188 | + - create new shs entries | |
178 | 189 | ''' |
179 | 190 | |
191 | + # Get all EXECUTED sequences from last schedule | |
180 | 192 | previous_sched = Schedule.objects.order_by('-created')[1] |
181 | 193 | previous_exc_seq = previous_sched.sequences.filter(status=Sequence.EXECUTED) |
194 | + | |
195 | + # Associate each EXECUTED sequence to the new schedule in DB (by creating a new shs entry for each sequence) | |
182 | 196 | for seq in previous_exc_seq: |
183 | 197 | shs = seq.shs |
184 | 198 | shs.pk = None |
... | ... | @@ -217,19 +231,37 @@ class Scheduler(): |
217 | 231 | return (self.schedule, self.sequences) |
218 | 232 | |
219 | 233 | def compute_schedule(self): |
234 | + #EP TODO: est-on sur ici que self.intervals est VIDE ??? | |
235 | + # Create a unique big empty available interval that takes all the night duration [plan_start,plan_end] | |
220 | 236 | self.intervals.append( |
221 | 237 | Interval(self.schedule.plan_start, self.schedule.plan_end)) |
222 | - self.check_sequences_validity() | |
238 | + | |
239 | + ''' | |
240 | + EP: | |
241 | + Uniquement à cause des sequences de Alain Klotz (qui sont parfois invalides pour Pyros) ??? | |
242 | + TODO: cette étape pourra être supprimée en production, car les sequences fabriquées par Pyros seront valides | |
243 | + ''' | |
244 | + #EP renamed | |
245 | + #self.check_sequences_validity() | |
246 | + self.remove_invalid_sequences() | |
247 | + | |
223 | 248 | self.determine_priorities() |
224 | - self.remove_not_eligible_sequences() | |
249 | + | |
250 | + self.remove_non_eligible_sequences() | |
251 | + | |
225 | 252 | self.sort_by_jd2_and_priorities() |
226 | - self.organize_sequences() | |
253 | + | |
254 | + #EP renamed: | |
255 | + #self.organize_sequences() | |
256 | + self.place_sequences() | |
227 | 257 | |
228 | - def check_sequences_validity(self): | |
258 | + #EP renamed: | |
259 | + #def check_sequences_validity(self): | |
260 | + def remove_invalid_sequences(self): | |
229 | 261 | ''' |
230 | 262 | Checks come sequence attributes to validate their integrity |
231 | 263 | |
232 | - :side-effect : | |
264 | + :side-effects : | |
233 | 265 | - remove invalid sequences from self.sequences |
234 | 266 | - set INVALID status for invalid sequences in DB |
235 | 267 | ''' |
... | ... | @@ -250,7 +282,7 @@ class Scheduler(): |
250 | 282 | # TODO: définir comment on calcule la priorité |
251 | 283 | pass |
252 | 284 | |
253 | - def remove_not_eligible_sequences(self): | |
285 | + def remove_non_eligible_sequences(self): | |
254 | 286 | ''' |
255 | 287 | Computes overlap between [jd1; jd2] and [plan_start; plan_end] |
256 | 288 | Removes from self.sequences all the sequences that cannot be observed between plan_start and plan_end |
... | ... | @@ -258,6 +290,7 @@ class Scheduler(): |
258 | 290 | |
259 | 291 | :side-effect : |
260 | 292 | - remove unwanted sequences from self.sequences |
293 | + - mark them as UNPLANNABLE (in DB) | |
261 | 294 | ''' |
262 | 295 | |
263 | 296 | ''' Note (1) ''' |
... | ... | @@ -280,7 +313,9 @@ class Scheduler(): |
280 | 313 | self.sequences.sort(key=lambda x: x[0].jd2) |
281 | 314 | self.sequences.sort(key=lambda x: x[0].priority) |
282 | 315 | |
283 | - def organize_sequences(self): | |
316 | + #EP renamed | |
317 | + #def organize_sequences(self): | |
318 | + def place_sequences(self): | |
284 | 319 | ''' |
285 | 320 | Main function of the Scheduler |
286 | 321 | Arrange a maximum of observable sequences in the planning | ... | ... |