Motion Master 6.0.0-alpha.86
Next-generation motion control software
Loading...
Searching...
No Matches
procedure_manager.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5#include <expected>
6#include <functional>
7#include <map>
8#include <memory>
9#include <mutex>
10#include <optional>
11#include <ostream>
12#include <stop_token>
13#include <string>
14#include <string_view>
15#include <thread>
16#include <utility>
17#include <vector>
18
19#include "node/device.h"
20#include "node/device_manager.h"
21#include "node/procedure.h"
22
23namespace mm::node {
24
39
54using ProcedureBody = std::function<std::expected<void, std::string>(
55 const ProcedureContext&, ProgressReporter&, std::stop_token)>;
56
70 enum class Kind : uint8_t {
71 kBusy,
75 };
76
78 std::string message;
79
81 const std::string& what() const { return message; }
82};
83
85inline std::ostream& operator<<(std::ostream& os, const ProcedureError& e) {
86 return os << e.message;
87}
88
122 public:
125 explicit ProcedureManager(DeviceManager& deviceManager) : deviceManager_(deviceManager) {}
126
129
132
144 std::expected<void, ProcedureError> start(uint16_t devicePosition, std::string name,
145 std::vector<ProgressStep> steps, ProcedureBody body);
146
153 std::optional<ProcedureSnapshot> snapshot(uint16_t devicePosition, std::string_view name) const;
154
163 bool cancel(uint16_t devicePosition, std::string_view name);
164
165 private:
170 struct Run {
171 std::shared_ptr<ProgressReporter> reporter;
172 uint32_t runCount = 0;
173 int64_t startedAt = 0;
176 uint64_t topologyGeneration = 0;
177 std::atomic<ProcedureStatus> status{ProcedureStatus::kRunning};
178 std::atomic<int64_t> finishedAt{0};
179 std::atomic<bool> running{true};
180 std::jthread thread;
181
184 void setError(std::string reason) {
185 const std::lock_guard lock(errorMutex_);
186 error_ = std::move(reason);
187 }
188
190 std::optional<std::string> error() const {
191 const std::lock_guard lock(errorMutex_);
192 return error_;
193 }
194
195 private:
205 mutable std::mutex errorMutex_;
206 std::optional<std::string> error_;
207 };
208
209 using Key = std::pair<uint16_t, std::string>;
210
213 using ResolvedWork =
214 std::function<std::expected<void, std::string>(ProgressReporter&, std::stop_token)>;
215
218 std::expected<void, ProcedureError> startRun(uint16_t devicePosition, std::string name,
219 std::vector<ProgressStep> steps, ResolvedWork work);
220
234 void discardIfRescanned() const;
235
236 DeviceManager& deviceManager_;
237 mutable std::mutex mutex_;
238 mutable std::map<Key, std::shared_ptr<Run>> runs_;
239};
240
241} // namespace mm::node
Owns the fieldbus driver and node collection, and drives PDO exchange.
Definition device_manager.h:287
Represents a single node on the fieldbus.
Definition device.h:116
Runs off-RT command-and-wait procedures and remembers how each one went.
Definition procedure_manager.h:121
~ProcedureManager()
Requests cancellation of every running procedure and waits for them to finish.
Definition procedure_manager.cc:24
std::expected< void, ProcedureError > start(uint16_t devicePosition, std::string name, std::vector< ProgressStep > steps, ProcedureBody body)
Starts name on devicePosition, returning as soon as the run is under way.
Definition procedure_manager.cc:56
std::optional< ProcedureSnapshot > snapshot(uint16_t devicePosition, std::string_view name) const
The current or last-known state of name on devicePosition.
Definition procedure_manager.cc:142
ProcedureManager(DeviceManager &deviceManager)
Binds the manager to the device set its procedures will run against.
Definition procedure_manager.h:125
bool cancel(uint16_t devicePosition, std::string_view name)
Asks the running name on devicePosition to stop.
Definition procedure_manager.cc:166
ProcedureManager & operator=(const ProcedureManager &)=delete
ProcedureManager(const ProcedureManager &)=delete
The handle a procedure body uses to report where it has got to.
Definition procedure.h:327
std::string name
Catalogue name, e.g. "sm2".
Definition eni_request.cc:37
Response error(std::string status, std::string_view message)
A status response carrying a {"error": message} body.
Definition router.cc:154
Definition bus_health_source.h:7
@ kRunning
A run is in progress.
std::function< std::expected< void, std::string >(const ProcedureContext &, ProgressReporter &, std::stop_token)> ProcedureBody
A procedure's work: everything one run does, as a plain callable.
Definition procedure_manager.h:55
std::ostream & operator<<(std::ostream &os, const ProcedureError &e)
Streams the message, so ASSERT_TRUE(r) << r.error() and spdlog {} work unchanged.
Definition procedure_manager.h:85
std::string reason
Definition soem_fieldbus_driver.cc:956
What a procedure body is given: the device it runs on, and the manager that owns it.
Definition procedure_manager.h:34
Device & device
Definition procedure_manager.h:36
DeviceManager & manager
Definition procedure_manager.h:35
uint16_t devicePosition
Definition procedure_manager.h:37
Why a procedure operation could not be performed. A caller must branch on this — an HTTP handler maps...
Definition procedure_manager.h:69
const std::string & what() const
Exception-shaped accessor for the message, for call sites that prefer .what().
Definition procedure_manager.h:81
Kind
Definition procedure_manager.h:70
@ kUnknownProcedure
No procedure by that name, or not one this device supports. → 404.
@ kInvalidRequest
The procedure exists but the request for it does not validate. → 400.
@ kBusy
Another procedure is already running on that device. → 409.
@ kUnknownDevice
No device holds that bus position. → 404.
Kind kind
Definition procedure_manager.h:77
std::string message
Definition procedure_manager.h:78