Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
smpi: fix issue with message IDs. In case of persistent request reused multiple times...
[simgrid.git] / examples / cpp / comm-failure / s4u-comm-failure.cpp
1 /* Copyright (c) 2021-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 /* This example shows how to react to a failed communication, which occurs when a link is turned off,
7  * or when the actor with whom you communicate fails because its host is turned off.
8  */
9
10 #include <simgrid/s4u.hpp>
11
12 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_comm_failure, "Messages specific for this s4u example");
13 namespace sg4 = simgrid::s4u;
14
15 class Sender {
16   std::string mailbox1_name;
17   std::string mailbox2_name;
18
19 public:
20   Sender(const std::string& mailbox1_name, const std::string& mailbox2_name)
21       : mailbox1_name(mailbox1_name), mailbox2_name(mailbox2_name)
22   {
23   }
24
25   void operator()() const
26   {
27     auto* mailbox1 = sg4::Mailbox::by_name(mailbox1_name);
28     auto* mailbox2 = sg4::Mailbox::by_name(mailbox2_name);
29
30     XBT_INFO("Initiating asynchronous send to %s", mailbox1->get_cname());
31     auto comm1 = mailbox1->put_async((void*)666, 5);
32     XBT_INFO("Initiating asynchronous send to %s", mailbox2->get_cname());
33     auto comm2 = mailbox2->put_async((void*)666, 2);
34
35     XBT_INFO("Calling wait_any..");
36     sg4::ActivitySet pending_comms;
37     pending_comms.push(comm1);
38     pending_comms.push(comm2);
39     try {
40       auto* acti = pending_comms.wait_any().get();
41       XBT_INFO("Wait any returned comm to %s", dynamic_cast<sg4::Comm*>(acti)->get_mailbox()->get_cname());
42     } catch (const simgrid::NetworkFailureException&) {
43       XBT_INFO("Sender has experienced a network failure exception, so it knows that something went wrong");
44       XBT_INFO("Now it needs to figure out which of the two comms failed by looking at their state:");
45       XBT_INFO("  Comm to %s has state: %s", comm1->get_mailbox()->get_cname(), comm1->get_state_str());
46       XBT_INFO("  Comm to %s has state: %s", comm2->get_mailbox()->get_cname(), comm2->get_state_str());
47     }
48
49     try {
50       comm1->wait();
51     } catch (const simgrid::NetworkFailureException& e) {
52       XBT_INFO("Waiting on a FAILED comm raises an exception: '%s'", e.what());
53     }
54     XBT_INFO("Wait for remaining comm, just to be nice");
55     pending_comms.wait_all();
56   }
57 };
58
59 class Receiver {
60   sg4::Mailbox* mailbox;
61
62 public:
63   explicit Receiver(const std::string& mailbox_name) : mailbox(sg4::Mailbox::by_name(mailbox_name)) {}
64
65   void operator()() const
66   {
67     XBT_INFO("Receiver posting a receive...");
68     try {
69       mailbox->get<void*>();
70       XBT_INFO("Receiver has received successfully!");
71     } catch (const simgrid::NetworkFailureException&) {
72       XBT_INFO("Receiver has experience a network failure exception");
73     }
74   }
75 };
76
77 int main(int argc, char** argv)
78 {
79   sg4::Engine engine(&argc, argv);
80   auto* zone  = sg4::create_full_zone("AS0");
81   auto* host1 = zone->create_host("Host1", "1f");
82   auto* host2 = zone->create_host("Host2", "1f");
83   auto* host3 = zone->create_host("Host3", "1f");
84   auto* link2 = zone->create_link("linkto2", "1bps")->seal();
85   auto* link3 = zone->create_link("linkto3", "1bps")->seal();
86
87   zone->add_route(host1, host2, {link2});
88   zone->add_route(host1, host3, {link3});
89   zone->seal();
90
91   sg4::Actor::create("Sender", host1, Sender("mailbox2", "mailbox3"));
92   sg4::Actor::create("Receiver", host2, Receiver("mailbox2"));
93   sg4::Actor::create("Receiver", host3, Receiver("mailbox3"));
94
95   sg4::Actor::create("LinkKiller", host1, [](){
96     sg4::this_actor::sleep_for(10.0);
97     XBT_INFO("Turning off link 'linkto2'");
98     sg4::Link::by_name("linkto2")->turn_off();
99   });
100
101   engine.run();
102
103   return 0;
104 }