Commit 64fc9a893e76108106d0fde505d9a40e7e075156

Authored by Etienne Pallier
1 parent 47c4dbef
Exists in master and in 1 other branch dev

- un peu de refactoring sur le Scheduler

- quelques nouveaux activity diagrams pour le Scheduler
doc/uml/activities/alert_manager/check_alert_validity_act.png 0 → 100644

33.2 KB

doc/uml/activities/alert_manager/retrieve_alert_act.txt
... ... @@ -2,7 +2,7 @@
2 2  
3 3 title Retrieve alerts
4 4  
5   -(*) --> "Read files names in events_received directory"
  5 +(*) --> "Read file names in events_received directory"
6 6  
7 7 --> if "New file detected" then
8 8 --> [yes] "Check alert validity"
... ...
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
... ...
doc/uml/activities/routine_manager/build_request_act.png 0 → 100644

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
... ... @@ -1,8 +0,0 @@
1   -@startuml
2   -
3   -title Compute schedule
4   -
5   -(*) --> "See specification document 'Module PLANNING'"
6   - --> (*)
7   -
8   -@enduml
9 0 \ No newline at end of file
doc/uml/activities/scheduler/compute_schedule_act_.txt 0 → 100644
... ... @@ -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
... ...
doc/uml/activities/scheduler/make_schedule_act.txt 0 → 100644
... ... @@ -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
... ...
doc/uml/usecases/alert_manager_usc.png 0 → 100644

34 KB

doc/uml/usecases/analyzer_usc.png 0 → 100644

11.2 KB

doc/uml/usecases/majordome_usc.png 0 → 100644

28.5 KB

doc/uml/usecases/majordome_usc.txt
  1 +TODO:
  2 +- start AlertManager et Monitoring
  3 +- lancer le premier Scheduling
  4 +- ...
  5 +Il faut récupérer ici plein de fonctions attribuées (par erreur de conception) à Monitoring
  6 +
  7 +
1 8 @startuml
2 9  
3 10 title Majordome
... ...
doc/uml/usecases/monitoring_usc.png 0 → 100644

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
... ...
doc/uml/usecases/observation_manager_usc.png 0 → 100644

13.2 KB

doc/uml/usecases/routine_manager_usc.png 0 → 100644

33.9 KB

doc/uml/usecases/scheduler_usc.png 0 → 100644

20.3 KB

doc/uml/usecases/user_manager_usc.png 0 → 100644

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
... ...