blob: eadf5c63b2af5d42f8a46788a903161fc6845688 [file] [log] [blame]
Tyler Chatowa79419d2020-08-12 20:12:11 -07001#ifndef AOS_STARTER_STARTER_RPC_LIB_H_
2#define AOS_STARTER_STARTER_RPC_LIB_H_
3
4#include <chrono>
James Kuszmaul293b2172021-11-10 16:20:48 -08005#include <map>
milind upadhyaya87957a2021-03-06 20:46:30 -08006#include <optional>
James Kuszmaul293b2172021-11-10 16:20:48 -08007#include <vector>
Tyler Chatowa79419d2020-08-12 20:12:11 -07008
9#include "aos/configuration.h"
James Kuszmaul293b2172021-11-10 16:20:48 -080010#include "aos/events/event_loop.h"
Tyler Chatowa79419d2020-08-12 20:12:11 -070011#include "aos/starter/starter_generated.h"
12#include "aos/starter/starter_rpc_generated.h"
13
14namespace aos {
15namespace starter {
16
James Kuszmaul293b2172021-11-10 16:20:48 -080017// Data required to command that starter start/stop/restart a given application.
18struct ApplicationCommand {
19 Command command;
20 std::string_view application;
21 std::vector<const aos::Node *> nodes;
22};
23
24// This class manages interacting with starterd so that you can conveniently
25// start/stop applications programmatically.
26// Note that the StarterClient only maintains internal state for a single set of
27// commands at once, so once the user calls SendCommands() they must wait for
28// the timeout or success handler to be called before calling SendCommands
29// again.
30class StarterClient {
31 public:
32 StarterClient(EventLoop *event_loop);
33
34 void SendCommands(const std::vector<ApplicationCommand> &commands,
35 monotonic_clock::duration timeout);
36
37 void SetTimeoutHandler(std::function<void()> handler) {
38 timeout_handler_ = handler;
39 }
40
41 void SetSuccessHandler(std::function<void()> handler) {
42 success_handler_ = handler;
43 }
44
45 private:
46 struct CommandStatus {
47 State expected_state;
48 std::string application;
49 std::optional<uint64_t> old_id;
50 };
51
52 bool CheckCommandsSucceeded();
53
54 void Timeout();
55
56 void Succeed();
57
58 EventLoop *event_loop_;
59 TimerHandler *timeout_timer_;
60 Sender<StarterRpc> cmd_sender_;
61 // Map of fetchers by node name.
62 std::map<std::string, Fetcher<Status>> status_fetchers_;
63
64 // Mapping of node name to a list of applications with pending commands.
65 std::map<std::string, std::vector<CommandStatus>> current_commands_;
66
67 std::function<void()> timeout_handler_;
68 std::function<void()> success_handler_;
69};
70
Tyler Chatowa79419d2020-08-12 20:12:11 -070071// Finds the status of an individual application within a starter status message
72// Returns nullptr if no application found by the given name.
73const aos::starter::ApplicationStatus *FindApplicationStatus(
74 const aos::starter::Status &status, std::string_view name);
75
milind upadhyay4272f382021-04-07 18:03:08 -070076// Checks if the name is an executable name and if it is, it returns that
77// application's name, otherwise returns name as given
Austin Schuhdae1e8d2022-03-26 15:09:31 -070078std::string_view FindApplication(const std::string_view name,
milind upadhyay4272f382021-04-07 18:03:08 -070079 const aos::Configuration *config);
80
Tyler Chatowa79419d2020-08-12 20:12:11 -070081// Sends the given command to the application with the name name. Creates a
82// temporary event loop from the provided config for sending the command and
83// receiving back status messages. Returns true if the command executed
84// successfully, or false otherwise. Returns false if the desired state was not
85// achieved within timeout.
86bool SendCommandBlocking(aos::starter::Command, std::string_view name,
87 const aos::Configuration *config,
James Kuszmaul293b2172021-11-10 16:20:48 -080088 std::chrono::milliseconds timeout,
89 std::vector<const aos::Node *> nodes = {});
Tyler Chatowa79419d2020-08-12 20:12:11 -070090
Austin Schuhe4b748a2021-10-16 14:19:58 -070091// Sends lots of commands and waits for them all to succeed. There must not be
92// more than 1 conflicting command in here which modifies the state of a single
93// application otherwise it will never succeed. An example is having both a
94// start and stop command for a single application.
James Kuszmaul293b2172021-11-10 16:20:48 -080095bool SendCommandBlocking(const std::vector<ApplicationCommand> &commands,
96 const aos::Configuration *config,
97 std::chrono::milliseconds timeout);
Austin Schuhe4b748a2021-10-16 14:19:58 -070098
Tyler Chatowa79419d2020-08-12 20:12:11 -070099// Fetches the status of the application with the given name. Creates a
James Kuszmaule4bb0a22022-01-07 18:14:43 -0800100// temporary event loop from the provided config for fetching. Returns nullopt
101// if the application is not found.
James Kuszmaul2ca441b2022-01-07 18:16:23 -0800102// The returned pair is the time at which the ApplicationStatus was sent on the
103// node it was sent from, to allow calculating uptimes on remote nodes.
James Kuszmaule4bb0a22022-01-07 18:14:43 -0800104const std::optional<
James Kuszmaul2ca441b2022-01-07 18:16:23 -0800105 std::pair<aos::monotonic_clock::time_point,
106 aos::FlatbufferDetachedBuffer<aos::starter::ApplicationStatus>>>
James Kuszmaule4bb0a22022-01-07 18:14:43 -0800107GetStatus(std::string_view name, const aos::Configuration *config,
108 const aos::Node *node);
Tyler Chatowa79419d2020-08-12 20:12:11 -0700109
Philipp Schrader08537492021-01-23 16:17:55 -0800110// Fetches the entire status message of starter. Creates a temporary event loop
111// from the provided config for fetching.
James Kuszmaul293b2172021-11-10 16:20:48 -0800112// The returned pair is the time at which the Status was sent on the node it was
113// sent from, to allow calculating uptimes on remote nodes.
114// TODO(james): Use the ServerStatistics message and return the monotonic offset
115// instead, so that we can correctly handle high message latencies. Because
116// people don't generally care about ultra-high-precision uptime calculations,
117// this hasn't been prioritized.
118std::optional<std::pair<aos::monotonic_clock::time_point,
119 const aos::FlatbufferVector<aos::starter::Status>>>
120GetStarterStatus(const aos::Configuration *config, const aos::Node *node);
Philipp Schrader08537492021-01-23 16:17:55 -0800121
Tyler Chatowa79419d2020-08-12 20:12:11 -0700122} // namespace starter
123} // namespace aos
124
125#endif // AOS_STARTER_STARTER_RPC_LIB_H_