Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / examples / cpp / task-microservice / s4u-task-microservice.cpp
1 /* Copyright (c) 2017-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 illustrates how to use Simgrid Tasks to reproduce the workflow 2.a of the article
7  * "Automated performance prediction of microservice applications using simulation" by ClĂ©ment Courageux-Sudan et al.
8  *
9  * To build this workflow we create;
10  *   - each Execution Task
11  *   - each Communication Task
12  *   - the links between the Tasks, i.e. the graph
13  *
14  * We also increase the parallelism degree of each Task to 10.
15  *
16  * In this scenario we send 500 requests per second (RPS) to the entry point of the graph for 7 seconds,
17  * and we count the number of processed requests between 2 and 7 seconds to evaluate the number of requests processed
18  * per second.
19  */
20
21 #include "simgrid/s4u.hpp"
22
23 XBT_LOG_NEW_DEFAULT_CATEGORY(task_microservice, "Messages specific for this s4u example");
24 namespace sg4 = simgrid::s4u;
25
26 static void request_sender(sg4::TaskPtr t, int requests_per_second)
27 {
28   for (int i = 0; i < requests_per_second * 7; i++) {
29     t->enqueue_firings(1);
30     sg4::this_actor::sleep_for(1.0 / requests_per_second);
31   }
32 }
33
34 int main(int argc, char* argv[])
35 {
36   sg4::Engine e(&argc, argv);
37   e.load_platform(argv[1]);
38
39   // Retrieve Hosts
40   auto pm0 = e.host_by_name("PM0");
41   auto pm1 = e.host_by_name("PM1");
42
43   // Set concurrency limit
44   pm0->set_concurrency_limit(10);
45   pm1->set_concurrency_limit(10);
46
47   // Create Exec Tasks
48   auto nginx_web_server        = sg4::ExecTask::init("nginx_web_server", 783 * pm0->get_speed() / 1e6, pm0);
49   auto compose_post_service_0  = sg4::ExecTask::init("compose_post_service_0", 682 * pm0->get_speed() / 1e6, pm0);
50   auto unique_id_service       = sg4::ExecTask::init("unique_id_service", 12 * pm0->get_speed() / 1e6, pm0);
51   auto compose_post_service_1  = sg4::ExecTask::init("compose_post_service_1", 140 * pm0->get_speed() / 1e6, pm0);
52   auto media_service           = sg4::ExecTask::init("media_service", 6 * pm1->get_speed() / 1e6, pm1);
53   auto compose_post_service_2  = sg4::ExecTask::init("compose_post_service_2", 135 * pm0->get_speed() / 1e6, pm0);
54   auto user_service            = sg4::ExecTask::init("user_service", 5 * pm0->get_speed() / 1e6, pm0);
55   auto compose_post_service_3  = sg4::ExecTask::init("compose_post_service_3", 147 * pm0->get_speed() / 1e6, pm0);
56   auto text_service_0          = sg4::ExecTask::init("text_service_0", 296 * pm0->get_speed() / 1e6, pm0);
57   auto text_service_1          = sg4::ExecTask::init("text_service_1", 350 * pm0->get_speed() / 1e6, pm0);
58   auto text_service_2          = sg4::ExecTask::init("text_service_2", 146 * pm0->get_speed() / 1e6, pm0);
59   auto user_mention_service    = sg4::ExecTask::init("user_mention_service", 934 * pm0->get_speed() / 1e6, pm0);
60   auto url_shorten_service     = sg4::ExecTask::init("url_shorten_service", 555 * pm0->get_speed() / 1e6, pm0);
61   auto compose_post_service_4  = sg4::ExecTask::init("compose_post_service_4", 138 * pm0->get_speed() / 1e6, pm0);
62   auto home_timeline_service_0 = sg4::ExecTask::init("home_timeline_service_0", 243 * pm0->get_speed() / 1e6, pm0);
63   auto social_graph_service    = sg4::ExecTask::init("home_timeline_service_0", 707 * pm0->get_speed() / 1e6, pm0);
64   auto home_timeline_service_1 = sg4::ExecTask::init("home_timeline_service_0", 7 * pm0->get_speed() / 1e6, pm0);
65   auto compose_post_service_5  = sg4::ExecTask::init("compose_post_service_5", 192 * pm0->get_speed() / 1e6, pm0);
66   auto user_timeline_service   = sg4::ExecTask::init("user_timeline_service", 913 * pm0->get_speed() / 1e6, pm0);
67   auto compose_post_service_6  = sg4::ExecTask::init("compose_post_service_6", 508 * pm0->get_speed() / 1e6, pm0);
68   auto post_storage_service    = sg4::ExecTask::init("post_storage_service", 391 * pm1->get_speed() / 1e6, pm1);
69
70   // Create Comm Tasks
71   auto compose_post_service_1_to_media_service =
72       sg4::CommTask::init("compose_post_service_1_to_media_service", 100, pm0, pm1);
73   auto media_service_to_compose_post_service_2 =
74       sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0);
75   auto compose_post_service_6_to_post_storage_service =
76       sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0);
77
78   // Create the graph
79   nginx_web_server->add_successor(compose_post_service_0);
80   compose_post_service_0->add_successor(unique_id_service);
81   unique_id_service->add_successor(compose_post_service_1);
82   compose_post_service_1->add_successor(compose_post_service_1_to_media_service);
83   compose_post_service_1_to_media_service->add_successor(media_service);
84   media_service->add_successor(media_service_to_compose_post_service_2);
85   media_service_to_compose_post_service_2->add_successor(compose_post_service_2);
86   compose_post_service_2->add_successor(user_service);
87   user_service->add_successor(compose_post_service_3);
88   compose_post_service_3->add_successor(text_service_0);
89   text_service_0->add_successor(text_service_1);
90   text_service_0->add_successor(text_service_2);
91   text_service_1->add_successor(user_mention_service);
92   text_service_2->add_successor(url_shorten_service);
93   user_mention_service->add_successor(compose_post_service_4);
94   compose_post_service_4->add_successor(home_timeline_service_0);
95   home_timeline_service_0->add_successor(social_graph_service);
96   social_graph_service->add_successor(home_timeline_service_1);
97   home_timeline_service_1->add_successor(compose_post_service_5);
98   compose_post_service_5->add_successor(user_timeline_service);
99   user_timeline_service->add_successor(compose_post_service_6);
100   compose_post_service_6->add_successor(compose_post_service_6_to_post_storage_service);
101   compose_post_service_6_to_post_storage_service->add_successor(post_storage_service);
102
103   // Dispatch Exec Tasks
104   std::vector<sg4::TaskPtr> exec_tasks = {nginx_web_server,
105                                           compose_post_service_0,
106                                           unique_id_service,
107                                           compose_post_service_1,
108                                           compose_post_service_1_to_media_service,
109                                           media_service,
110                                           media_service_to_compose_post_service_2,
111                                           compose_post_service_2,
112                                           user_service,
113                                           compose_post_service_3,
114                                           text_service_0,
115                                           text_service_1,
116                                           text_service_2,
117                                           user_mention_service,
118                                           url_shorten_service,
119                                           compose_post_service_4,
120                                           home_timeline_service_0,
121                                           social_graph_service,
122                                           home_timeline_service_1,
123                                           compose_post_service_5,
124                                           user_timeline_service,
125                                           compose_post_service_6,
126                                           compose_post_service_6_to_post_storage_service,
127                                           post_storage_service};
128   for (auto t : exec_tasks)
129     t->set_parallelism_degree(10);
130
131   // Create the actor that will inject requests during the simulation
132   sg4::Actor::create("request_sender", pm0, request_sender, nginx_web_server, 500);
133
134   // Add a function to be called when tasks end for log purpose
135   int requests_processed = 0;
136   sg4::Task::on_completion_cb([&e, &requests_processed](const sg4::Task* t) {
137     if (t->get_name() == "post_storage_service" and e.get_clock() < 7 and e.get_clock() > 2)
138       requests_processed++;
139   });
140
141   // Start the simulation
142   e.run();
143   XBT_INFO("Requests processed per second: %f", requests_processed / 5.0);
144   return 0;
145 }