Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c278faca08862ba0e64755495d8a260573257cb6
[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     std::vector<sg4::CommPtr> pending_comms;
37     pending_comms.push_back(comm1);
38     pending_comms.push_back(comm2);
39     try {
40       long index = sg4::Comm::wait_any(pending_comms);
41       XBT_INFO("Wait any returned index %ld (comm to %s)", index, pending_comms.at(index)->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.erase(pending_comms.begin());
56     sg4::Comm::wait_any(pending_comms);
57   }
58 };
59
60 class Receiver {
61   sg4::Mailbox* mailbox;
62
63 public:
64   explicit Receiver(const std::string& mailbox_name) : mailbox(sg4::Mailbox::by_name(mailbox_name)) {}
65
66   void operator()() const
67   {
68     XBT_INFO("Receiver posting a receive...");
69     try {
70       mailbox->get<void*>();
71       XBT_INFO("Receiver has received successfully!");
72     } catch (const simgrid::NetworkFailureException&) {
73       XBT_INFO("Receiver has experience a network failure exception");
74     }
75   }
76 };
77
78 int main(int argc, char** argv)
79 {
80   sg4::Engine engine(&argc, argv);
81   auto* zone  = sg4::create_full_zone("AS0");
82   auto* host1 = zone->create_host("Host1", "1f");
83   auto* host2 = zone->create_host("Host2", "1f");
84   auto* host3 = zone->create_host("Host3", "1f");
85
86   sg4::LinkInRoute linkto2{zone->create_link("linkto2", "1bps")->seal()};
87   sg4::LinkInRoute linkto3{zone->create_link("linkto3", "1bps")->seal()};
88
89   zone->add_route(host1->get_netpoint(), host2->get_netpoint(), nullptr, nullptr, {linkto2}, false);
90   zone->add_route(host1->get_netpoint(), host3->get_netpoint(), nullptr, nullptr, {linkto3}, false);
91   zone->seal();
92
93   sg4::Actor::create("Sender", host1, Sender("mailbox2", "mailbox3"));
94   sg4::Actor::create("Receiver", host2, Receiver("mailbox2"));
95   sg4::Actor::create("Receiver", host3, Receiver("mailbox3"));
96   
97   sg4::Actor::create("LinkKiller", host1, [](){
98     sg4::this_actor::sleep_for(10.0);
99     XBT_INFO("Turning off link 'linkto2'");
100     sg4::Link::by_name("linkto2")->turn_off();
101   });
102
103   engine.run();
104
105   return 0;
106 }