Commit d467c6d88506d48fb0c8e3af2dd76d107b522de1
1 parent
4ba41afb
Exists in
dev
Optimisation log_agent_status() (ex update_survey())
+ bugfix import celme + activity diag
Showing
5 changed files
with
101 additions
and
37 deletions
Show diff stats
README.md
... | ... | @@ -73,9 +73,7 @@ Author: E. Pallier |
73 | 73 | |
74 | 74 | VERSION: 0.20.31 |
75 | 75 | |
76 | -Comment: AgentM | |
77 | - | |
78 | - - routine_process() : envoi commande n'est plus bloquant | |
76 | +Comment: Optimisation log_agent_status() (ex update_survey()) | |
79 | 77 | |
80 | 78 | - Scenario de test : |
81 | 79 | - lancer agents A et B en mode simu (option -t): ./pyros.py -t start agentA,agentB |
... | ... | @@ -89,7 +87,9 @@ Comment: AgentM |
89 | 87 | (ou encore: activer l'environnement virtuel, puis lancer "cd src/agent/ ; ./AgentA.py configfile") |
90 | 88 | - pour utiliser thread ou processus : il suffit de mettre la constante RUN_IN_THREAD de AgentA (ou AgentB ou AgentX) à False ou True |
91 | 89 | |
92 | - - Autres remarques: | |
90 | + - Historique des nouveautés : | |
91 | + - AgentM (début) pour remplacer progressivement l'agent monitoring | |
92 | + - routine_process() : envoi commande n'est plus bloquant | |
93 | 93 | - pyros.py peut lancer plusieurs agents (A et B) en même temps |
94 | 94 | - run(N) : run only N iterations |
95 | 95 | - send_command() implemented | ... | ... |
src/agent/Agent.py
... | ... | @@ -72,12 +72,12 @@ print() |
72 | 72 | |
73 | 73 | # --- GENERAL PURPOSE IMPORT --- |
74 | 74 | #from __future__ import absolute_import |
75 | +import utils.Logger as L | |
75 | 76 | import platform |
76 | 77 | import random |
77 | 78 | from threading import Thread |
78 | 79 | import threading, multiprocessing |
79 | 80 | import time |
80 | -import utils.Logger as L | |
81 | 81 | import socket |
82 | 82 | #import ctypes |
83 | 83 | #import copy |
... | ... | @@ -185,19 +185,82 @@ class StoppableThreadEvenWhenSleeping(threading.Thread): |
185 | 185 | class Agent: |
186 | 186 | """ |
187 | 187 | Behavior of an agent: |
188 | + - If idle : | |
189 | + - still does routine_process() and general_process() | |
190 | + - does not do specific_process() | |
188 | 191 | - Once a command has been sent to another agent : |
189 | - - It waits for the end of execution of the command and get its result | |
190 | - - If command is timed out or has been skipped or killed, then same command will be re-executed at next iteration | |
191 | - - Then only, it goes to next iteration | |
192 | + - It waits (non blocking) for the end of execution of the command and get its result | |
193 | + - If command is timed out or has been skipped or killed, then it is NOT re-executed at next iteration (except if needed explicitely) | |
192 | 194 | """ |
193 | 195 | |
196 | + """ | |
197 | + PLANTUML ACTIVITY DIAGRAM | |
198 | + # (http://plantuml.com/fr/activity-diagram-legacy) | |
199 | + """ | |
200 | + | |
201 | + """ | |
202 | + @startuml | |
203 | + version | |
204 | + @enduml | |
205 | + """ | |
206 | + | |
207 | + """ | |
208 | + @startuml | |
209 | + | |
210 | + title | |
211 | + __** Agent.run() function activity diagram **__ | |
212 | + end title | |
213 | + | |
214 | + skinparam activity { | |
215 | + StartColor red | |
216 | + EndColor Silver | |
217 | + BackgroundColor Peru | |
218 | + BackgroundColor<< Begin >> Olive | |
219 | + BorderColor Peru | |
220 | + FontName Impact | |
221 | + } | |
222 | + | |
223 | + (*) --> load_config() | |
224 | + | |
225 | + --> init() | |
226 | + | |
227 | + partition infinite_loop { | |
228 | + ---> "reload_config()" | |
229 | + note right | |
230 | + only if changed | |
231 | + end note | |
232 | + | |
233 | + --> log_agent_status() | |
234 | + note right | |
235 | + Log this agent status in DB | |
236 | + end note | |
237 | + | |
238 | + --> routine_process() | |
239 | + | |
240 | + --> cmd = get_next_valid_command() | |
241 | + --> cmd = command_process(cmd) | |
242 | + note right | |
243 | + only if there is a command | |
244 | + end note | |
245 | + } | |
246 | + | |
247 | + If "NEW ITERATION ?" then | |
248 | + --> [Yes] "reload_config()" | |
249 | + else | |
250 | + --> (*) | |
251 | + Endif | |
252 | + | |
253 | + @enduml | |
254 | + """ | |
255 | + | |
256 | + | |
194 | 257 | |
195 | 258 | # Maximum duration of this agent (only for SIMULATION mode) |
196 | 259 | # If set to None, it will never exit except if asked (or CTRL-C) |
197 | 260 | # If set to 20, it will exit after 20s |
198 | 261 | SIMULATOR_MAX_DURATION_SEC = None |
199 | 262 | #SIMULATOR_MAX_DURATION_SEC = 30 |
200 | - | |
263 | + | |
201 | 264 | # FOR TEST ONLY |
202 | 265 | # Run this agent in simulator mode |
203 | 266 | SIMULATOR_MODE = True |
... | ... | @@ -345,10 +408,10 @@ class Agent: |
345 | 408 | self.RUN_IN_THREAD = RUN_IN_THREAD |
346 | 409 | self.set_status(self.STATUS_LAUNCH) |
347 | 410 | self.set_idle() |
348 | - | |
411 | + | |
349 | 412 | self._log = LogPyros() |
350 | 413 | self._log.set_agent_alias(self.name) |
351 | - | |
414 | + | |
352 | 415 | #self.set_mode(self.MODE_IDLE) |
353 | 416 | if not config_filename: |
354 | 417 | config_filename = self.DEFAULT_CONFIG_FILE_NAME |
... | ... | @@ -379,11 +442,11 @@ class Agent: |
379 | 442 | #if len(tmp) == 0: |
380 | 443 | #nb_agents = AgentSurvey.objects.filter(name=self.name).count() |
381 | 444 | #if nb_agents == 0: |
382 | - if not AgentSurvey.objects.filter(name=self.name).exists(): | |
445 | + if AgentSurvey.objects.filter(name=self.name).exists(): | |
446 | + self._agent_survey = AgentSurvey.objects.get(name=self.name) | |
447 | + else: | |
383 | 448 | self._agent_survey = AgentSurvey.objects.create(name=self.name, validity_duration_sec=60, mode=self.mode, status=self.status) |
384 | - self.printd("Agent survey is", self._agent_survey) | |
385 | - #self._agent_survey = AgentSurvey(name=self.name, validity_duration_sec=60, mode=self.mode, status=self.status) | |
386 | - #self._agent_survey.save() | |
449 | + self.printd("Agent survey is", self._agent_survey) | |
387 | 450 | |
388 | 451 | def __repr__(self): |
389 | 452 | return "I am agent " + self.name |
... | ... | @@ -417,7 +480,7 @@ class Agent: |
417 | 480 | """ |
418 | 481 | |
419 | 482 | self.load_config() |
420 | - | |
483 | + | |
421 | 484 | if self.SIMULATOR_MODE: |
422 | 485 | self._log.print("[IN SIMULATOR MODE]") |
423 | 486 | else: |
... | ... | @@ -440,11 +503,6 @@ class Agent: |
440 | 503 | Command.delete_pending_commands_for_agent(self.name) |
441 | 504 | |
442 | 505 | ''' |
443 | - self.printd() | |
444 | - self.printd(self) | |
445 | - self.printd("FOR REAL ?", self.FOR_REAL) | |
446 | - self.printd("DB3 used is:", djangosettings.DATABASES["default"]["NAME"]) | |
447 | - | |
448 | 506 | # SETUP |
449 | 507 | try: |
450 | 508 | self.config = get_object_or_404(Config, id=1) |
... | ... | @@ -467,7 +525,7 @@ class Agent: |
467 | 525 | |
468 | 526 | # Bad number of iterations, so exit |
469 | 527 | if nb_iter is not None: |
470 | - if nb_iter <= 0: break | |
528 | + if nb_iter <= 0: break | |
471 | 529 | # Number of iterations asked is reached, so exit |
472 | 530 | if self._iter_num > nb_iter: |
473 | 531 | print(f"Exit because number of iterations asked ({nb_iter}) has been reached") |
... | ... | @@ -488,8 +546,8 @@ class Agent: |
488 | 546 | |
489 | 547 | self.load_config() # only if changed |
490 | 548 | |
491 | - # Update my current mode and status in DB | |
492 | - self.update_survey() | |
549 | + # Log this agent status (update my current mode and status in DB) | |
550 | + self.log_agent_status() | |
493 | 551 | |
494 | 552 | self.printd("------START COMMMAND PROCESSING------") |
495 | 553 | |
... | ... | @@ -500,18 +558,17 @@ class Agent: |
500 | 558 | #Command.purge_old_commands_for_agent(self.name) |
501 | 559 | self.purge_old_commands_sent_to_me() |
502 | 560 | |
561 | + # ROUTINE process | |
562 | + #if self.is_active(): | |
563 | + self.routine_process() | |
564 | + #self.printd("I am IDLE, so I bypass the routine_process (do not send any new command)") | |
565 | + | |
503 | 566 | # Get next command to execute |
504 | 567 | cmd = self.get_next_valid_command() |
505 | 568 | #if cmd: cmd = self.general_process(cmd) |
506 | - | |
507 | 569 | # Process this (next) command (if exists) |
508 | 570 | if cmd: cmd = self.command_process(cmd) |
509 | 571 | |
510 | - # ROUTINE process | |
511 | - #if self.is_active(): | |
512 | - self.routine_process() | |
513 | - #self.printd("I am IDLE, so I bypass the routine_process (do not send any new command)") | |
514 | - | |
515 | 572 | self.printd("------END COMMMAND PROCESSING------") |
516 | 573 | |
517 | 574 | #self.waitfor(self.mainloop_waittime) |
... | ... | @@ -519,7 +576,7 @@ class Agent: |
519 | 576 | self.print("-"*20, "MAIN LOOP ITERATION (END)", "-"*20) |
520 | 577 | #self.do_log(LOG_DEBUG, "Ending main loop iteration") |
521 | 578 | |
522 | - # Exit if max duration is reached | |
579 | + # (simulator only) Exit if max duration is reached | |
523 | 580 | if self.SIMULATOR_MAX_DURATION_SEC and (time.time()-start_time > self.SIMULATOR_MAX_DURATION_SEC): |
524 | 581 | self.print("Exit because of max duration set to ", self.SIMULATOR_MAX_DURATION_SEC, "s") |
525 | 582 | self.kill_running_specific_cmd_if_exists() |
... | ... | @@ -782,15 +839,21 @@ class Agent: |
782 | 839 | self._log.set_home(home) |
783 | 840 | |
784 | 841 | |
785 | - def update_survey(self): | |
786 | - self.printd("Updating the survey database table...") | |
842 | + #def update_survey(self): | |
843 | + def log_agent_status(self): | |
844 | + """ | |
845 | + Save (update) this agent current mode and status in DB | |
846 | + """ | |
847 | + self.printd("Updating the agent survey database table...") | |
787 | 848 | #self.printd("- fetching table line for agent", self.name) |
788 | 849 | # only necessary when using process (not necessary with threads) |
789 | 850 | #with transaction.atomic(): |
790 | - self._agent_survey = AgentSurvey.objects.get(name=self.name) | |
851 | + #self._agent_survey = AgentSurvey.objects.get(name=self.name) | |
791 | 852 | self._agent_survey.mode = self.mode |
792 | 853 | self._agent_survey.status = self.status |
793 | - self._agent_survey.save() | |
854 | + #self._agent_survey.save() | |
855 | + self._agent_survey.save(update_fields=["mode", "status"]) | |
856 | + | |
794 | 857 | |
795 | 858 | """ |
796 | 859 | def send_command(self, cmd_name): | ... | ... |
src/agent/AgentA.py
... | ... | @@ -69,6 +69,7 @@ class AgentA(Agent): |
69 | 69 | def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True): |
70 | 70 | if name is None: name = self.__class__.__name__ |
71 | 71 | super().__init__(name, config_filename, RUN_IN_THREAD) |
72 | + self._log.print(f"init done for {name}") | |
72 | 73 | |
73 | 74 | # @override |
74 | 75 | def init(self): | ... | ... |
39.4 KB
src/agent/logpyros.py