Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Pylint examples/*.py.
[simgrid.git] / examples / python / platform-failures / platform-failures.py
1 ## Copyright (c) 2007-2022. The SimGrid Team. All rights reserved.
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the license (GNU LGPL) which comes with this package.
5
6 """
7 This example shows how to work with the state profile of a host or a link,
8 specifying when the resource must be turned on or off.
9
10 To set such a profile, the first way is to use a file in the XML, while the second is to use the programmatic
11 interface, as exemplified in the main() below. Once this profile is in place, the resource will automatically
12 be turned on and off.
13
14 The actors running on a host that is turned off are forcefully killed
15 once their on_exit callbacks are executed. They cannot avoid this fate.
16 Since we specified on_failure="RESTART" for each actors in the XML file,
17 they will be automatically restarted when the host starts again.
18
19 Communications using failed links will .. fail.
20 """
21
22 import sys
23 from simgrid import Actor, Engine, Host, Mailbox, this_actor, NetworkFailureException, TimeoutException
24
25 def master(* args):
26     assert len(args) == 4, f"Actor master requires 4 parameters, but got {len(args)} ones."
27     tasks_count = int(args[0])
28     comp_size = int(args[1])
29     comm_size = int(args[2])
30     workers_count = int(args[3])
31
32     this_actor.info(f"Got {workers_count} workers and {tasks_count} tasks to process")
33
34     for i in range(tasks_count): # For each task to be executed:
35         # - Select a worker in a round-robin way
36         mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
37         try:
38             this_actor.info(f"Send a message to {mailbox.name}")
39             mailbox.put(comp_size, comm_size, 10.0)
40             this_actor.info(f"Send to {mailbox.name} completed")
41         except TimeoutException:
42             this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
43         except NetworkFailureException:
44             this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
45
46     this_actor.info("All tasks have been dispatched. Let's tell everybody the computation is over.")
47     for i in range(workers_count):
48         # - Eventually tell all the workers to stop by sending a "finalize" task
49         mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
50         try:
51             mailbox.put(-1.0, 0, 1.0)
52         except TimeoutException:
53             this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
54         except NetworkFailureException:
55             this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
56
57     this_actor.info("Goodbye now!")
58
59 def worker(* args):
60     assert len(args) == 1, "Expecting one parameter"
61     my_id = int(args[0])
62
63     mailbox = Mailbox.by_name(f"worker-{my_id}")
64     done = False
65     while not done:
66         try:
67             this_actor.info(f"Waiting a message on {mailbox.name}")
68             compute_cost = mailbox.get()
69             if compute_cost > 0: # If compute_cost is valid, execute a computation of that cost
70                 this_actor.info("Start execution...")
71                 this_actor.execute(compute_cost)
72                 this_actor.info("Execution complete.")
73             else: # Stop when receiving an invalid compute_cost
74                 this_actor.info("I'm done. See you!")
75                 done = True
76         except NetworkFailureException:
77             this_actor.info("Mmh. Something went wrong. Nevermind. Let's keep going!")
78
79 def sleeper():
80     this_actor.info("Start sleeping...")
81     this_actor.sleep_for(1)
82     this_actor.info("done sleeping.")
83
84 if __name__ == '__main__':
85     assert len(sys.argv) > 2, f"Usage: python app-masterworkers.py platform_file deployment_file"
86
87     e = Engine(sys.argv)
88
89     # This is how to attach a profile to an host that is created from the XML file.
90     # This should be done before calling load_platform(), as the on_creation() event is fired when loading the platform.
91     # You can never set a new profile to a resource that already have one.
92     def on_creation(host):
93         if host.name == "Bourrassa":
94             host.set_state_profile("67 0\n70 1\n", 0)
95     Host.on_creation_cb(on_creation)
96
97     e.load_platform(sys.argv[1])
98
99     e.register_actor("master", master)
100     e.register_actor("worker", worker)
101     e.load_deployment(sys.argv[2])
102
103     # Add a new host programatically, and attach a state profile to it
104     lili = e.netzone_root.create_host("Lilibeth", 1e15)
105     lili.set_state_profile("4 0\n5 1\n", 10)
106     lili.seal()
107
108     # Create an actor on that new host, to monitor its own state
109     actor = Actor.create("sleeper", lili, sleeper)
110     actor.set_auto_restart(True)
111
112     e.run()
113
114     this_actor.info(f"Simulation time {e.clock:.4f}")