Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into jbod
[simgrid.git] / examples / python / comm-failure / comm-failure.py
1 # Copyright (c) 2010-2023. 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 import sys
7
8 from simgrid import Engine, Actor, Comm, NetZone, Link, LinkInRoute, Mailbox, this_actor, NetworkFailureException
9
10
11 def sender(mailbox1_name: str, mailbox2_name: str) -> None:
12     mailbox1: Mailbox = Mailbox.by_name(mailbox1_name)
13     mailbox2: Mailbox = Mailbox.by_name(mailbox2_name)
14
15     this_actor.info(f"Initiating asynchronous send to {mailbox1.name}")
16     comm1: Comm = mailbox1.put_async(666, 5)
17
18     this_actor.info(f"Initiating asynchronous send to {mailbox2.name}")
19     comm2: Comm = mailbox2.put_async(666, 2)
20
21     this_actor.info("Calling wait_any..")
22     pending_comms = [comm1, comm2]
23     try:
24         index = Comm.wait_any([comm1, comm2])
25         this_actor.info(f"Wait any returned index {index} (comm to {pending_comms[index].mailbox.name})")
26     except NetworkFailureException:
27         this_actor.info("Sender has experienced a network failure exception, so it knows that something went wrong")
28         this_actor.info("Now it needs to figure out which of the two comms failed by looking at their state:")
29
30     this_actor.info(f"  Comm to {comm1.mailbox.name} has state: {comm1.state_str}")
31     this_actor.info(f"  Comm to {comm2.mailbox.name} has state: {comm2.state_str}")
32
33     try:
34         comm1.wait()
35     except NetworkFailureException as err:
36         this_actor.info(f"Waiting on a FAILED comm raises an exception: '{err}'")
37
38     this_actor.info("Wait for remaining comm, just to be nice")
39     pending_comms.pop(0)
40     try:
41         Comm.wait_any(pending_comms)
42     except Exception as e:
43         this_actor.warning(str(e))
44
45
46 def receiver(mailbox_name: str) -> None:
47     mailbox: Mailbox = Mailbox.by_name(mailbox_name)
48     this_actor.info(f"Receiver posting a receive ({mailbox_name})...")
49     try:
50         mailbox.get()
51         this_actor.info(f"Receiver has received successfully ({mailbox_name})!")
52     except NetworkFailureException:
53         this_actor.info(f"Receiver has experience a network failure exception ({mailbox_name})")
54
55
56 def link_killer(link_name: str) -> None:
57     link_to_kill = Link.by_name(link_name)
58     this_actor.sleep_for(10.0)
59     this_actor.info(f"Turning off link '{link_to_kill.name}'")
60     link_to_kill.turn_off()
61
62 def main():
63     e = Engine(sys.argv)
64     zone: NetZone = NetZone.create_full_zone("AS0")
65     host1 = zone.create_host("Host1", "1f")
66     host2 = zone.create_host("Host2", "1f")
67     host3 = zone.create_host("Host3", "1f")
68
69     link_to_2 = zone.create_link("link_to_2", "1bps").seal()
70     link_to_3 = zone.create_link("link_to_3", "1bps").seal()
71
72     zone.add_route(host1, host2, [link_to_2])
73     zone.add_route(host1, host3, [link_to_3])
74     zone.seal()
75
76     Actor.create("Sender", host1, sender, "mailbox2", "mailbox3")
77     Actor.create("Receiver-1", host2, receiver, "mailbox2").daemonize()
78     Actor.create("Receiver-2", host3, receiver, "mailbox3").daemonize()
79     Actor.create("LinkKiller", host2, link_killer, "link_to_2").daemonize()
80
81     e.run()
82
83
84 if __name__ == "__main__":
85     main()